CollisionTubes - CollisionCapsule Tutorial 6 not colliding

I am new to Panda3d and have looked at a few different situations using CollisionTubes/CollisionCapsule and can’t figure out what I am not doing correctly.

The tutorial lesson I was following is linked here:

The relevant code is here but if you want the full code, I can provide it but it also accessible at lesson 06 link. The tut uses Tubes, but upon reading, I guess those are old. So i made the switch to Capsule and it did make no difference. Showing the tubes demonstrates they are present. The tutorial doesn’t do anything with the traverser/pusher. I tried adding it to the traverser but you cannot add collision nodes to the pusher and so I’m not sure it was even relevant. I commented it out. I think the into and from concepts means that if it’s in the traverser/pusher system it’s the ‘into’ role so you probably don’t put the walls there anyway. Regardless, I’m not managing to get collisions with my tubes and my sprite. Any thoughts or obvious mistakes jumping out?

    self.traverser = CollisionTraverser()
    self.pusher    = CollisionHandlerPusher()
    
    
    colliderNode = CollisionNode("player")
    colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.3))
    collider = self.pchan.attachNewNode(colliderNode)
    collider.show()
    
    self.pusher.addCollider(collider,self.pchan)
    self.traverser.addCollider(collider,self.pusher)
    self.pusher.setHorizontal(True)
  
    wallSolid = CollisionCapsule(-8.0, 0, 0, 8.0, 0, 0, 0.2)
    wallNode = CollisionNode("wall")
    wallNode.addSolid(wallSolid)
    wall = self.render.attachNewNode(wallNode)
    wall.setY(8.0)
    #wall.show()
    
    
    #self.traverser.addCollider(wall,self.pusher)
    
    wallSolid = CollisionCapsule(-8.0, 0, 0, 8.0, 0, 0, 0.2)
    wallNode = CollisionNode("wall")
    wallNode.addSolid(wallSolid)
    wall = self.render.attachNewNode(wallNode)
    wall.setY(-8.0)
    #wall.show()
    
    #self.traverser.addCollider(wall,self.pusher)
    
    wallSolid = CollisionCapsule(0, -8.0, 0, 0, 8.0, 0, 0.2)
    wallNode = CollisionNode("wall")
    wallNode.addSolid(wallSolid)
    wall = self.render.attachNewNode(wallNode)
    wall.setX(8.0)
    #wall.show()
    
    #self.traverser.addCollider(wall,self.pusher)

    wallSolid = CollisionCapsule(0, -8.0, 0, 0, 8.0, 0, 0.2)
    wallNode = CollisionNode("wall")
    wallNode.addSolid(wallSolid)
    wall = self.render.attachNewNode(wallNode)
    wall.setX(-8.0)
    #wall.show()
    
    #self.traverser.addCollider(wall,self.pusher)

Greetings, and welcome to the forum! I hope that you enjoy your time here! :slight_smile:

To answer your question, I believe that the problem is that you’ve renamed the variable that holds your traverser: in the tutorial it’s named “cTrav”, while in your code it’s named “traverser”.

Now, in most cases this would likely-enough be fine, as long as you were consistent in the renaming.

However, in this case “cTrav” is a special variable provided by the ShowBase class, and assigning a traverser to it causes ShowBase to automatically run collision-traversal with that traverser.

Since “cTrav” isn’t being used, collision-traversal is (presumably) not being run, and thus no collisions are detected.

Thus the simplest fix is likely to assign your traverser to “cTrav” instead of to another variable.

That said, one can use a traverser in a variable of one’s own–and indeed, this can be useful at times! For example, one might want to only perform a particular collision-traversal when a certain event occurs, rather than on every update as cTrav does. In such cases, one then manually calls the traverser’s “traverse” method.

PS: You are quite right about the name “CollisionTube”, I do believe! In short, and if I recall correctly, it’s an old name that has been deprecated in favour of “CollisionCapsule”. But the old name is still available, I believe, and hence the code should still work.

Thank you very much for your quick answer- and kind welcome.
So far, I have really liked how Panda3d is working and hope to develop my first indie game with it.
I have a small team of friends who have committed to certain aspects, but I’ll try to be doing the heavy lifting using Panda3d.

Ah darnit! Yeah, I guess extending the classes, it’s not always easy to tell when something is named arbitrarily or specifically. Maybe it was written and I missed it. Either way, I’ll read into the collision traverser more.

In those tutorials, the author uses base.pusher and base.cTrav. Is that important to call the base or wouldn’t self.pusher/self.cTrav delegate to the base class?

self.cTrav = self.traverser
at the end fixed the issue, so I assume that this is okay, but now I just want to double check.

Thanks again! :slight_smile:

1 Like

oh also seeing your name… Thanks for the tutorial! Super helpful.

It’s my pleasure! :slight_smile:

I’m glad that you’re enjoying the engine–and that sounds like quite an exciting project! Good luck with it! :slight_smile:

It’s not at all important to use “base”: since (as you point out) in this case the object to which “self” refers is a descendant of “ShowBase”, they end up as the same thing.

And honestly, there’s an argument to be made that “self.” is better. (For one thing, it avoids the use of the possibly-cryptic and, I think, now-deprecated global variable “base”.)

When I wrote the tutorial, my habit was to use “base.”, I think; since then I’ve been transitioning towards using “self.” instead, I believe.

It should be okay, I think.

It’s perhaps a little untidy, as it leaves a superfluous variable–“self.traverser”–hanging around. While likely-enough fine here, doing so overmuch could result in code that’s difficult to read and prone to issues. (e.g. Unexpected failures of garbage-collection due to having an extra reference to an object in a forgotten variable.)

Hahah, it’s my pleasure! I’m very glad that it’s proven helpful! :slight_smile: