Ray car

(BluePrintRandom) #1

rayCar2.blend (565.3 KB)

import bge
from mathutils import Vector

def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner
    S = cont.sensors['S']
    #store wheelbases
    if 'wheelBases' not in own:
        wb = []
        sp = []
        for child in own.children:
            if 'WheelPoint' in child:
                
                wb.append(child)
            
        own['wheelBases'] = wb
        print('stored '+str(len(wb))+' Wheels')
    
    
    # apply wheel code to each wheel
    for wheelBase in own['wheelBases']:
        if 'SteerMe' in wheelBase:
            rot = own.worldOrientation.to_euler()
            rot.z += own['Steering']*.5
            wheelBase.worldOrientation = rot
            
        end = wheelBase.worldPosition+own.worldOrientation.col[2]*-.66
        start = wheelBase.worldPosition+own.worldOrientation.col[2]*-.125
        ray = own.rayCast(end, start, 0, '', 0,0,0)
        local =  wheelBase.localPosition
        travel = (start-end).magnitude
        
        
        #if the ray hits the wheel is on something
        if ray[0]:
            tire = wheelBase.children[0]
            own.localAngularVelocity.z*=.975
            tire['roll']= ((tire['roll']*7)+own.localLinearVelocity.x*.025*local.y)/8
            tire.applyRotation((0,0,tire['roll']*.5),1)
            if 'SteerMe' in wheelBase:
                if abs(own.localLinearVelocity.y)<2.5:
                    own.applyTorque( (0,0,own.localLinearVelocity.x * own['Steering']),1 )
                else:
                    own.applyTorque( (0,0,own.localLinearVelocity.x * (own['Steering']* 1.5)),1 )
                        
                             
            if 'DriveMe' in wheelBase:
                if abs(own.localLinearVelocity.y)<1.5:
                    own.applyImpulse((start+ray[1])/2,own.worldOrientation.col[0]*own['Throttle']*.025)
                    
                    
                    if  own['Throttle']>0 and 'RTime' in own and not S.positive:
                        del own['RTime']
                        
                    elif own['Throttle']<=0 and 'RTime' not in own and S.positive:
                        own['RTime'] =0
                    elif 'RTime' in own:    
                        if own['RTime']<=14:
                            own['RTime']+=1
                        elif own['RTime']<=19:
                            own['RTime']+=.1
                            own.applyImpulse((start+ray[1])/2,own.worldOrientation.col[0]*own['RTime']*-.005)
                            
                        else:
                            own.applyImpulse((start+ray[1])/2,own.worldOrientation.col[0]*own['RTime']*.1)
                else:
                    own.applyImpulse((start+ray[1])/2,own.worldOrientation.col[0]*own['Throttle']*.025)
                                            
            
            hit_distance = (start-ray[1]).magnitude
            ratio = 1 - (hit_distance/travel)
             
            #print(ratio)
            
            #lift up car with spring force
            own.applyImpulse(ray[1], own.worldOrientation.col[2]*(ratio+ratio)*.06125*2.95)
            own.applyImpulse(ray[1], own.worldOrientation.col[2].reflect(ray[2])*ratio*.06125*-.5)
            vecDist = (own.worldOrientation.col[2]-Vector([0,0,1])).magnitude
            if vecDist<.66:
                own.applyImpulse(start, Vector([0,0,ratio*.06125*.77]))
                own.worldLinearVelocity.z*=.995
            wheelBase.children[0].worldPosition =  wheelBase.children[0].worldPosition.lerp(ray[1]+ (own.worldOrientation.col[2]*(wheelBase.children[0]['r'])),.5)
            
            
            #vertical dampening
            if own.localLinearVelocity.z < 0:
                own.localLinearVelocity.z*= .95
            elif hit_distance < (travel/2) and vecDist<.66:
                own.localLinearVelocity.z*= .975
                
            
            #angular dampening
            
            #print(vecDist)
            
            #print(local)
            diff2 = (own.worldOrientation.col[2]-ray[2]).magnitude
            print(diff2)
            if diff2 <.5:
                if local.x > 0 and own.localAngularVelocity.y < 0:
                    own.localAngularVelocity.y *= 1 -(ratio*.63)
                
                if local.x < 0 and own.localAngularVelocity.y > 0:
                    own.localAngularVelocity.y *= 1 -(ratio*.63)
                    
                if local.y > 0 and own.localAngularVelocity.x > 0:
                    own.localAngularVelocity.x *= 1 -(ratio*.63)
                
                if local.y < 0 and own.localAngularVelocity.x < 0:
                    own.localAngularVelocity.x *= 1 -(ratio*.63)
            
            if local.y > 0 and own.localLinearVelocity.y < 0:
                own.applyTorque([own.localLinearVelocity.y* -2.125,0,0],1)
                own.localLinearVelocity.y*=.995
            elif local.y < 0 and own.localLinearVelocity.y > 0:
                own.applyTorque([own.localLinearVelocity.y* -2.125,0,0],1)    
                own.localLinearVelocity.y*=.995
            if vecDist<.46:
                own.localLinearVelocity.y *= ((1-ratio)*.5 )+.5
                
                
        #push out the tire to max suspension travel if the ray does not hit                         
        else:
            tire = wheelBase.children[0]
            tire.worldPosition = tire.worldPosition.lerp(wheelBase.worldPosition + (own.worldOrientation.col[2]* - (travel-(tire['r'])) ), .5)
            tire['roll'] = ((tire['roll']*7) +  own['Throttle']*.025*local.y)/8
            tire.applyRotation((0,0,tire['roll']*.5),1)
            
main()
(Nicholas_A) #2

or you could use the vehicle wrapper. Just seems easier.

(Daedalus_MDW) #3

the vehicle wrapper is nice, but its not very stable.

making your own allows you to constrain forces better, or even prevent the vehicle from dropping through the ground.

(BluePrintRandom) #4

yeah the vehicle wrapper is less flexible, [upbge vehicle wrapper is more flexible than bge]

this is 100% adjustable - I can tune behaviors. :smiley:

(Lostscience) #5

in the thirdperson videogame i made that has a car in it.you can cause the car to be upside down and get out on your head.but your car cannot be turned upside.i like that feature of your car.

(AeroLynx) #6

Sweet! Thanks for sharing :ok_hand:

Just recently, I stumbled upon this presentation from the Rocket League devs:

As it deals heavily with tuning car physics, I’ll leave this here for your entertainment.

(BluePrintRandom) #7

thanks

I may have tuned this up after this, I am not sure.

(AeroLynx) #8

In the above Rocke League presentation, the roll-over behavior of the car seen as in your demo video is discussed 15:55 onwards. He describes their trick of avoiding it as well. Really interesting presentation.