Files
BABA_YAGA/Assets/Scove/Player_Movement_Description.txt
2026-03-26 20:40:28 +07:00

126 lines
5.2 KiB
Plaintext

# PROJECT CONTEXT & ARCHITECTURE
- Engine: Unity 6.3
- Genre: 3D Third-Person Action Game (TPS)
- Input: Unity New Input System (using InputReader script)
- Pattern: Hierarchical State Machine (HSM) / State Pattern
- Coding Rules: Strictly English for all variables, methods, classes, and comments. Use CharacterController for movement. Handle rotation using Quaternion.Slerp.
# 1. INPUT READER (InputReader.cs)
Inherits: MonoBehaviour
Properties:
- Vector2 MoveInput (from WASD/Left Stick)
- bool IsSprintHeld (from Left Shift - continuous hold)
Events (Actions):
- event Action OnJumpEvent (Space bar pressed)
- event Action OnDodgeEvent (Right Mouse Button - RMB pressed)
- event Action OnCrouchEvent (C key pressed)
# 2. ANIMATOR SETUP REQUIREMENTS
Parameters:
- "Speed" (Float): Grounded movement (0.0 = Idle, 0.5 = Walk, 1.0 = Run).
- "IsCrouching" (Bool): Toggle crouch mode.
- "CrouchSpeed" (Float): Crouch movement (0.0 = Idle, 0.5 = Sneak, 1.0 = Walk).
- Triggers: "Dash", "Jump", "Fall", "AirDash", "Thrust", "Dodge".
# 3. STATE MACHINE CORE (PlayerStateMachine.cs)
Inherits: MonoBehaviour
RequireComponents: CharacterController, InputReader, Animator
Variables:
- float WalkSpeed = 3f, RunSpeed = 6f, DashForce = 10f, SneakSpeed = 1.5f
- float JumpForce = 5f, Gravity = -9.81f, ThrustDownwardForce = -20f
- float VelocityY (tracks vertical speed)
- PlayerBaseState currentState
Methods:
- SwitchState(PlayerBaseState newState): calls currentState.Exit(), updates state, calls currentState.Enter().
- Update(): calls currentState.Tick(Time.deltaTime).
- FixedUpdate(): calls currentState.PhysicsTick(Time.fixedDeltaTime).
# 4. BASE STATE (PlayerBaseState.cs)
Abstract class. Constructor takes (PlayerStateMachine stateMachine).
Abstract Methods: Enter(), Tick(float deltaTime), PhysicsTick(float fixedDeltaTime), Exit().
# 5. DETAILED STATE LOGICS
## PlayerIdleState
- Enter: Subscribe to OnJumpEvent, OnDodgeEvent, OnCrouchEvent.
- Tick: SmoothDamp "Speed" to 0.0. If MoveInput != Vector2.zero -> SwitchState(PlayerMoveState).
- Exit: Unsubscribe events.
## PlayerMoveState
- Enter: Subscribe to events (Jump, Dodge, Crouch).
- Tick:
- If MoveInput == Vector2.zero -> SwitchState(PlayerIdleState).
- If IsSprintHeld == true -> SwitchState(PlayerDashState).
- Move using CharacterController (MoveInput * WalkSpeed).
- Slerp rotation towards MoveInput direction.
- SmoothDamp "Speed" to 0.5.
- Exit: Unsubscribe events.
## PlayerDashState
- Variables: timer = 0.25s, dashDirection (Vector3).
- Enter: Set dashDirection to MoveInput (or transform.forward if 0). Snap rotation to dashDirection. SetTrigger("Dash").
- Tick:
- Move at DashForce along dashDirection (no gravity applied).
- timer -= deltaTime.
- If timer <= 0:
- If IsSprintHeld AND MoveInput != 0 -> SwitchState(PlayerRunState).
- If MoveInput != 0 -> SwitchState(PlayerMoveState).
- Else -> SwitchState(PlayerIdleState).
## PlayerRunState
- Enter: Subscribe to events (Jump, Dodge, Crouch).
- Tick:
- If MoveInput == 0 -> SwitchState(PlayerIdleState).
- If IsSprintHeld == false -> SwitchState(PlayerMoveState).
- Move using CharacterController (MoveInput * RunSpeed). Slerp rotation.
- SmoothDamp "Speed" to 1.0.
- Exit: Unsubscribe events.
## PlayerJumpState
- Enter: SetTrigger("Jump"). VelocityY = JumpForce.
- Tick:
- Apply Gravity (VelocityY += Gravity * deltaTime).
- Apply horizontal Air Control (MoveInput * WalkSpeed).
- Move using CharacterController (Horizontal + Vertical).
- If VelocityY <= 0 -> SwitchState(PlayerFallState).
## PlayerFallState
- Enter: SetTrigger("Fall"). Subscribe to OnDodgeEvent (maps to Thrust here).
- Tick:
- Apply Gravity. Apply horizontal Air Control. Move via Controller.
- If IsSprintHeld -> SwitchState(PlayerAirDashState).
- If isGrounded -> Set VelocityY = -2f. SwitchState(Idle or Move based on input).
- Thrust Event Trigger: SwitchState(PlayerThrustState).
- Exit: Unsubscribe OnDodgeEvent.
## PlayerAirDashState
- Variables: timer = 0.2s, dashDir.
- Enter: SetTrigger("AirDash"). VelocityY = 0f. Set dashDir based on MoveInput.
- Tick:
- Move horizontally at DashForce (VelocityY stays 0).
- timer -= deltaTime. If timer <= 0 -> SwitchState(PlayerFallState).
## PlayerThrustState
- Enter: SetTrigger("Thrust"). VelocityY = ThrustDownwardForce.
- Tick:
- VelocityY += (Gravity * 2) * deltaTime. Move purely downwards (no horizontal).
- If isGrounded -> Set VelocityY = -2f. SwitchState(PlayerIdleState).
## PlayerCrouchState
- Enter: SetBool("IsCrouching", true). Subscribe to OnCrouchEvent (Toggle), OnDodgeEvent.
- Tick:
- If MoveInput == 0: "CrouchSpeed" = 0.0.
- If MoveInput != 0 AND IsSprintHeld: Move at SneakSpeed. "CrouchSpeed" = 0.5.
- If MoveInput != 0 AND !IsSprintHeld: Move at WalkSpeed. "CrouchSpeed" = 1.0.
- Apply Movement and Slerp rotation.
- Toggle Event Trigger (C key): SwitchState(Idle or Move).
- Dodge Event Trigger (LMB): SwitchState(PlayerDodgeState).
- Exit: SetBool("IsCrouching", false). Unsubscribe events.
## PlayerDodgeState
- Variables: timer = 0.4s, dodgeDir.
- Enter: SetTrigger("Dodge"). Set dodgeDir based on MoveInput (Left/Right/Back/Forward). Snap rotation.
- Tick:
- Move at (DashForce * 0.8) along dodgeDir.
- timer -= deltaTime.
- If timer <= 0 -> SwitchState(Idle or Move based on MoveInput).