Shoot Bullets at Moving Objects

I’ve been trying to shoot a bullet at a moving object, but the problem has been that it’s moving too fast to always be detected by the wall, so sometimes the bullet goes through the wall instead of being ended by it. People have been saying use a ray and get the position of the object before the bullet fires, but the problem is the objects are moving. So if the ray gets a position and the bullet fires, but the target moves, the bullet is gonna end in mid-air instead of hitting what’s behind it. It seems like the only way to get an accurate hit is with collision, but I don’t know how to make the bullet hit the object while still moving fast. I’ve changed the substeps and framerate and neither of those work.

If you going to use a ray, why shoot a bullet? what is exactly do you want to make? kill a enemy? bullet hole?

Because it’s not going to hit instantly, it needs to travel there. And if when it gets there the object has moved it need to keep going.

The rays hit instantly, it no have velocity, what do you mean? if you like i’m can make an example(use python). The question remains, what is exactly do you want to make?

EDIT: i’m making an example.

I don’t want the bullet to hit the object instantly. I want it to travel there. The ray will hit instantly.

You can interpolate the ray’s start and end points till it hits something.

Ok, how would I do that? Also, my other concern is the bullet is bigger than the ray is. So if the ray misses, but the bullet hits, it will still count as a miss. Can I make the ray bigger?

I am also interested in what say Jackii, i know the end and start values of the ray can be change in realtime, but how manage each ray hitted, because you can shoot 5 times in a second(an example), so you need to store each ray somehow, and still changing the values after the frame that you trigger it.

@@DannyMaz:

The rays “not have size”, although there are some things you can do to what you mention.

I tried it recently, it works perfectly.

Bit offtopic: I’m currently working on a realistic bullets system using beziers instead of straight rays to emulate gravity effect, and also to bounce properly off walls, similar to the pre-visualization in peggle 2.

How do you do it?

Set constant variable for the speed of the bullet. Fire ray, get ray distance to hit position, create delay (according to speed variable and ray distance) before adding bullet hole and applying damage to hitObject, add “bullet” object to track to ray hit position at defined velocity (all with the use of the very useful equation v=d/t).

Sent from my Galaxy Nexus using Tapatalk

Here is an example of shoots using rays…without the ray speed, fps using rays v0.1.blend (496 KB), the rays used here not have velocity, but can be usefull for somebody, and also someone can use it as base for make an example of the ray velocity method.

Me a bit difficult to understand MrPutuLips, you may be able to make an example?

Here’s a simple example:

Attachments

basicbullet.blend (480 KB)

Isn’t there a way to up the # of physics ticks… that should fix it pretty quick and easy.

@John_L:
Yes, you can increase the physics tics, but it comes at a performance penalty and is not a recommended way to do it.

So here’s what I’d do:

  • Spawn a bullet with whatever forwards velocity you like
  • have a script that stores the position the bullet is in in a game property
  • The next frame, it casts a ray from where it was (the game property) to where it is (own.worldPosition)

I think that’s kind of what jakii was talking about. I’ll have to have a look at his example file.

I would just cast a ray from the BULLET itself. Using some simple maths, you can figure out the maximum distance the bullet can travel per logic tick and cast the ray slightly farther than that.

My impalement code does pretty much that.


def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner
    scene = bge.logic.getCurrentScene()
    
    if not "init" in own:
        own["init"] = True
        own["end"] = False
        own["timer"] = 2
    
    if not own["end"]:
    
        pos = own.worldPosition.copy()
        
        #calculating the would be position of the next frame
        next_pos = pos.copy()
        vel = own.getLinearVelocity()    
        next_pos.x += vel[0] / bge.logic.getLogicTicRate() #speed per frame 
        next_pos.y += vel[1] / bge.logic.getLogicTicRate() # is actual step
        next_pos.z += vel[2] / bge.logic.getLogicTicRate() #taken /moved
        ###
        
        #raycast to the pos of next frame.
        #rayCast(to, from, distance, property, face, xray, poly)  
          
        ray = own.rayCast(next_pos, pos, 0, 'Physical',False,False,True)    
        
        if ray[0] != None and ray[-1] != None:            
            mat_name = ray[-1].getMaterialName()
            print(mat_name)
            if mat_name in ["MAStick","MAWood","MACobble"]:            
                own.worldPosition = ray[1]
                new = scene.addObject('impaled_projectile', own,200)                
                new.setParent(ray[0]) 
                
            elif mat_name in [ "MABounce", "MASteel"]:
                scene.addObject('Bolt_Bounce', own,70)
                
            own.endObject()        

Basically from:
http://www.blenderartist.org/forum/showthread.php?210587-Arrow-stick-and-bounce-Blend-File-video-need-help

So far sdfgeoff has the best suggestion. How would you do that? It seems like you’d have to get the current frame, which it doesn’t look like you can do.

A ray on the bullet is very simple. Just attach a ray sensor shooting straight forward and do something like this.


ray = own.sensors["Ray"]

if ray.positive:
    hit_obj = ray.hitObject
    hit_point = ray.hitPosition


It’s really that simple.

I waited a while to post something here because I was working on a solution. If you really need it to be realistic, then indeed, you should cast rays from the flying bullet. However, because it’s virtually known where the bullet will be as it travels, you don’t actually need the bullet object itself to do this. Additionally, if you would like to show a bullet trail, the object has to be larger, and thus it would penetrate through objects. Obviously this is no beauty. Solution is to add the bullet for only one logic tic and scale it on the fly, every frame, until the bullet range is reached.

It is an advanced setup, but honestly I can’t think of a better setup. Advantages are:

  • only one python controller needed
  • bullet and trail never go through objects
  • time and location of impact is always correct

A disadvantage is, the lower the bullet speed, the more processes a shot takes. A speed of 5 per tic is equivalent to 300 m/s (at 60fps), which is almost the real speed of a bullet. And logic doesn’t climb so much at a speed of 5.

Enjoy!

Attachments

Ray_bullet_advanced_00.blend (121 KB)