Using collisionhandlerqueue?

How do I use collisionhandlerqueue?

When I add zombies:

self.colNode[x] = self.zombie[x].attachNewNode(CollisionNode("z"+str(x)))
            
            self.colNode[x].show()
            self.colNode[x].node().addSolid(CollisionTube(0, 0, 20, 0, 0, -20, 20))
            base.cTrav.addCollider(self.colNode[x], self.notifier)

Setting up the cd (I don’t know why it tabs in):

base.cTrav = CollisionTraverser()
        self.notifier = CollisionHandlerQueue()

Shooting bullets:

self.bullet = render.attachNewNode(CollisionNode("bullet"))
            self.bullet.node().addSolid(CollisionRay(Point3(self.cam.getPos()), Vec3(self.cam.getHpr())))
            base.cTrav.addCollider(self.bullet, self.notifier)

Registering Hits:

if self.notifier.getNumEntries() >= 1:
            self.dr = True
            for i in range(self.notifier.getNumEntries()):
                entry = self.notifier.getEntry(i)
                if entry[0] == "z":
                    self.zombiesHit.append(entry)

            for i in self.zombiesHit:
                zombieName = self.getZomName(i)
                dst = (zombieName).getDistance(self.cam)
                dst.setPythonTag("zombiename", zombieName)
                self.distanceZombies.append(dst)


            lengthDst = len(self.distanceZombies)
            shortestDistance = min(self.distanceZombies)
            zombieNName = shortestDistance.getPythonTag("zombiename")

            self.zombie_shot(zombieNName.getPythonTag("HP"), zombieNName, zombieNName.getPythonTag("COLNODE"))

            self.clear(self.distanceZombies)
            self.clear(self.ZombiesHit)
        self.notifier.clearEntries

        return task.cont

self.dr is a test variable, I print it to see if there are entries in the collision notifier. It always printed as false, so that would be no.

But when I shoot, the zombies don’t register hits! What am I doing wrong?

Any help would be greatly appreciated,
Thanks.

I strongly suspect that the problem is in your definition of your CollisionRay: specifically, based on a look at the documentation, it appears that CollisionRay takes its direction not as HPR but as a direction vector: dx, dy and dz.

For example, a CollisionRay starting at the origin and pointed along the positive y-axis might be defined like so:

ray = CollisionRay(0, 0, 0, 0, 1, 0)

while a ray starting at the origin and pointed along a 45-degree angle between the x- and z- axes might be defined like so:

ray = CollisionRay(0, 0, 0, 1, 0, 1)

I imagine that the same applies to the constructor that takes a Point3 and a Vec3 rather than six floats, as used above.

Hi, thanks for replying!

I have a question though, how would I use this like I want to, with the camera’s orientation to shoot rays, I’ve never used direction vectors…

Thanks a lot.

Looking again at the manual, it seems to me that in your case it should be fairly simple: you’re basically doing what is described here.

(Note that, unless you want your rays to hang around and keep interacting after initial use, you can probably just use a single CollisionRay, as described in the link above, rather than creating a new one for each shot.)

However, if you want a brief description of direction vectors, as I understand them:

A direction vector describes a direction by viewing it as a line pointed in the desired direction. This line can then be expressed by its x-, y- and z- components, as with any line.

A few examples:
(Note: the following are expressed mathematically, rather than as Vec3s - I leave the conversion to you. I’m presuming y-forward and z-up, as I believe that Panda uses.)

If the direction is looking along the positive y-axis, the direction vector should be (0, 1, 0) (or a multiple thereof).

If the direction is looking up at an angle of 45 degrees, then the direction vector should be (0, 1, 1). (We are looking both forward and up, after all; since the angle is 45 degrees, we are looking up as much as we are looking forward.)

Thanks for the explanation!

So what should I put in CollisionRay(x)

so that it will place it in the same orientation as the camera, where camera is self.cam?

Thanks a lot.

The page that I linked to appears to have a full example - I recommend doing what is done there.

In brief: Nothing. Construct an empty CollisionRay and then use the method shown in the example to place and orient it for each new shot. If you do want to have multiple CollisionRays around, do the same, but apply the method to each new ray after creation rather than to the same ray on each shot.

So I now know it is placing the cnode that is being done wrong (no time to explain). But this method does not work quite right.

 self.bullet = CollisionRay()
            self.bulletDummy = render.attachNewNode(CollisionNode("frowney"))
            self.bulletDummy.node().addSolid(self.bullet)
            base.cTrav.addCollider(self.bulletDummy, self.notifier)
            self.bulletDummy.show()
            if base.mouseWatcherNode.hasMouse():
                mpos = base.mouseWatcherNode.getMouse()
                self.bullet.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.playerBullets = self.playerBullets - 1

Maybe there is a way to just place the cray at the same orientation at the camera without using setfromlens? Or what am I doing wrong here?

Thanks.

Well, you’ve posted only a small piece of code there, and not provided much description of what’s going wrong, but two thoughts occur to me:

  1. Are you repeating the call to “setFromLens” when you shoot, or just that once?

  2. I’m not sure of why it does so, but I note that the example attaches the ray to “camera”, not “render”.

(The first is the point that most concerns me; I recommend checking that first.)