]> Untitled Git - baabarian.git/blob - player.gd
Added test scene, debug UI, and player
[baabarian.git] / player.gd
1 extends CharacterBody3D
2 class_name Player
3
4
5 # player settings
6 @export_group("Movement")
7 @export var walk_speed := 3.0
8 @export var jog_speed := 6.0
9 @export var charge_speed := 20
10
11 @export var air_speed := 3.0
12 @export var acceleration := 30.0
13 @export var jump_speed := 6.0
14 @export var rotation_speed := 10.0
15 @export var fall_speed := 1.2
16 @export var idle_timeout := 5.0
17 @export var hard_landing_limit := 10.0
18
19 @export_group("Camera")
20 @export_range(1.0, 10.0) var camera_distance := 2.0
21 @export_range(0.0, 1.0) var mouse_sensitivity := 0.15
22 @export_range(0.0, 1.0) var mouse_sensitivity_x := 1.0
23 @export_range(0.0, 1.0) var mouse_sensitivity_y := 0.5
24 @export_range(0.0, 10.0) var joystick_sensitivity_x := 4.0
25 @export_range(0.0, 10.0) var joystick_sensitivity_y := 2.0
26
27
28 @onready var _debug: CanvasLayer = %debug
29 @onready var _camera_pivot: Node3D = %camera_pivot
30 @onready var _camera: Camera3D = %camera
31 @onready var _skin: AnimatedSkin = %skin
32
33 var _last_movement_direction := rotation
34 var _camera_input_direction := Vector2.ZERO
35
36 enum {CAMERA_MOUSE_INPUT, CAMERA_JOYSTICK_INPUT}
37 var _camera_input_method := CAMERA_MOUSE_INPUT
38
39 var _idle_time: float = 0.0
40 var _player_speed: float = walk_speed
41
42
43 func _ready() -> void:
44         _debug.draw.add_vector(self, "velocity", 1, 1, Color(0,1,0,1))
45         _debug.draw.add_vector(self, "_last_movement_direction", 1, 1, Color(1,0,0,1))
46         _debug.stats.add_property(self, "velocity", "length")
47         _debug.stats.add_property(self, "_idle_time", "round")
48
49
50 func _physics_process(delta: float) -> void:
51         _process_camera(delta)
52         _process_player(delta)
53
54
55 func _unhandled_input(event: InputEvent) -> void:
56         # If user clicks on the window, capture the mouse and direct the camera with it
57         if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
58                 return
59
60                         #_camera_input_direction *= mouse_sensitivity
61         if event is InputEventMouseMotion:
62                 _camera_input_method = CAMERA_MOUSE_INPUT
63                 _camera_input_direction = event.screen_relative * mouse_sensitivity
64         elif event is InputEventJoypadMotion:
65                 _camera_input_method = CAMERA_JOYSTICK_INPUT
66                 _camera_input_direction = Input.get_vector("camera-left", "camera-right", "camera-up", "camera-down")
67                 _camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y)
68
69
70 func _input(event: InputEvent):
71         if event.is_action_pressed("player_run"):
72                 _player_speed = jog_speed
73         elif event.is_action_released("player_run"):
74                 _player_speed = walk_speed
75         
76         if event.is_action_pressed("player_attack") and velocity.length() > jog_speed * .75:
77                 _player_speed = charge_speed
78
79
80 # Get the XZ input direction based on player's input relative to the camera
81 func _get_player_move_direction() -> Vector3:
82         var input_dir := Input.get_vector("player_left", "player_right", "player_forward", "player_backward")
83         var forward := _camera.global_basis.z
84         var right := _camera.global_basis.x
85         var move_direction := (forward * input_dir.y + right * input_dir.x).normalized()
86         move_direction.y = 0
87         return move_direction
88
89
90 func _process_camera(delta: float) -> void:
91         # vertical camera rotation
92         _camera_pivot.rotation.x += _camera_input_direction.y * mouse_sensitivity_y * delta
93         _camera_pivot.rotation.x = clamp(_camera_pivot.rotation.x, -PI / 6, PI / 3)
94
95         # horizontal camera rotation
96         _camera_pivot.rotation.y -= _camera_input_direction.x * mouse_sensitivity_x * delta
97
98         # reset mouse movement vector if mouse input
99         if _camera_input_method == CAMERA_MOUSE_INPUT:
100                 _camera_input_direction = Vector2.ZERO
101
102
103 func _process_player(delta: float) -> void:
104         var move_direction := _get_player_move_direction()
105         
106         # if we're not stuck, then it's okay to set the velocity
107         velocity = velocity.move_toward(move_direction * _player_speed, acceleration * delta)
108         var movement_speed := Vector3(velocity.x, 0, velocity.z).length()
109         
110         # also, if we're moving, we're not idle
111         if move_direction.length() < 0.2:
112                 if velocity == Vector3.ZERO:
113                         _idle_time += delta
114         else:
115                 _last_movement_direction = move_direction
116                 _idle_time = 0.0
117
118         # if camera is unlocked, rotate whole skin to face movement direction
119         # else, rotate to face camera pivot global Y direction
120         var skin_target_angle := Vector3.BACK.signed_angle_to(_last_movement_direction, Vector3.UP)
121         _skin.global_rotation.y = lerp_angle(
122                 _skin.global_rotation.y,
123                 skin_target_angle,
124                 rotation_speed * delta
125                 )
126         _skin.set_movement_speed(movement_speed)
127
128         move_and_slide()