diff --git a/game/player/InputManagementComponent/InputManagementComponent.gd b/game/player/InputManagementComponent/InputManagementComponent.gd index 27dbbbc..b6c0c2b 100644 --- a/game/player/InputManagementComponent/InputManagementComponent.gd +++ b/game/player/InputManagementComponent/InputManagementComponent.gd @@ -13,6 +13,7 @@ class_name InputManagementComponent @export var run_action : StringName = "player_run" @export var jump_action : StringName = "player_jump" @export var dodge_action : StringName = "player_dodge" +@export var crouch_action : StringName = "player_crouch" @export_subgroup("Camera variables") @export var aim_cam_action : StringName = "player_aim_camera" @export var cam_zoom_in_action : StringName = "player_zoom_camera_in" @@ -38,6 +39,7 @@ func attribute_keybinds() -> void: play_char_ref.run_action = run_action play_char_ref.jump_action = jump_action play_char_ref.dodge_action = dodge_action + play_char_ref.crouch_action = crouch_action play_char_ref.aim_cam_action = aim_cam_action cam_holder_ref.aim_cam_action = aim_cam_action diff --git a/game/player/PlayerCharacter.tscn b/game/player/PlayerCharacter.tscn index dfa72e0..07c3958 100644 --- a/game/player/PlayerCharacter.tscn +++ b/game/player/PlayerCharacter.tscn @@ -10,6 +10,7 @@ [ext_resource type="Script" uid="uid://dn5idrvu68k83" path="res://game/player/StateMachine/AimState.gd" id="7_kxr4l"] [ext_resource type="Script" uid="uid://dpcfffs3vt5co" path="res://game/player/StateMachine/RunState.gd" id="8_j4mf1"] [ext_resource type="Script" uid="uid://bwojkp7yrwswt" path="res://game/player/StateMachine/DodgeState.gd" id="9_6abew"] +[ext_resource type="Script" uid="uid://d0577tj0c23bu" path="res://game/player/StateMachine/CrouchState.gd" id="10_mi63v"] [sub_resource type="Curve" id="Curve_kxr4l"] _limits = [0.0, 10.0, 0.0, 1.0] @@ -89,5 +90,8 @@ script = ExtResource("8_j4mf1") [node name="DodgeState" type="Node" parent="StateMachine" unique_id=232179400] script = ExtResource("9_6abew") +[node name="CrouchState" type="Node" parent="StateMachine" unique_id=381419367] +script = ExtResource("10_mi63v") + [node name="InputManagementComponent" type="Node" parent="." unique_id=1981951371] script = ExtResource("2_r5dqo") diff --git a/game/player/StateMachine/AimState.gd b/game/player/StateMachine/AimState.gd index 1774cc4..09f9498 100644 --- a/game/player/StateMachine/AimState.gd +++ b/game/player/StateMachine/AimState.gd @@ -24,10 +24,13 @@ var play_char : CharacterBody3D var auto_lock_blocked : bool = false #true apres un deverrouillage manuel, tant que la cible est encore au centre var dodging_from_aim : bool = false #true quand on quitte Aim pour rouler, pour ne pas relacher la cible verrouillee +var came_from_crouch : bool = false #true si Aim a ete declenche depuis CrouchState, pour y retourner en sortant func enter(play_char_ref : CharacterBody3D) -> void: play_char = play_char_ref auto_lock_blocked = false + #curr_state_name n'est pas encore mis a jour a ce stade : il reflete encore l'etat qu'on est en train de quitter + came_from_crouch = play_char.state_machine.curr_state_name == "Crouch" verifications() func verifications() -> void: @@ -62,7 +65,10 @@ func input_management() -> bool: return true if !Input.is_action_pressed(aim_action): - transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState") + if came_from_crouch: + transitioned.emit(self, "CrouchState") + else: + transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState") return true if Input.is_action_just_pressed(unlock_action): diff --git a/game/player/StateMachine/CrouchState.gd b/game/player/StateMachine/CrouchState.gd new file mode 100644 index 0000000..ed8cf73 --- /dev/null +++ b/game/player/StateMachine/CrouchState.gd @@ -0,0 +1,71 @@ +extends State + +class_name CrouchState + +var state_name : String = "Crouch" + +var play_char : CharacterBody3D + +func enter(play_char_ref : CharacterBody3D) -> void: + play_char = play_char_ref + + verifications() + +func verifications() -> void: + #play_char.godot_plush_skin.set_state("crouch") + play_char.move_speed = play_char.crouch_speed + play_char.move_accel = play_char.crouch_accel + play_char.move_deccel = play_char.crouch_deccel + + play_char.floor_snap_length = 1.0 + if play_char.jump_cooldown > 0.0: play_char.jump_cooldown = -1.0 + if play_char.nb_jumps_in_air_allowed < play_char.nb_jumps_in_air_allowed_ref: play_char.nb_jumps_in_air_allowed = play_char.nb_jumps_in_air_allowed_ref + if play_char.coyote_jump_cooldown < play_char.coyote_jump_cooldown_ref: play_char.coyote_jump_cooldown = play_char.coyote_jump_cooldown_ref + if play_char.has_cut_jump: play_char.has_cut_jump = false + + play_char.is_crouching = true + +func exit() -> void: + play_char.is_crouching = false + +func physics_update(delta : float) -> void: + applies() + + play_char.gravity_apply(delta) + + input_management() + + move(delta) + +func applies() -> void: + #quitter le sol (ex: crouch au bord d'une plateforme) bascule vers InairState, comme IdleState + if !play_char.is_on_floor() and !play_char.is_on_wall(): + transitioned.emit(self, "InairState") + #le saut est bloque en crouch : on ne consomme pas le jump buffer ici, il restera en attente + #et sera pris en compte des la sortie du crouch (Idle/Walk) + +func input_management() -> void: + #courir annule automatiquement le crouch + if play_char.walk_or_run == "RunState": + transitioned.emit(self, "RunState") + + #bascule (toggle) : un nouvel appui ressort du crouch vers l'etat au sol approprie + if Input.is_action_just_pressed(play_char.crouch_action): + transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState") + + if Input.is_action_just_pressed(play_char.aim_cam_action): + transitioned.emit(self, "AimState") + + #pas de saut ici : le jump_action est volontairement ignore pendant le crouch + +func move(delta : float) -> void: + play_char.move_dir = Input.get_vector(play_char.move_left_action, play_char.move_right_action, play_char.move_forward_action, play_char.move_backward_action).rotated(-play_char.cam_holder.global_rotation.y) + + if play_char.move_dir and play_char.is_on_floor(): + #deplacement accroupi, a vitesse reduite + play_char.velocity.x = lerp(play_char.velocity.x, play_char.move_dir.x * play_char.move_speed, play_char.move_accel * delta) + play_char.velocity.z = lerp(play_char.velocity.z, play_char.move_dir.y * play_char.move_speed, play_char.move_accel * delta) + else: + #pas de transition vers Idle ici : Crouch gere lui-meme l'immobilite, comme AimState + play_char.velocity.x = lerp(play_char.velocity.x, 0.0, play_char.move_deccel * delta) + play_char.velocity.z = lerp(play_char.velocity.z, 0.0, play_char.move_deccel * delta) diff --git a/game/player/StateMachine/CrouchState.gd.uid b/game/player/StateMachine/CrouchState.gd.uid new file mode 100644 index 0000000..f804a98 --- /dev/null +++ b/game/player/StateMachine/CrouchState.gd.uid @@ -0,0 +1 @@ +uid://d0577tj0c23bu diff --git a/game/player/StateMachine/IdleState.gd b/game/player/StateMachine/IdleState.gd index fcf94f5..34491dd 100644 --- a/game/player/StateMachine/IdleState.gd +++ b/game/player/StateMachine/IdleState.gd @@ -47,6 +47,9 @@ func input_management() -> void: if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0: transitioned.emit(self, "DodgeState") + if Input.is_action_just_pressed(play_char.crouch_action): + transitioned.emit(self, "CrouchState") + if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action): transitioned.emit(self, "JumpState") diff --git a/game/player/StateMachine/PlayerCharacter.gd b/game/player/StateMachine/PlayerCharacter.gd index c7e28cc..3e6c810 100644 --- a/game/player/StateMachine/PlayerCharacter.gd +++ b/game/player/StateMachine/PlayerCharacter.gd @@ -14,6 +14,7 @@ var last_frame_velocity : Vector3 var was_on_floor : bool = false var walk_or_run : String = "WalkState" #keep in memory if play char was walking or running before being in the air var is_dodging : bool = false #true while DodgeState is active ; hook this up to a hurtbox/i-frame check later +var is_crouching : bool = false #true while CrouchState is active ; hook this up to a collision-shape resize later @export_group("Walk variables") @export var walk_speed : float = 5.0 @@ -32,6 +33,11 @@ var is_dodging : bool = false #true while DodgeState is active ; hook this up to @export var dodge_cooldown : float = 0.6 var dodge_cooldown_ref : float +@export_group("Crouch variables") +@export var crouch_speed : float = 2.5 +@export var crouch_accel : float = 7.0 +@export var crouch_deccel : float = 7.0 + @export_group("Jump variables") @export var jump_height : float = 3.0 @export var jump_time_to_peak : float = 0.35 @@ -67,6 +73,7 @@ var move_right_action : StringName var run_action : StringName var jump_action : StringName var dodge_action : StringName +var crouch_action : StringName var aim_cam_action : StringName @export_group("Model variables") diff --git a/game/player/StateMachine/WalkState.gd b/game/player/StateMachine/WalkState.gd index 3cf1a9f..5dd8b02 100644 --- a/game/player/StateMachine/WalkState.gd +++ b/game/player/StateMachine/WalkState.gd @@ -49,6 +49,9 @@ func input_management() -> void: if Input.is_action_just_pressed(play_char.dodge_action) and play_char.dodge_cooldown <= 0.0: transitioned.emit(self, "DodgeState") + if Input.is_action_just_pressed(play_char.crouch_action): + transitioned.emit(self, "CrouchState") + if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action) : transitioned.emit(self, "JumpState")