extends KinematicBody onready var util = get_node("/root/Util") export var gravity: float = 6.0 # When falling, gravity is artificially increased export var gravity_downwards_factor: float = 3 # Rate of gaining speed export var velocity_acceleration_xz: float = 3 export var velocity_acceleration_y: float = 5 # Rate of losing speed when stopping export var velocity_friction_xz: float = 15 export var velocity_friction_y: float = 1 export var jump_power: float = 50 # Controls the base speeds of walking and sprinting export var sprint_factor: float = 3.5 export var walk_factor: float = 1.5 "public" var velocity: Vector3 = Vector3.ZERO # Value changed by code only to add slow down or speed up effects var velocity_factor: Vector3 = Vector3.ONE var target_velocity: Vector3 = Vector3.ZERO var is_jumping: bool = false var jump_permission: float = 1.0 var is_falling: bool = false var is_falling_medium = false var is_falling_terminally: bool = false var just_landed: bool = false var just_landed_medium: bool = false var just_landed_terminally: bool = false func get_terminal_falling_velocity(): return -9 func is_falling_velocity_terminal(): return velocity.y <= get_terminal_falling_velocity() func process_velocity(delta: float): # Uses the input from MovementInput to compute and update this node's velocity # velocity_acceleration controls gradual speedup whereas velocity_friction # controls gradual slowdown # Gravity # You can buffer jumps by pressing releaseing the space bar and then pressing it again if not is_on_floor(): var grav = -gravity target_velocity.y = grav # Gravity is stronger when you're falling. Feels nicer target_velocity.y *= util.clamped_lerp(gravity_downwards_factor, 1.0, velocity.y/2, 0.0) else: velocity.y = max(0.0, velocity.y) target_velocity.y = max(0.0, max(target_velocity.y, jump_power * $"../MovementInput".jump_intent * jump_permission)) if not is_jumping and $"../MovementInput".jump_intent != 0.0 and is_on_floor(): jump_permission = 0.0 is_jumping = true elif is_jumping and $"../MovementInput".jump_intent == 0.0: jump_permission = 1.0 is_jumping = false var target_velocity_xz = $"../MovementInput".input_xz if $"../MovementInput".sprinting: target_velocity_xz *= sprint_factor else: target_velocity_xz *= walk_factor target_velocity = util.vec2_xz_to_vec3(target_velocity_xz, target_velocity.y) var velocity_xz = util.vec3_xz(velocity) var xz_weight = velocity_acceleration_xz * delta if target_velocity_xz.length() < velocity_xz.length(): xz_weight = velocity_friction_xz * delta var target_xz_length = util.clamped_lerp(velocity_xz.length(), target_velocity_xz.length(), xz_weight, 0.25) if target_velocity_xz != Vector2.ZERO: velocity_xz = target_velocity_xz.normalized() * target_xz_length elif velocity_xz != Vector2.ZERO: velocity_xz = velocity_xz.normalized() * target_xz_length var y_weight = velocity_acceleration_y * delta if target_velocity.y < velocity.y: y_weight = velocity_friction_y * delta var velocity_y = util.clamped_lerp(velocity.y, target_velocity.y, y_weight, 0.25) velocity = util.vec2_xz_to_vec3(velocity_xz, velocity_y) * velocity_factor func process_falling(): if not $Floor.is_on_floor: is_falling = true just_landed = false just_landed_terminally = false if velocity.y <= 5.0: is_falling_medium = true if is_falling_velocity_terminal(): is_falling_terminally = true return just_landed = is_falling just_landed_medium = is_falling_medium just_landed_terminally = is_falling_terminally is_falling = false is_falling_medium = false is_falling_terminally = false func increase_velocity_factor(by: Vector3): velocity_factor *= by func decrease_velocity_factor(by: Vector3): velocity_factor /= by func _physics_process(delta): process_velocity(delta) velocity = move_and_slide(velocity, Vector3.UP) process_falling()