Files
zeling_v2/Assets/Scripts/Player/States/SwimState.cs
2026-05-12 15:34:08 +08:00

86 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
}
}
}