Files
zeling_v2/Assets/_Game/Scripts/UI/HUD/HUDController.cs
Joywayer b7baf7ad6a Add WeaponFeedback component and AddressableManagerWindow meta file
- Implemented WeaponFeedback class for handling weapon-related feedbacks such as hit effects and attack sounds.
- Added meta file for AddressableManagerWindow to manage addressable assets.
- Included a new jump.data file for profiler data.
2026-05-22 22:03:32 +08:00

134 lines
5.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.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using BaseGames.Core.Events;
namespace BaseGames.UI.HUD
{
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")]
[SerializeField] private TMP_Text _interactText;
[SerializeField] private GameObject _interactPromptRoot;
[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;
[SerializeField] private StringEventChannelSO _onShowInteractPrompt;
[SerializeField] private VoidEventChannelSO _onHideInteractPrompt;
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);
_onShowInteractPrompt?.Subscribe(ShowInteractPrompt).AddTo(_subs);
_onHideInteractPrompt?.Subscribe(HideInteractPrompt).AddTo(_subs);
}
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);
}
private void ShowInteractPrompt(string text)
{
if (_interactText != null) _interactText.text = text;
if (_interactPromptRoot != null) _interactPromptRoot.SetActive(true);
}
private void HideInteractPrompt()
{
if (_interactPromptRoot != null) _interactPromptRoot.SetActive(false);
}
}
}