[Solved]CollisionHandlerEvent Question...

I tried to use the CollisionHandlerEvent method to do my collision detection, but just didn’t work.

Is there any special thing I have to notice when making the egg file? What I need is “Growl” collides into “Wall”, where Growl was made from

“maya2egg7 -a model” (still) and “maya2egg7 -a chan” (walk, idle)

and Wall was from

“maya2egg7 -a pose”

here’s my code snippet:


# ### Load Still Models & Actors
self.arena = loader.loadModel(MYDIR+"/models/arena")
self.wall =   self.arena.find("**/wall")

self.Growl = Actor.Actor(MYDIR+"/models/growl",
                         {"idle":MYDIR+"/models/growl_idle",
                          "walk":MYDIR+"/models/growl_walk"})

# ### Collision setup
    
    # WALL collision setup (into)
    self.wall.setCollideMask(BitMask32.bit(1))

    # ORC collision setup (from)
    __bounds = self.Growl.getChild(0).getBounds()
    _cSphere = CollisionSphere(__bounds.getCenter(), __bounds.getRadius())
    
    cnGrowl = CollisionNode("Growl") #Growl Collision Node (cn = Collision Node)
    cnGrowl.setFromCollideMask(BitMask32.bit(1))
    cnGrowl.setIntoCollideMask(BitMask32.allOff())
    cnGrowl.addSolid(_cSphere)

    self.cnpGrowl = self.Growl.attachNewNode(cnGrowl)    #self.Growl is a Node Path!
    self.cnpGrowl.show()

    
# ### Collision Events (handler...)

    # use an event collision handler (sends events on collisions)
    self.cHandler = CollisionHandlerEvent()
    
    # Initialize handler
    self.collHandEvent=CollisionHandlerEvent()
    self.collHandEvent.addInPattern('into-%in')

# ### Traverser setup

    # make a traverser <and make it the default traverser>
    self.cTrav = CollisionTraverser()

    # add Growl's collision np to the traverser as a collider
    self.cTrav.addCollider(self.cnpGrowl, self.cHandler)
    #print "self.cnpGrowl: ", type(self.cnpGrowl)
                                                      
        
# ### Action (event/handler) when things happened...

    # Accept the events sent by the collisions
    self.accept( 'into-' + self.wall.getName(), self.collide)

    
def collide(self):
    print "--- collided!! ---"

Is there anything else I missed?

Thanks for the help again.

I don’t see anything obviously missing. There are a number of ways to debug this.

First thing to try is:


messenger.toggleVerbose()

to see if it is detecting the collision, but sending an unexpected event name. You can also try:


self.cTrav.showCollisions(render)

to enable a mode in which all of the collisions that are tested are highlighted in yellow, while the collisions that are detected are highlighted in white (with a few other colors thrown in for various meanings).

If neither of those produces any useful insight, you can try the nuclear bomb of collision debugging: full verbose spammage. You probably only want to do one frame of full spammage, because it is a lot of output to wade through. Position your character so that it is intersecting the wall, and then do:

Notify.ptr().getCategory(':collide').setSeverity(NSSpam)
self.cTrav.traverse(render)
Notify.ptr().getCategory(':collide').setSeverity(NSInfo)

The first command turns on spam output for the collide category; it’s equivalent to putting “notify-level-collide spam” in your Config.prc file. The second line runs the traverser, and the third line puts the output level back to normal.

In this output, you should see it walking through the scene graph and considering each node that it visits. You may then gain some insight into why it is or is not detecting the collision that you expect it to detect with the wall.

David

Also, make sure that you are at some point assigning base.cTrav = self.cTrav, or spawning a task to run the traverser yourself every frame.

Whatever traverser you assign to base.cTrav will be run automatically by ShowBase; anything else you will have to run yourself.

David

:laughing: :laughing: :laughing: Just like in my old time, I bet I’ve got everything set, then :open_mouth: I realised that I haven’t traverse the coll traverser.

I did setup a line about base.cTrav = self.cTrav but forgot to show in my preceding code; it’s not working.

I just did a quick test… the collision message was not throwing out (nothing happened when collided), and the collision wall’s color was…interesting.
(yellow before collided, white when collided, and grey when un-collided again)

I’ll take a deeper dig tomorrow.

Thanks again for David about your step-by-step debugging techniques. It’s extremely helpful and let me have the courage to face Panda…forever! :laughing:

Ah, so now I see the problem. From the description of your symptoms, your CollisionHandler is detecting the collision, but your CollisionHandlerEvent is not throwing events.

Now look at this:

   self.cHandler = CollisionHandlerEvent()
       # Initialize handler
    self.collHandEvent=CollisionHandlerEvent() 

Eek! You’ve just created two CollisionHandlerEvents, one called self.cHandler, and another one called self.collHandEvent. Then you enable the event on the second one, but the one you actually use is the first one!

David

Urr…my fault!
My mind must be somewhere… Urrrr…!!

Thanks David…why your eyes are so sharp?