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[2]
ray = own.rayCast(z_direction, own, distance)
# grab the hitNormal or create a dummy one (z direction)
if ray[0]:
hit_normal = ray[2]
else:
hit_normal = [0,0,1.0]
# grab a z vector
z_vec = own.worldOrientation.col[2]
# 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.