class_name PlayerCharacter extends CharacterBase3D const ACTION_RUN: StringName = &"run" const ACTION_JUMP: StringName = &"jump" const ACTION_MOVE_LEFT: StringName = &"move_left" const ACTION_MOVE_RIGHT: StringName = &"move_right" const ACTION_MOVE_FORWARD: StringName = &"move_forward" const ACTION_MOVE_BACKWARD: StringName = &"move_backward" var has_control: bool = true @onready var head: GameCamera3D = $Head func _ready() -> void: GameGlobals.player = self if not get_tree().root.is_node_ready(): await get_tree().root.ready var spawn_point := PlayerSpawnPoint.get_spawn_point_by_index(GameGlobals.spawn_index) if is_instance_valid(spawn_point): global_position = spawn_point.global_position head.global_rotation = spawn_point.global_rotation func _physics_process(delta: float) -> void: # Add the gravity. if not is_on_floor(): apply_gravity(delta) if not has_control: move(Vector3.ZERO, delta) move_and_slide() return # Handle jump. if Input.is_action_just_pressed(ACTION_JUMP) and is_on_floor(): jump() var input_dir: Vector3 = get_input_direction() movement_direction = input_dir.normalized() # Rotate the movement direction based on the cameras orientation. movement_direction = movement_direction.rotated(Vector3.UP, head.global_rotation.y) speed = get_desired_speed() * input_dir.length() move(movement_direction, delta) move_and_slide() func apply_gravity(delta: float) -> void: super(delta) func get_input_direction() -> Vector3: if not InputManager.window_focused(): return Vector3.ZERO var input_dir := Input.get_vector(ACTION_MOVE_LEFT, ACTION_MOVE_RIGHT, ACTION_MOVE_FORWARD, ACTION_MOVE_BACKWARD) var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 1, input_dir.y))#.normalized() direction.y = 0.0 return direction func get_desired_speed() -> float: if Input.is_action_pressed(ACTION_RUN): return movement.running_speed if is_on_floor() else movement.air_running_speed return movement.walking_speed if is_on_floor() else movement.air_walking_speed