Files
zeling_v2/Assets/_Game/Scripts/UI/HUD/HUDController.cs
2026-05-25 11:54:37 +08:00

125 lines
4.9 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.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using BaseGames.Core.Events;
namespace BaseGames.UI.HUD
{
/// <summary>
/// 游戏内 HUD 控制器(架构 10_UIModule §2
/// 订阅事件频道更新 HP 格子、魂魂力/灵力/灵珠/弹簧充能和形态图标。
/// HP/弹簧格子采用 SetActive 复用,避免运行期频繁 Instantiate/Destroy。
/// </summary>
public class HUDController : MonoBehaviour
{
[Header("HP")]
[SerializeField] private Transform _hpContainer;
[SerializeField] private GameObject _hpCellPrefab;
[Header("Gauges")]
[SerializeField] private Image _soulGaugeFill;
[SerializeField] private Image _spiritGaugeFill;
[SerializeField] private TMP_Text _lingZhuText;
[Header("Spring Charges")]
[SerializeField] private Transform _springContainer;
[SerializeField] private GameObject _springIconPrefab;
[Header("Form")]
[SerializeField] private Image[] _formIcons;
[Header("Interact Prompt")]
[Tooltip("独立 Widget 组件负责渲染图标+文本HUDController 仅保留引用供编辑器配置检查")]
[SerializeField] private InteractPromptWidget _interactPromptWidget;
[Header("Event Channels - Subscribe")]
[SerializeField] private IntEventChannelSO _onHPChanged;
[SerializeField] private IntEventChannelSO _onMaxHPChanged;
[SerializeField] private IntEventChannelSO _onSoulPowerChanged;
[SerializeField] private IntEventChannelSO _onSpiritPowerChanged;
[SerializeField] private IntEventChannelSO _onLingZhuChanged;
[SerializeField] private IntEventChannelSO _onSpringChargesChanged;
[SerializeField] private IntEventChannelSO _onFormChanged;
private readonly List<GameObject> _hpCells = new();
private readonly List<GameObject> _springIcons = new();
private readonly CompositeDisposable _subs = new();
private int _lastLingZhu = int.MinValue;
private void OnEnable()
{
_onHPChanged?.Subscribe(UpdateHP).AddTo(_subs);
_onMaxHPChanged?.Subscribe(RebuildHPCells).AddTo(_subs);
_onSoulPowerChanged?.Subscribe(UpdateSoul).AddTo(_subs);
_onSpiritPowerChanged?.Subscribe(UpdateSpirit).AddTo(_subs);
_onLingZhuChanged?.Subscribe(UpdateLingZhu).AddTo(_subs);
_onSpringChargesChanged?.Subscribe(RebuildSpringIcons).AddTo(_subs);
_onFormChanged?.Subscribe(UpdateFormIcon).AddTo(_subs);
// 交互提示由独立的 InteractPromptWidget 组件处理HUDController 不再直接订阅
}
private void OnDisable() => _subs.Clear();
private void UpdateHP(int current)
{
for (int i = 0; i < _hpCells.Count; i++)
if (_hpCells[i] != null) _hpCells[i].SetActive(i < current);
}
private void RebuildHPCells(int max)
{
if (_hpContainer == null || _hpCellPrefab == null) return;
// 复用现有 Cell仅在数量不足时 Instantiate 补充,超出时 SetActive(false) 而非 Destroy
for (int i = 0; i < max; i++)
{
if (i < _hpCells.Count)
_hpCells[i].SetActive(true);
else
_hpCells.Add(Instantiate(_hpCellPrefab, _hpContainer));
}
for (int i = max; i < _hpCells.Count; i++)
if (_hpCells[i] != null) _hpCells[i].SetActive(false);
}
private void UpdateSoul(int val)
{
if (_soulGaugeFill != null) _soulGaugeFill.fillAmount = val / 100f;
}
private void UpdateSpirit(int val)
{
if (_spiritGaugeFill != null) _spiritGaugeFill.fillAmount = val / 100f;
}
private void UpdateLingZhu(int val)
{
if (_lingZhuText == null || val == _lastLingZhu) return;
_lastLingZhu = val;
_lingZhuText.text = val.ToString();
}
private void RebuildSpringIcons(int charges)
{
if (_springContainer == null || _springIconPrefab == null) return;
// 复用已有图标,超出数量时 SetActive(false)
for (int i = 0; i < charges; i++)
{
if (i < _springIcons.Count)
_springIcons[i].SetActive(true);
else
_springIcons.Add(Instantiate(_springIconPrefab, _springContainer));
}
for (int i = charges; i < _springIcons.Count; i++)
if (_springIcons[i] != null) _springIcons[i].SetActive(false);
}
private void UpdateFormIcon(int formIndex)
{
if (_formIcons == null) return;
for (int i = 0; i < _formIcons.Length; i++)
if (_formIcons[i] != null) _formIcons[i].enabled = (i == formIndex);
}
}
}