How does one try and make it so when a player is climbing, the game checks the angle or normal of the surface, and then applies the correct mechanism? There used to be AngleBetweenVecs, CrossVecs, etc, but they got taken out when Blender was transitioning to 2.5 years ago, and since then, I have found no identical built in function. An example is when the player deflects off a wall.
simply by using .angle()
What I am trying to accomplish here is this scenario:
A cube (or some other object) is going towards an object. A Radar sensor picks up the angle of the objects nearest face, and if the angle of the face normal is too steep (maybe like 60 or more degrees), it will try and move out of the way). This can also be used for slippery surfaces and to make game characters slip over when a staircase suddenly goes flat for instance, or on ice.
I know, i got it build in in my:
to take it apart it’s this code you are looking for to adjust to your liking, 3 properties needed
height_direction → string
slope_angle → float
on_slope → boolean
# check if we go up or downwards dead_zone = 0.05 #from this z speed to detect up/down movement if own.worldLinearVelocity.z < -dead_zone: own['height_direction'] = 'down' # if we go down, we want our character be able to slide down when we have no collision z = own.localLinearVelocity.z elif own.localLinearVelocity.z > dead_zone: own['height_direction'] = 'up' else: own['height_direction'] = 'even'
Thr code above is not needed, but it’s an additional debug option / a check to add velocity back, this can be scripted into the lowest part.
def on_slope(cont): own = cont.owner # shoot a ray distance = 1.5 z_direction = own.worldPosition - own.worldOrientation.col ray = own.rayCast(z_direction, own, distance) # grab the hitNormal or create a dummy one (z direction) if ray: hit_normal = ray else: hit_normal = [0,0,1.0] # grab a z vector z_vec = own.worldOrientation.col # calculate angle between hitnormal and the z vector angle = z_vec.angle(hit_normal) # convert to degrees degrees = math.degrees(angle) # debug option own['slope_angle'] = degrees # if we get some degree then we are on a slope if degrees: own['on_slope'] = True return True # if we do not have a degree or it's 0 then we are not on a slope own['on_slope'] = False return False
Then the check is executed like this:
# slope check if on_slope(cont): #if we are on a slope and we are idle, give an upforce to the player to stop sliding down if own['player_action'] == 'idle': own.applyForce((0,0,own.mass * 9.8)) # slow our speed down when we are on a slope (just like real life) # The angle itself will slowdown the player as well y = y/1.5
With this you can create all you want.