getting only a single collision [SOLVED]

hello, I am making an FPS and when i fire I take an already created collision ray and set the direction of it. When the ray collides with a sphere I set up i make it the ray change direction so I get only one collision. My problem is that when the ray does not collide with the sphere (nothing) it stays and will not change direction.

for i in range(self.queue.getNumEntries()):
    	      entry = self.queue.getEntry(i)
              if entry.getFromNodePath()==self.vecp:
    	      	 print 'SHOT'
      	      self.vec.setDirection(0,0,-.00005)

I have tried adding

self.vec.setDirection(0,0,-.00005)

in the same indentation as the for loop but when I do that I do not get any collisions.
[/code]

if you modify a collisionobject the collisions will be detected only in the next step (frame) if you have added your collisions to base.cTrav. if you want to modify and instantly get collision results you need to initiate the collision detection manually (collTraverser.traverse(render)). if you want to manually detect collisions, dont define the collisionTraverser you use as base.cTrav, because this makes it run automatically every frame automatically.

enabling collision visuals helps a lot when debugging collisions. base.cTrav.showCollisions(render), also collisionNode.show() is quite useful.

I don’t think you understand my question. I am already getting the collision detection and I have the visuals turned on so I can see the rays. The problem I am having is that when I shoot something I dont want the ray to stay in the same stop, so it triggers the collision only once. I have that working when I collide with a collision sphere I have set up. The problem comes in when I don’t collide with anything. The ray just sits there and I cant figure out how to change the direction of it so isnt out in the open. This will be a problem later on when I get enemy’s that move and if I still have the ray sitting out the enemy could collide with a ray the ray that was placed there 5min ago.

Well, gee, if you traverse through the rays returned in your collision queue, as you are doing above, of course you are only going to visit (and modify) those rays that actually detected a collision. The rays that didn’t collide with anything aren’t going to be in that queue, so you’re never going to modify them.

If you want to take all of your rays out of the collision traverser (and calling traverser.removeCollider() is a much better way to do this than simply pointing the ray backwards), then you need to have a separate list of all of your rays in the first place. You have to build up this list when you create the rays. Then you can walk through this list and take them out one at a time.

David

I understand that the stuff in the queue will only be collided items. But what I said that I tried to do was this:

for i in range(self.queue.getNumEntries()): 
             entry = self.queue.getEntry(i) 
              if entry.getFromNodePath()==self.vecp: 
                 print 'SHOT' 
self.vec.setDirection(0,0,-.00005) 

I thought that if I moved self.vec.setDirection(0,0,-.00005) outside the for loop I would always be able to move the ray no matter if it collided or not. The problem is that the rays no longer go where I click and I get no collision. Would using traverser.removeCollider() still be a better way to do this even if I only have one collision ray?

Let me see if I understand what you want to happen.

You want to:
(a) create a CollisionRay.
(b) use that ray to test for collisions, exactly once.
© disable that ray so that it does not test for collisions again.

You have tried to do © by pointing the ray backwards. But you found that when you did this, it also disabled (b), so that you never even got the first collision test.

Do I understand the problem correctly?

If that is an accurate description of your problem, I think it is clear that you must have pointed the ray backwards too early, before the collision test was performed in the first place.

Of course, pointing the ray backwards is not a good way to disable it anyway. It’s still active, it’s only pointing backwards.

Why don’t you just create a CollisionTraverser on-the-fly and use it only once, and then don’t use it again? Something like this:

ctrav = CollisionTraverser('temp')
ctrav.addCollider(...)
ctrav.traverse(...)

David

Im sorry that I didn’t explain myself fully but yes drwr that is what I am looking to do. Im starting to think that removing the ray would be better then pointing it backwards, as you have stated. I don’t want to create transversers on the fly because I need that one to handle all of the collisions with respect to thinks being shot and I feel that creating more would be more of a problem to deal with. Im going to try creating and destroying rays and I’ll post back if I need some help still.

Thanks

Thanks drwr for the help. I am now making the CollisionTraverser on-the-fly and the collision is working perfectly.
[/quote]