using UnityEngine; namespace OnlyScove.Scripts { public class PlayerCrouchState : PlayerBaseState { private readonly int isCrouchingHash = Animator.StringToHash("IsCrouching"); private readonly int crouchSpeedHash = Animator.StringToHash("CrouchSpeed"); private const float AnimatorDampTime = 0.1f; public PlayerCrouchState(PlayerStateMachine stateMachine) : base(stateMachine) {} public override void Enter() { stateMachine.Anim.SetBool(isCrouchingHash, true); stateMachine.Input.OnCrouchEvent += OnCrouchToggle; stateMachine.Input.OnDodgeEvent += OnDodge; } public override void Tick(float deltaTime) { Vector2 moveInput = stateMachine.Input.MoveInput; float currentSpeed = 0f; float animValue = 0f; if (moveInput == Vector2.zero) { animValue = 0f; } else { if (stateMachine.Input.IsSprintHeld) { currentSpeed = stateMachine.SneakSpeed; animValue = 0.5f; } else { currentSpeed = stateMachine.WalkSpeed; animValue = 1.0f; } Vector3 moveDirection = new Vector3(moveInput.x, 0f, moveInput.y).normalized; if (stateMachine.Cam != null) { moveDirection = stateMachine.Cam.PlanarRotation * moveDirection; } // Apply horizontal movement Vector3 movement = moveDirection * currentSpeed; // Apply gravity if (stateMachine.Controller.isGrounded) { stateMachine.VelocityY = -2f; } else { stateMachine.VelocityY += stateMachine.Gravity * deltaTime; } movement.y = stateMachine.VelocityY; stateMachine.Controller.Move(movement * deltaTime); Quaternion targetRotation = Quaternion.LookRotation(moveDirection); stateMachine.transform.rotation = Quaternion.Slerp( stateMachine.transform.rotation, targetRotation, deltaTime * 10f ); } stateMachine.Anim.SetFloat(crouchSpeedHash, animValue, AnimatorDampTime, deltaTime); } public override void PhysicsTick(float fixedDeltaTime) {} public override void Exit() { stateMachine.Anim.SetBool(isCrouchingHash, false); stateMachine.Input.OnCrouchEvent -= OnCrouchToggle; stateMachine.Input.OnDodgeEvent -= OnDodge; } private void OnCrouchToggle() { if (stateMachine.Input.MoveInput == Vector2.zero) stateMachine.SwitchState(new PlayerIdleState(stateMachine)); else stateMachine.SwitchState(new PlayerMoveState(stateMachine)); } private void OnDodge() => stateMachine.SwitchState(new PlayerDodgeState(stateMachine)); } }