Refactor interaction prompt system to use world space prompts

- Removed the InteractPromptWidget from HUD and its references in HUDController.
- Introduced IInteractPromptView interface for world space interaction prompts.
- Implemented WorldInteractPrompt class to manage display of interaction prompts in world space.
- Updated InteractableDetector to handle showing/hiding of world space prompts based on player proximity to interactable objects.
- Created a new prefab for UI_WorldInteractPrompt to facilitate the new interaction prompt system.
This commit is contained in:
2026-06-10 14:14:08 +08:00
parent 32566020c7
commit a1f54b68e6
23 changed files with 6085 additions and 554 deletions

View File

@@ -1,7 +1,8 @@
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using BaseGames.Core;
using BaseGames.UI;
namespace BaseGames.Dialogue
{
@@ -26,10 +27,9 @@ namespace BaseGames.Dialogue
[SerializeField] private TMP_Text _label;
[Header("按键图标")]
[Tooltip("键盘/鼠标设备激活时使用的按键图标 Sprite。")]
[SerializeField] private Sprite _keyboardIcon;
[Tooltip("手柄设备激活时使用的按键图标 Sprite。")]
[SerializeField] private Sprite _gamepadIcon;
[Tooltip("用于查询按键图标的输入动作名(与 InputReader 的 Action 对应)。\n" +
"图标走 IInputIconService随设备切换 / 改键自动刷新。")]
[SerializeField] private string _actionName = "Interact";
[Header("位置与动画")]
[Tooltip("相对于本组件 transform 的世界空间偏移。调整此值可控制气泡与 NPC 的相对位置。")]
@@ -42,10 +42,11 @@ namespace BaseGames.Dialogue
[SerializeField] [Min(0f)] private float _fadeOutDuration = 0.08f;
// ── 运行时状态 ────────────────────────────────────────────────────────
private InteractableNPC _npc;
private bool _visible;
private float _alpha;
private Camera _cam;
private InteractableNPC _npc;
private bool _visible;
private float _alpha;
private Camera _cam;
private IInputIconService _iconService;
// ── Lifecycle ─────────────────────────────────────────────────────────
@@ -69,6 +70,11 @@ namespace BaseGames.Dialogue
_npc.PlayerEnteredRange -= OnPlayerEntered;
_npc.PlayerExitedRange -= OnPlayerExited;
}
if (_iconService != null)
{
_iconService.OnIconSetChanged -= UpdateIcon;
_iconService = null;
}
}
private void Update()
@@ -151,9 +157,19 @@ namespace BaseGames.Dialogue
private void UpdateIcon()
{
if (_icon == null) return;
bool isGamepad = Gamepad.current != null && Gamepad.current.enabled;
_icon.sprite = isGamepad ? _gamepadIcon : _keyboardIcon;
if (_icon == null || string.IsNullOrEmpty(_actionName)) return;
// 延迟绑定:首次需要时获取服务(确保 ServiceLocator 已初始化),并订阅设备/改键刷新
if (_iconService == null)
{
_iconService = ServiceLocator.GetOrDefault<IInputIconService>();
if (_iconService != null)
_iconService.OnIconSetChanged += UpdateIcon;
}
var sprite = _iconService?.GetActionIcon(_actionName);
if (sprite != null) { _icon.sprite = sprite; _icon.enabled = true; }
else { _icon.enabled = false; }
}
private void ApplyAlpha(float a)