Godot Version
Godot Version 3.5
Question
Last time I was here I lamented a problem I was having with adding with adding climbing and the scene crashing. I have fixed the issue with the scene crashing and I found a work around with the player clipping into the sky. The issue I’m having now is with the jump, or more accurately, lack there of. The current issue is that the player stays stuck to the floor when I try to jump, as seen here;
video of the problem
As the video shows, neither the jump nor the climb works.
Here is the code for you to check.
extends KinematicBody
#exports
export var max_speed = 10
export var acceleration = 70
export var friction = 30
export var air_friction = 10
export var gravity:float= -0.0
export var jump_impulse = 20
export var mouse_sensitivity = .1
export var controller_sensitivity = 3
export var rot_speed = 25
export var climb_speed = 3.0
const GRAVITY: float = -40.0
const JUMP_IMPULSE: float = 01.0
var gravity_active: bool = true
var angular_velocity = 15
#Vectors
var velocity = Vector3.ZERO
var snap_vector = Vector3.ZERO
var direction = Vector3()
var gravity_vec = Vector3()
var movement = Vector3()
#onready vars
onready var spring_arm = $SpringArm
onready var pivot = $Pivot
onready var mesh = $Pivot/skin
#climbing
onready var still_on_wall_check := $Wall_check/still_on_wall_check
onready var wall_check := $Wall_check/wall_check
onready var stick_point_holder = $Stick_point_holder
onready var stick_point = $Stick_point_holder/Stick_point
var is_climbing = false
#mouse
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _unhandled_input(event):
if event.is_action_pressed("click"):
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if event.is_action_pressed("toggel_mouse_captured"):
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if event is InputEventMouseMotion and Input.get_mouse_mode() ==Input.MOUSE_MODE_CAPTURED:
rotate_y(deg2rad(-event.relative.x * mouse_sensitivity))
spring_arm.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity))
func _check_vel_y(VEL_Y: float, debug: String) -> void:
if VEL_Y != velocity.y:
print("Velocity Y Changed %f -> %f at: %s" % [VEL_Y, velocity.y, debug])
VEL_Y = velocity.y
func _physics_process(delta):
var VEL_Y = velocity.y
var input_vector = get_input_vector()
_check_vel_y(VEL_Y, "get_input_vector()")
var direction = get_direction(input_vector)
_check_vel_y(VEL_Y, "get_direction()")
apply_movement(input_vector, direction, delta)
_check_vel_y(VEL_Y, "apply_movement()")
apply_friction(direction, delta)
_check_vel_y(VEL_Y, "apply_friction()")
apply_gravity(delta)
_check_vel_y(VEL_Y, "apply_gravity()")
update_snap_vector()
_check_vel_y(VEL_Y, "update_snap_vector()")
jump()
_check_vel_y(VEL_Y, "jump()")
climbing()
_check_vel_y(VEL_Y, "climbing()")
apply_controller_rotation()
_check_vel_y(VEL_Y, "apply_controller_rotation()")
spring_arm.rotation.x = clamp(spring_arm.rotation.x, deg2rad(-65), deg2rad(25))
_check_vel_y(VEL_Y, "clamp(spring_arm)")
velocity = move_and_slide_with_snap(velocity, snap_vector, Vector3.UP, true)
_check_vel_y(VEL_Y, "move_and_slide_with_snap()")
#inputs
func get_input_vector():
var input_vector = Vector3.ZERO
input_vector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
input_vector.z = Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward")
return input_vector.normalized() if input_vector.length() > 1 else input_vector
func get_direction(input_vector):
var direction = (input_vector.x * transform.basis.x) + (input_vector.z * transform.basis.z)
return direction
#movement, friction, & gravity
func apply_movement(input_vector, direction, delta):
if direction != Vector3.ZERO:
velocity.x = velocity.move_toward(direction*max_speed,acceleration*delta).x
velocity.z = velocity.move_toward(direction*max_speed,acceleration*delta).z
# pivot.look_at(global_transform.origin + direction, Vector3.UP)
pivot.rotation.y = lerp_angle(pivot.rotation.y, atan2(-input_vector.x, -input_vector.z), rot_speed * delta)
func apply_friction(direction, delta):
if direction == Vector3.ZERO:
if is_on_floor():
velocity = velocity.move_toward(Vector3.ZERO, friction * delta)
else:
velocity.x = velocity.move_toward(direction*max_speed,air_friction*delta).x
velocity.z = velocity.move_toward(direction*max_speed,air_friction*delta).z
func apply_gravity(delta: float) -> void:
if gravity_active:
velocity.y = clamp(velocity.y + (delta * GRAVITY), GRAVITY, JUMP_IMPULSE)
#snap to floor
func update_snap_vector():
snap_vector = -get_floor_normal() if is_on_floor() else Vector3.ZERO
#jumping
func jump():
if Input.is_action_just_pressed("jump") and is_on_floor():
snap_vector = Vector3.ZERO
velocity.y = jump_impulse
if Input.is_action_just_released("jump") and velocity.y > jump_impulse /2:
velocity.y = jump_impulse / 2
#climbing
func climbing() -> void:
#check if player is able to climb
if wall_check.is_colliding():
if still_on_wall_check.is_colliding():
if Input.is_action_just_pressed("jump"):
if is_on_floor():
is_climbing = false
else:
is_climbing = true
else:
is_climbing = false
else:
#if player is at top of a climb, boost them over the top
jump()
yield(get_tree().create_timer(0.3), "timeout")
is_climbing = false
is_climbing = false
if is_climbing:
#if player is climbing disable gravity
gravity_active = false
max_speed = climb_speed
direction = Vector3.ZERO
gravity_vec = Vector3.ZERO
#sticks player to the wall
stick_point_holder.global_transform.origin = wall_check.get_collision_point()
self.global_transform.origin.x = stick_point.global_transform.origin.x
self.global_transform.origin.z = stick_point.global_transform.origin.z
#move player relative to the walls normal
var rot = -(atan2(wall_check.get_collision_normal().z, wall_check.get_collision_normal().x) - PI/2)
var f_input = Input.get_action_strength("forward") - Input.get_action_strength("back")
var h_input = Input.get_action_strength("right") - Input.get_action_strength("left")
direction = Vector3(h_input, f_input, 0).rotated(Vector3.UP, rot).normalized()
else:
gravity_active = true
func _process(delta):
#turns body in the direction of movement
if direction != Vector3.ZERO and !is_climbing:
mesh.rotation.y = lerp_angle(mesh.rotation.y, atan2(-direction.x, -direction.z), angular_velocity * delta)
elif direction != Vector3.ZERO and is_climbing:
mesh.rotation.y = -(atan2(wall_check.get_collision_normal().z, wall_check.get_collision_normal().x) - PI/2)
#controller
func apply_controller_rotation():
var axis_vector = Vector2.ZERO
axis_vector.x = Input.get_action_strength("look_right") - Input.get_action_strength("look_left")
axis_vector.y = Input.get_action_strength("look_down") - Input.get_action_strength("look_up")
if InputEventJoypadMotion:
rotate_y(deg2rad(-axis_vector.x) * controller_sensitivity)
spring_arm.rotate_x(deg2rad(-axis_vector.y) * controller_sensitivity)