126 lines
5.2 KiB
Plaintext
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). |