[solved] Issue with multiple collision handler

Hi all,

I’m having troubles with collisions:

I want that my FPS camera uses the CollisionHandlerPusher to handle collision with visible geometry and the CollisionHandlerEvent to handle the collision with some spheres i put in the map in order to save the player position.

The spheres have to be traversable and, when the player passes through them, the game has to save the player position.

Here an image to explain better

B represents the collision sphere I want to use like “triggers”.

Here the code that manages the camera collider:

# -*- coding: utf-8 -*-'

from pandac.PandaModules import ExecutionEnvironment
from pandac.PandaModules import *

def handleCollision(showbaseObject):

	showbaseObject.cTrav = CollisionTraverser()
	showbaseObject.cTrav2 = CollisionTraverser()

	showbaseObject.pusher = CollisionHandlerPusher()
	showbaseObject.triggerEvent = CollisionHandlerEvent()

	colNode= CollisionNode('cameracnode')

	showbaseObject.cameraCollider = showbaseObject.cameraRef.attachNewNode(colNode)
	showbaseObject.cameraCollider.node().addSolid(CollisionSphere(0, 1.8, 0, 1.3))

	showbaseObject.cTrav.addCollider(showbaseObject.cameraCollider, showbaseObject.pusher)
	showbaseObject.pusher.addCollider(showbaseObject.cameraCollider,showbaseObject.cameraRef)

	showbaseObject.cTrav2.addCollider(showbaseObject.cameraCollider, showbaseObject.triggerEvent)
	showbaseObject.triggerEvent.addOutPattern('outof-%in')

And this is the code for the spheres/geometry:

# the model of the city has a mesh collider in it
		self.showbaseObject.environment = loader.loadModel ("models/city/city_coll")
		self.showbaseObject.environment.reparentTo (self.node)

# here the code for the spheres
	for i in range(0,len(posCollisionSphere)):
			c = CollisionSphere(posCollisionSphere[i][X], posCollisionSphere[i][Y], posCollisionSphere[i][Z], posCollisionSphere[i][R])
			colNode = CollisionNode('cnode'+str(i))
			cnodePath = self.showbaseObject.center.attachNewNode(colNode)
			cnodePath.node().addSolid(c)
			self.showbaseObject.accept('outof-' + 'cnode'+str(i), self.savePosition)

The problem is that the pusher works perfectly but the camera cannot travers the spheres :frowning:

How can I solve this problem?

If I recall correctly, “base.cTrav” is a special case in that it is automatically traversed if assigned to a traverser. Any other traversers that you create (such as your “cTrav2”) call for manual traversal in your code, perhaps in a task, I believe.

That said, why not just use a single traverser? They’re attached to different handlers, after all. Do you intend to check for spheres collisions only under specific conditions, and if so, why are you not doing so?

“You will need to create a CollisionHandler that specifies what to do when a collision event is detected. Each object can only have one collision handler associated with it.” http://www.panda3d.org/manual/index.php/Collision_Handlers

I have two traversers because I need to handle two kind of collisions. The first: collision against the city buildings. Here I need CollisionHandlerPusher.
The second: collision against the control sphere. Here I need CollisionHandlerEvent.

If I use only one traverser, the last handler I use in the function traverser.addCollider(collider, handler) will be the one will work.

So the real issue is: I have to use the same collider (cameraCollider) in order to achieve two different kind of collisions. I have to use the same collider but with two different handlers and then two diferent traversers.

I want my camera pass through the sphere but not through the wall!

The quote that you give doesn’t appear to say anything about having multiple traversers, only multiple handlers.

Have you tried having more than one handler in a traverser? I may well be mistaken, but I seem to recall having used more than one handler in a single traverser…

Nevertheless, if you don’t want to control either traversal yourself then I don’t think that two handlers are called for either. Note two things: First, that collision solids can, I believe, be marked as “intangible” via a call to the “setTangible” method. Second, note that CollisionHandlerPusher extends CollisionHandlerEvent, and can thus be treated as a CollisionHandlerEvent and events fired by it, I believe. You should be able to simply mark your spheres as intangible and set up events in the CollisionHandlerPusher for intersection with them.

I cannot assign more than one hanlder to a traverser because the last handler I add replaces the first. So I cannot assign two handlers to the same traverser

Really a usefull information. I solved one of my problem with that!

That’s what I’ve done and now it works perfectly! Really thank you!