I am using move with snap on my fps controller to allow my character to stick to slopes. The controller can walk up slopes easily. However, when you move on a slope, and then stop moving, the character will slide down the slope a little before stopping. If you jump while on a slope, no sliding occurs, it is only while walking. It will always slide down, no matter which direction you are walking. I am not sure why this is happening, but I think it might be because of my use of linear interpolation to smooth the movement.
Here is my code for the fps controller. Sorry it's a little long, I tried to organize it but I'm not the best at that. =)
extends KinematicBody
export var mouse_sensetivity = .1
export var jump_time = 1.5
var jump_time_counter
export var jump_strength = 6.5
export var walking_speed = 7
export var airborne_speed = 2
export var gravity = 30
var speed = walking_speed
var velocity = Vector3.ZERO
var h_velocity = Vector3.ZERO
var h_acceleration = .2
var air_acceleration = .08
var normal_acceleration = .2
var snap_direction = Vector3.DOWN
onready var head = $Head
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
jump_time_counter = jump_time
pass
func _input(event):
if event is InputEventMouseMotion:
head.rotation_degrees.x += event.relative.y * mouse_sensetivity
head.rotation_degrees.x = clamp(head.rotation_degrees.x, -90, 75)
head.rotation_degrees.y -= event.relative.x * mouse_sensetivity
head.rotation_degrees.y = wrapf(head.rotation_degrees.y, 0, 360)
func _physics_process(delta):
handle_movement(delta)
handle_jumping(delta)
if Input.is_action_just_pressed("ui_cancel"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
velocity = move_and_slide_with_snap(velocity, snap_direction, Vector3.UP, true)
func handle_jumping(delta):
var just_landed = is_on_floor() and snap_direction == Vector3.ZERO
var jumping = Input.is_action_pressed("jump")
if jumping and jump_time_counter > 0:
velocity.y = jump_strength
h_acceleration = air_acceleration
snap_direction = Vector3.ZERO
speed = airborne_speed
jump_time_counter -= delta
elif just_landed:
h_acceleration = normal_acceleration
jump_time_counter = jump_time #reset jump counter so the player can jump again.
snap_direction = Vector3.DOWN
speed = walking_speed #change speed back to full controll.
if Input.is_action_just_released("jump"):
jump_time_counter = 0
func handle_movement(delta):
var move_direction = Vector3.ZERO
move_direction.x = Input.get_action_strength("left") - Input.get_action_strength("right")
move_direction.z = Input.get_action_strength("forward") - Input.get_action_strength("backward")
move_direction = move_direction.rotated(Vector3.UP, head.rotation.y).normalized()
velocity.x = move_direction.x
velocity.z = move_direction.z
velocity.y -= gravity * delta
h_velocity = h_velocity.linear_interpolate(move_direction * speed, h_acceleration)
velocity.z = h_velocity.z
velocity.x = h_velocity.x
Thanks!