using System; using TH1_Core.Events; using TH1_Core.Managers; using TMPro; using UI.HintUI; using UnityEngine; // 确保引用了事件命名空间 namespace TH1_UI.HintUI { public class HintUI { // 视图引用 private readonly GameObject ROHintWindow; private readonly RectTransform _rectTransform; private TextMeshProUGUI _hintTextComponent; private readonly Canvas _rootCanvas; // 缓存委托以用于取消订阅 private readonly Action _onShowHintAction; private readonly Action _onHideHintAction; // ---【新增】--- private readonly Action _onTriggerDisabledAction; #region --- 新增: 状态管理 --- /// /// 记录当前显示提示的数据提供者。 /// 如果没有提示在显示,则为null。 /// 这是实现“精确关闭”逻辑的核心。 /// private HintDataProvider _currentActiveDataProvider; #endregion public HintUI(GameObject hintWindowRoot) { if (hintWindowRoot == null) { Debug.LogError("HintWindowUI的构造函数收到了一个空的GameObject引用!"); return; } this.ROHintWindow = hintWindowRoot; this._rectTransform = ROHintWindow.GetComponent(); this._rootCanvas = ROHintWindow.GetComponentInParent(); if (this._rootCanvas == null) { Debug.LogError("在HintWindow的父级中找不到Canvas组件!坐标转换将失败。", ROHintWindow); } // 缓存Action委托 _onShowHintAction = OnShowHint; _onHideHintAction = OnHideHint; // ---【新增】--- _onTriggerDisabledAction = OnTriggerDisabled; init(); } private void init() { Transform textTransform = ROHintWindow.transform.Find("Text"); if (textTransform != null) _hintTextComponent = textTransform.GetComponent(); if (_hintTextComponent == null) return; // 订阅所有事件 EventManager.Subscribe(_onShowHintAction); EventManager.Subscribe(_onHideHintAction); // ---【新增】--- EventManager.Subscribe(_onTriggerDisabledAction); ROHintWindow.SetActive(false); } public void Dispose() { // 取消所有订阅 EventManager.Unsubscribe(_onShowHintAction); EventManager.Unsubscribe(_onHideHintAction); // ---【新增】--- EventManager.Unsubscribe(_onTriggerDisabledAction); } #region --- 事件处理器 --- private void OnShowHint(ShowHintEvent e) { if (ROHintWindow == null || _hintTextComponent == null || _rectTransform == null || e.DataProvider == null) { HideAndResetState(); // 使用重构后的方法 return; } string textToShow = e.DataProvider.GetHintText(); if (string.IsNullOrEmpty(textToShow)) { HideAndResetState(); // 使用重构后的方法 return; } ROHintWindow.SetActive(true); _hintTextComponent.text = textToShow; ROHintWindow.GetComponent().RefreshSize(); RectTransformUtility.ScreenPointToLocalPointInRectangle( _rectTransform.parent as RectTransform, e.Position, _rootCanvas.worldCamera, out Vector2 localPoint ); ROHintWindow.GetComponent().Present(e.Position); //_rectTransform.localPosition = localPoint; _rectTransform.SetAsLastSibling(); // 在成功显示提示后,记录下它的来源 _currentActiveDataProvider = e.DataProvider; } private void OnHideHint(HideHintEvent e) { // 由OnPointerExit触发的通用隐藏请求 HideAndResetState(); } // ---【新增】--- /// /// 处理来自HintTrigger的禁用事件 /// private void OnTriggerDisabled(HintTriggerDisabledEvent e) { // 核心逻辑:检查被禁用的Trigger是否就是当前正在显示提示的那个 if (e.DataProvider != null && e.DataProvider == _currentActiveDataProvider) { // 如果是,则隐藏提示框并重置状态 Debug.Log($"Hint is hiding because its trigger ({e.DataProvider}) was disabled."); HideAndResetState(); } // 如果不是(例如,另一个不相关的UI元素被禁用了),则什么也不做 } #endregion #region --- 新增: 重构的辅助方法 --- /// /// 隐藏窗口并清空当前状态,确保系统干净。 /// private void HideAndResetState() { if (ROHintWindow != null) { ROHintWindow.SetActive(false); } // 无论是主动隐藏还是被动隐藏,都需要清空状态 _currentActiveDataProvider = null; } #endregion } }