extends CharacterBody3D class_name Player ########## # settings ########## @export_group("Movement") @export var walk_speed := 8.0 @export var dash_length := 10.0 @export var air_speed := 3.0 @export var acceleration := 30.0 @export var rotation_speed := 10.0 @export var idle_timeout := 5.0 ###### # init ###### @onready var _input: InputHandler = %Input @onready var _camera: Camera3D = %camera @onready var _skin: AnimatedSkin = %skin var _last_movement_direction: Vector3 = rotation var _floor_normal := Vector3.ONE var _ground_slope_input := 0.0 var _idle_time: float = 0.0 var _player_speed: float = walk_speed ########## # movement ########## func _physics_process(delta: float) -> void: var input_pkt := _input.get_player_input() velocity = _get_velocity_by_input(input_pkt, delta) move_and_slide() # Get the XZ input direction based on player's input relative to the camera func _get_player_move_direction(input_dir: Vector2) -> Vector3: var forward := _camera.global_basis.z var right := _camera.global_basis.x var move_direction := (forward * input_dir.y + right * input_dir.x).normalized() move_direction.y = 0 return move_direction func _get_velocity_by_input(input_pkt: InputPacket, delta: float) -> Vector3: var new_velocity: Vector3 = velocity if is_on_floor(): var move_dir := _get_player_move_direction(input_pkt.movement_direction) # if we're not stuck, then it's okay to set the velocity _floor_normal = get_floor_normal() _ground_slope_input = (PI / 2) - new_velocity.angle_to(_floor_normal) new_velocity = new_velocity.move_toward( move_dir * (_player_speed + _ground_slope_input * _player_speed), acceleration * delta ) else: new_velocity += get_gravity() * air_speed * delta return new_velocity ######### # actions ######### func _player_dash(): if _last_movement_direction != Vector3.ZERO: var dash_local_pos = _last_movement_direction * dash_length # TODO: check if valid position, crop the vector to last valid position global_position += dash_local_pos