// Assets/Scripts/Player/States/SwimState.cs // 游泳状态:玩家在液体中时使用(Architecture 21_LiquidPuzzleModule §5) // ⚠️ 遵循 PlayerStateBase 构造函数注入模式(非 MonoBehaviour) // ⚠️ 输入通过 Input.MoveInput / Input.JumpStartedEvent 访问(项目实际 API) using BaseGames.Player; using BaseGames.World.Liquid; using UnityEngine; namespace BaseGames.Player.States { /// /// 游泳状态:玩家在液体中时使用。 /// 需要 AbilityType.Swim 已解锁;若未解锁则由 WaterDangerState 触发溺水流程。 /// 由 PlayerController 在收到 EVT_LiquidEntered 后切换进入。 /// public class SwimState : PlayerStateBase { private LiquidPhysicsConfigSO _currentPhysics; private float _originalGravity; public SwimState(PlayerController owner) : base(owner) { } /// 由 PlayerController 在切换状态前调用,注入当前液体区域的物理配置。 public void SetPhysicsConfig(LiquidPhysicsConfigSO config) => _currentPhysics = config; public override void OnStateEnter() { _originalGravity = Move.Rb.gravityScale; Move.SetGravityScale(_currentPhysics?.GravityScale ?? 0.3f); if (AnimCfg?.SwimIdle != null) Anim?.Play(AnimCfg.SwimIdle); Input.JumpStartedEvent += OnJumpStarted; } public override void OnStateExit() { Input.JumpStartedEvent -= OnJumpStarted; Move.SetGravityScale(_originalGravity); } public override void OnStateUpdate() { var input = Input.MoveInput; var maxSpeed = _currentPhysics?.MaxSwimSpeed ?? 4f; var accel = _currentPhysics?.SwimAcceleration ?? 8f; var drag = _currentPhysics?.DragCoefficient ?? 3f; var rb = Move.Rb; if (input != Vector2.zero) { var targetVel = input * maxSpeed; rb.velocity = Vector2.MoveTowards(rb.velocity, targetVel, accel * Time.deltaTime); if (AnimCfg?.SwimMove != null) Anim?.Play(AnimCfg.SwimMove); } else { // 水下浮力(持续向上的微弱力) rb.AddForce(Vector2.up * (_currentPhysics?.BuoyancyForce ?? 0.5f), ForceMode2D.Force); if (AnimCfg?.SwimIdle != null) Anim?.Play(AnimCfg.SwimIdle); } // 施加水阻 rb.velocity *= 1f - drag * Time.deltaTime; } public override PlayerStateBase GetNextState() { // 离开液体区域由 PlayerController 订阅 EVT_LiquidExited 后切换到 FallState return null; } private void OnJumpStarted() { // 跳跃键 = 跃出水面冲量 Move.Rb.AddForce(Vector2.up * (_currentPhysics?.SurfaceExitSpeed ?? 5f), ForceMode2D.Impulse); } } }