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.
 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*A+A*A+A*A) def VEC_normalize(A): vecLen=VEC_length(A) return [A/vecLen,A/vecLen,A/vecLen] return [x/length,x/length,x/length] def VEC_cross(x, y): return [x*y - x*y, x*y - x*y, x*y - x*y] def VEC_min(x, y): return [x - y, x - y, x - y] def MAT_trackvector(fw, y): if abs(abs(fw) - abs(y)) < .001: y.append(y) del y right = VEC_normalize(VEC_cross(y, fw)) up = VEC_cross(fw, right) return [[right, up, fw], [right, up, fw], [right, up, fw]] #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*o.topSpeed o.velY=velNorm*o.topSpeed o.velZ=velNorm*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-hitPos,pos-hitPos,pos-hitPos]) #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+o.velX,pos+o.velY,pos+o.velZ])
well, I hope this is useful for somebody other than me ^^