Files
zeling_v2/Assets/Scripts/World/Liquid/WaterDangerState.cs
Joywayer 1135139bc6 v11 全量评审:修复 TD-13 至 TD-17
- TD-13: IQuestManager.CompleteQuest 改用 IRewardTarget,移除 using BaseGames.Player
- TD-14: HurtFlashController 缓存 WaitForSeconds(_waitForFlash 字段)
- TD-16: LiquidType 枚举迁移至 BaseGames.Core.Events;LiquidEvent.LiquidType 改为枚举直接比较
- TD-17: DeathScreenController 移除失效的 _onPlayerDied 订阅,改为 OnEnable 直接启动延迟显示

影响文件: IQuestManager.cs / HurtFlashController.cs / LiquidType.cs(迁移) /
  LiquidEvent.cs / LiquidZone.cs / WaterDangerState.cs /
  UnderwaterPostProcessingController.cs / UnderwaterAudioController.cs /
  DeathScreenController.cs

评审文档: Docs/Review/FrameworkReview_2026_May_v11.md(综合评分 9.30/10)
2026-05-12 16:34:03 +08:00

70 lines
2.4 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/World/Liquid/WaterDangerState.cs
using BaseGames.Core.Events;
using BaseGames.Player;
using UnityEngine;
namespace BaseGames.World.Liquid
{
/// <summary>
/// 当玩家进入 Water 类型液体且未解锁游泳能力时,触发溺水倒计时。
/// 订阅 EVT_LiquidEntered / EVT_LiquidExited 事件频道。
/// </summary>
public class WaterDangerState : MonoBehaviour
{
[SerializeField] private LiquidPhysicsConfigSO _config;
[SerializeField] private PlayerStats _playerStats; // 检查 Swim 能力
[SerializeField] private LiquidEventChannelSO _onLiquidEntered; // EVT_LiquidEntered
[SerializeField] private LiquidEventChannelSO _onLiquidExited; // EVT_LiquidExited
[SerializeField] private FloatEventChannelSO _onDrownProgress; // 0~1 倒计时进度HUD 用)
[SerializeField] private VoidEventChannelSO _onPlayerDrowned; // 触发死亡
private float _drownTimer;
private bool _isActive;
private readonly CompositeDisposable _subs = new();
private void Awake()
{
Debug.Assert(_config != null, "[WaterDangerState] _config 未赋值,请在 Inspector 中指定 LiquidPhysicsConfigSO。", this);
}
private void OnEnable()
{
_onLiquidEntered?.Subscribe(OnEnterLiquid).AddTo(_subs);
_onLiquidExited?.Subscribe(OnExitLiquid).AddTo(_subs);
}
private void OnDisable() => _subs.Clear();
public void OnEnterLiquid(LiquidEvent evt)
{
if (evt.LiquidType != LiquidType.Water) return;
if (_playerStats != null && _playerStats.HasAbility(AbilityType.Swim)) return;
_isActive = true;
_drownTimer = _config.DrownTime;
}
public void OnExitLiquid(LiquidEvent evt)
{
_isActive = false;
_drownTimer = _config.DrownTime;
_onDrownProgress?.Raise(0f);
}
private void Update()
{
if (!_isActive) return;
_drownTimer -= Time.deltaTime;
float drownTime = _config.DrownTime;
_onDrownProgress?.Raise(1f - (_drownTimer / drownTime));
if (_drownTimer <= 0f)
{
_isActive = false;
_onPlayerDrowned?.Raise();
}
}
}
}