86 lines
3.1 KiB
C#
86 lines
3.1 KiB
C#
// 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
|
||
{
|
||
/// <summary>
|
||
/// 游泳状态:玩家在液体中时使用。
|
||
/// 需要 AbilityType.Swim 已解锁;若未解锁则由 WaterDangerState 触发溺水流程。
|
||
/// 由 PlayerController 在收到 EVT_LiquidEntered 后切换进入。
|
||
/// </summary>
|
||
public class SwimState : PlayerStateBase
|
||
{
|
||
private LiquidPhysicsConfigSO _currentPhysics;
|
||
private float _originalGravity;
|
||
|
||
public SwimState(PlayerController owner) : base(owner) { }
|
||
|
||
/// <summary>由 PlayerController 在切换状态前调用,注入当前液体区域的物理配置。</summary>
|
||
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);
|
||
}
|
||
}
|
||
}
|