bullets that don't pass thru walls

I’m making a game involving artillery combat. I wanted things like gravity and wind to affect projectiles. suffice it to say, I needed a system to allow very small projectiles to move very fast without passing through walls (I’m, sure many of you are acquainted with the “high-speed objects passing through walls” problem)

I wrote a simple script using a ray sensor to allow my bullet to go any speed (you have to manually set it’s top speed- if I could dynamically change a ray sensors distance value, you wouldn’t have to)
keep in mind that this projectile is infinitely small, so other things can’t hit it, but it works fine for projectiles. there’s no ricochet system, since my intent is to have the bullets explode on contact, but I expect someone more knowledgeable than me could add one, if they felt moved to do so.

[edit] ooh, I forgot to mention that the object rotation scripting came from Social’s FPS template (I hate messing with the orientation matrix, so many thanks for doing it for me)


#================================
#fast bullet collision script
#by Liam Richardson (AKA Captain Oblivion)
#================================

#-------------------
#requires:
#properties: velX,velY,velZ,topSpeed
#you can set topSpeed to whatever you like, I use 5 to be safe
#note that you can change any of the vel variables manually or with other scripts, to do things like give the bullet a starting speed or apply wind
#you also need a ray sensor named raySolid, Range must be the same as the topSpeed variable, axis must be +Z
#-------------------

#define useful functions
def VEC_length(A):
    return sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2])
def VEC_normalize(A):
    vecLen=VEC_length(A)
    return [A[0]/vecLen,A[1]/vecLen,A[2]/vecLen]
    return [x[0]/length,x[1]/length,x[2]/length]
def VEC_cross(x, y):
    return  [x[1]*y[2] - x[2]*y[1],
             x[2]*y[0] - x[0]*y[2],
             x[0]*y[1] - x[1]*y[0]]
def VEC_min(x, y):
    return [x[0] - y[0], x[1] - y[1], x[2] - y[2]]
def MAT_trackvector(fw, y):
    if abs(abs(fw[2]) - abs(y[2])) < .001:
        y.append(y[0])
        del y[0]
    right = VEC_normalize(VEC_cross(y, fw))
    up = VEC_cross(fw, right)
    return [[right[0], up[0], fw[0]],
        [right[1], up[1], fw[1]],
        [right[2], up[2], fw[2]]]

#imports, variable declarations, and the like
from math import sqrt
g=GameLogic
c=g.getCurrentController()
o=c.getOwner()

raySolid=c.getSensor("raySolid")
pos=o.getPosition()
hit=0

#gravity
o.velZ-=.0026

#limit speed (It may be pointless to gripe every time I have to use a workaround, but I will anyways. this would be unnecessary if I could dynamically change the ray's Range)
speed=VEC_length([o.velX,o.velY,o.velZ])
if speed>o.topSpeed:
    velNorm=VEC_normalize([o.velX,o.velY,o.velZ])
    o.velX=velNorm[0]*o.topSpeed
    o.velY=velNorm[1]*o.topSpeed
    o.velZ=velNorm[2]*o.topSpeed

#bullet always faces with it's +Z axis pointing the direction it's moving
o.setOrientation(MAT_trackvector(VEC_normalize([o.velX,o.velY,o.velZ]),[0.0,0.0,1.0]))

#if the ray sensor is positive, there's a collision within the maximum distance the bulelt can move
if raySolid.isPositive():
    #this is a workaround because I can't change the ray's Range value with python
    hitPos=raySolid.getHitPosition()
    hitDist=VEC_length([pos[0]-hitPos[0],pos[1]-hitPos[1],pos[2]-hitPos[2]])
    #check if the collision will occur during this frame
    if hitDist<=VEC_length([o.velX,o.velY,o.velZ]):
        hit=1
        o.velX,o.velY,o.velZ=[0,0,0]
        o.setPosition(hitPos)
if hit==0:
    o.setPosition([pos[0]+o.velX,pos[1]+o.velY,pos[2]+o.velZ])

well, I hope this is useful for somebody other than me ^^

It sounds good but it would be nice to see it in action. Do you have anything made up to show it’s usefulness?

~~Stu

Well I’m not that good with scripting, but I was making a top down shooter and had that problem. I just used logic bricks and made it where when something with the “bullet” property touched it, it ended the bullets life.

here’s an example using the bullet. please excuse the graphics (I needed an explosion, so I threw it together)

[edit] oh, right, this was made as a test to see if the game was worth making (I’ve taken to seeing if all the main features of a game are even remotely possible in blender before starting a project- I used to get halfway through making the main engine, the run into some absurd roadblock, the only solution to which is to wait for the bug to be fixed). The point of saying all this is that the game doesn’t actually exist yet, so there’s no example of it in action- yet…

Are you really making up the game of your own.I want to have a preview of that can you tell me any url where i can found any pics of your game. Please.:cool:

Okay, thanks for the example. It works well, and if you’re going to use the template then it isn’t much extra logic. High speed collisions are indeed a pain in blender and you’ve done a job job of making one work around. Good job, and good luck with the game development!

~~Stu

I updated the file, it’s now a simple artillery target practice test file. again, please excuse the graphics, this is just a simple test.

if you don’t want to scroll to my last post, here’s the link again.

[edit] I just learned that the splitscreen script doesn’t work properly inside blender, so it’s set up to look right in blender. this means it’ll look wrong if you export the exe; it’s not a huge deal though.

and screenshots:

Attachments