Add InputDeviceIconSetSO configuration guide and related documentation
- Created a new markdown file detailing the configuration of InputDeviceIconSetSO. - Included sections on system architecture, field explanations, image specifications, and complete workflow from setup to runtime. - Documented the automatic device recognition logic and provided troubleshooting for common issues. - Added references to relevant files and scripts for easier navigation.
This commit is contained in:
@@ -25,8 +25,8 @@ namespace BaseGames.UI.HUD
|
||||
[SerializeField] private Image[] _formIcons;
|
||||
|
||||
[Header("Interact Prompt")]
|
||||
[SerializeField] private TMP_Text _interactText;
|
||||
[SerializeField] private GameObject _interactPromptRoot;
|
||||
[Tooltip("独立 Widget 组件负责渲染图标+文本,HUDController 仅保留引用供编辑器配置检查")]
|
||||
[SerializeField] private InteractPromptWidget _interactPromptWidget;
|
||||
|
||||
[Header("Event Channels - Subscribe")]
|
||||
[SerializeField] private IntEventChannelSO _onHPChanged;
|
||||
@@ -36,8 +36,6 @@ namespace BaseGames.UI.HUD
|
||||
[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();
|
||||
@@ -53,8 +51,7 @@ namespace BaseGames.UI.HUD
|
||||
_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);
|
||||
// 交互提示由独立的 InteractPromptWidget 组件处理,HUDController 不再直接订阅
|
||||
}
|
||||
|
||||
private void OnDisable() => _subs.Clear();
|
||||
@@ -118,16 +115,5 @@ namespace BaseGames.UI.HUD
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
119
Assets/_Game/Scripts/UI/HUD/InteractPromptWidget.cs
Normal file
119
Assets/_Game/Scripts/UI/HUD/InteractPromptWidget.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BaseGames.Core;
|
||||
using BaseGames.Core.Events;
|
||||
|
||||
namespace BaseGames.UI.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// 交互提示 Widget。
|
||||
///
|
||||
/// 职责:
|
||||
/// • 订阅 InteractPromptEventChannelSO 显示/隐藏提示
|
||||
/// • 显示按键图标(Image)+ 动作文本(TMP_Text)
|
||||
/// • 监听 IInputIconService.OnIconSetChanged,在设备切换或改键后自动刷新图标
|
||||
///
|
||||
/// 布置方式:放在 HUD Canvas 下,引用对应的事件频道 SO 资产。
|
||||
/// 不依赖 HUDController,可独立使用。
|
||||
/// </summary>
|
||||
public sealed class InteractPromptWidget : MonoBehaviour
|
||||
{
|
||||
[Header("UI 引用")]
|
||||
[SerializeField] private Image _keyIcon;
|
||||
[SerializeField] private TMP_Text _labelText;
|
||||
[Tooltip("整个提示根节点,控制显示/隐藏")]
|
||||
[SerializeField] private GameObject _root;
|
||||
|
||||
[Header("Event Channels")]
|
||||
[SerializeField] private InteractPromptEventChannelSO _onShowPrompt;
|
||||
[SerializeField] private VoidEventChannelSO _onHidePrompt;
|
||||
|
||||
// ── 运行时状态 ────────────────────────────────────────────────────────
|
||||
private IInputIconService _iconService;
|
||||
private string _currentActionName;
|
||||
private readonly CompositeDisposable _subs = new();
|
||||
|
||||
// ── Lifecycle ─────────────────────────────────────────────────────────
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// ServiceLocator 可能在此组件 OnEnable 时尚未注册(执行顺序问题),
|
||||
// 延迟到 ShowPrompt 首次调用时再获取,确保服务可用
|
||||
_onShowPrompt?.Subscribe(ShowPrompt).AddTo(_subs);
|
||||
_onHidePrompt?.Subscribe(HidePrompt).AddTo(_subs);
|
||||
|
||||
HidePrompt();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_subs.Clear();
|
||||
UnsubscribeFromIconService();
|
||||
}
|
||||
|
||||
// ── Handlers ──────────────────────────────────────────────────────────
|
||||
|
||||
private void ShowPrompt(InteractPromptEvent evt)
|
||||
{
|
||||
_currentActionName = evt.ActionName;
|
||||
|
||||
// 延迟绑定:首次显示时获取服务(确保 ServiceLocator 已初始化)
|
||||
if (_iconService == null)
|
||||
{
|
||||
_iconService = ServiceLocator.GetOrDefault<IInputIconService>();
|
||||
if (_iconService != null)
|
||||
_iconService.OnIconSetChanged += RefreshIcon;
|
||||
}
|
||||
|
||||
if (_labelText != null)
|
||||
_labelText.text = evt.LabelText;
|
||||
|
||||
RefreshIcon();
|
||||
|
||||
if (_root != null)
|
||||
_root.SetActive(true);
|
||||
else
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void HidePrompt()
|
||||
{
|
||||
_currentActionName = null;
|
||||
|
||||
if (_root != null)
|
||||
_root.SetActive(false);
|
||||
else
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// ── Icon Refresh ──────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>设备切换或改键后刷新图标。由 IInputIconService.OnIconSetChanged 调用。</summary>
|
||||
private void RefreshIcon()
|
||||
{
|
||||
if (_keyIcon == null || string.IsNullOrEmpty(_currentActionName)) return;
|
||||
|
||||
var sprite = _iconService?.GetActionIcon(_currentActionName);
|
||||
if (sprite != null)
|
||||
{
|
||||
_keyIcon.sprite = sprite;
|
||||
_keyIcon.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 找不到图标时隐藏图标格,避免显示错误占位图
|
||||
_keyIcon.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UnsubscribeFromIconService()
|
||||
{
|
||||
if (_iconService != null)
|
||||
{
|
||||
_iconService.OnIconSetChanged -= RefreshIcon;
|
||||
_iconService = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/UI/HUD/InteractPromptWidget.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/HUD/InteractPromptWidget.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85bdb69d66e546f49b6c89941beda368
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user