]> Untitled Git - baabarian.git/blobdiff - player/player.gd
* Added dust clouds
[baabarian.git] / player / player.gd
index d538d8b327ee48b90241f103e99637af56ea2e74..84657ec2db18c6c8a3d4fb61e37c2093a09bed84 100644 (file)
@@ -10,17 +10,15 @@ class_name Player
 
 @export var air_speed := 3.0
 @export var acceleration := 20.0
-@export var jump_speed := 6.0
 @export var rotation_speed := 10.0
-@export var fall_speed := 1.2
 @export var idle_timeout := 5.0
 @export var hard_landing_limit := 10.0
 
 @export_group("Physics")
-@export var push_force := 1.5
+@export var push_force := 5.0
 
 @export_group("Camera")
-@export_range(1.0, 10.0) var camera_distance := 2.5
+@export_range(1.0, 10.0) var camera_distance := 2.0
 @export_range(0.0, 1.0) var mouse_sensitivity := 0.15
 @export_range(0.0, 1.0) var mouse_sensitivity_x := 1.0
 @export_range(0.0, 1.0) var mouse_sensitivity_y := 0.5
@@ -31,24 +29,31 @@ class_name Player
 @onready var _debug: CanvasLayer = %debug
 @onready var _camera_pivot: Node3D = %camera_pivot
 @onready var _camera: Camera3D = %camera
+@onready var _camera_spring: SpringArm3D = %spring
 @onready var _skin: AnimatedSkin = %skin
+@onready var _dust: GPUParticles3D = %dust
 
 var _last_movement_direction := rotation
+var _floor_normal := Vector3.ONE
 var _camera_input_direction := Vector2.ZERO
 
 enum {CAMERA_MOUSE_INPUT, CAMERA_JOYSTICK_INPUT}
 var _camera_input_method := CAMERA_MOUSE_INPUT
 
 var _idle_time: float = 0.0
-var _player_speed: float = walk_speed
+var _player_speed: float = 0
 
 
 func _ready() -> void:
-       $camera_pivot/SpringArm3D.spring_length = camera_distance
        _debug.draw.add_vector(self, "velocity", 1, 1, Color(0,1,0,1))
+       _debug.draw.add_vector(self, "_floor_normal", 1, 1, Color(0, 0, 1, 1))
        _debug.draw.add_vector(self, "_last_movement_direction", 1, 1, Color(1,0,0,1))
        _debug.stats.add_property(self, "velocity", "length")
        _debug.stats.add_property(self, "_idle_time", "round")
+       
+       _camera_spring.spring_length = camera_distance
+       _player_speed = jog_speed
+       _skin.set_grounded()
 
 
 func _physics_process(delta: float) -> void:
@@ -73,12 +78,14 @@ func _unhandled_input(event: InputEvent) -> void:
 
 func _input(event: InputEvent):
        if event.is_action_pressed("player_run"):
-               _player_speed = jog_speed
-       elif event.is_action_released("player_run"):
                _player_speed = walk_speed
+       elif event.is_action_released("player_run"):
+               _player_speed = jog_speed
        
        if event.is_action_pressed("player_attack") and velocity.length() > jog_speed * .75:
                _player_speed = charge_speed
+       elif event.is_action_released("player_attack"):
+               _player_speed = jog_speed
 
 
 # Get the XZ input direction based on player's input relative to the camera
@@ -102,35 +109,54 @@ func _process_camera(delta: float) -> void:
        # reset mouse movement vector if mouse input
        if _camera_input_method == CAMERA_MOUSE_INPUT:
                _camera_input_direction = Vector2.ZERO
+               
+       # change spring length depending on player speed
+       _camera_spring.spring_length = lerp(
+               _camera_spring.spring_length, camera_distance + velocity.length() / 4, delta 
+       ) 
 
 
 func _process_player_on_floor(delta: float):
        var move_direction := _get_player_move_direction()
        
        # if we're not stuck, then it's okay to set the velocity
-       velocity = velocity.move_toward(move_direction * _player_speed, acceleration * delta)
+       _floor_normal = get_floor_normal()
+       var ground_angle := move_direction.angle_to(_floor_normal * Vector3(1, 0, 1))
+       #print(str(ground_angle))
+       velocity = velocity.move_toward(move_direction * (_player_speed + ground_angle), acceleration * delta)
        var movement_speed := Vector3(velocity.x, 0, velocity.z).length()
        
        # also, if we're moving, we're not idle
        if move_direction.length() < 0.2:
                if velocity == Vector3.ZERO:
                        _idle_time += delta
+               if _idle_time > idle_timeout:
+                       _skin.set_idle()
        else:
                _last_movement_direction = move_direction
                _idle_time = 0.0
+               _skin.set_grounded()
 
        # if camera is unlocked, rotate whole skin to face movement direction
-       # else, rotate to face camera pivot global Y direction
        var skin_target_angle := Vector3.BACK.signed_angle_to(_last_movement_direction, Vector3.UP)
        _skin.global_rotation.y = lerp_angle(
                _skin.global_rotation.y,
                skin_target_angle,
                rotation_speed * delta
                )
-       _skin.set_movement_speed(movement_speed)
+               
+       # lean into player momentum just a little bit
+       _skin.rotation.z = lerp_angle(
+               _skin.rotation.z,
+               clamp(_last_movement_direction.signed_angle_to(velocity, Vector3.UP) * movement_speed * 0.08, -PI/4, PI/ 4),
+               rotation_speed * delta * 0.25
+               )
+       
+       # let skin know how fast player is moving along the ground
+       _skin.set_grounded_speed(movement_speed)
        
        # timescale tweaking for fun effect!
-       if movement_speed >= charge_speed * 0.75:
+       if _player_speed == charge_speed:
                _skin.set_timescale(2.0)
        else:
                _skin.set_timescale(1.0)
@@ -139,16 +165,20 @@ func _process_player_on_floor(delta: float):
 func _process_player(delta: float) -> void:
        if is_on_floor():
                _process_player_on_floor(delta)
+       
+               _dust.emitting = velocity.length() > (0.75 * charge_speed) and is_on_floor()
+               _dust.amount_ratio = velocity.length()
        else:
+               _skin.set_falling()
                velocity += get_gravity() * air_speed * delta
 
        # now actually move!
-       var movement_speed := velocity.length()
+       var velocity_length := velocity.length()
        move_and_slide()
-       
+
        # handle collisions 
        for i in get_slide_collision_count():
                var c := get_slide_collision(i)
                if c.get_collider() is RigidBody3D:
                        var col: RigidBody3D = c.get_collider()
-                       col.apply_central_impulse(-c.get_normal() * push_force * movement_speed / col.mass)
+                       col.apply_central_impulse(-c.get_normal() * velocity_length * push_force)