161 lines
5.5 KiB
C#
161 lines
5.5 KiB
C#
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<ShowHintEvent> _onShowHintAction;
|
||
private readonly Action<HideHintEvent> _onHideHintAction;
|
||
// ---【新增】---
|
||
private readonly Action<HintTriggerDisabledEvent> _onTriggerDisabledAction;
|
||
|
||
#region --- 新增: 状态管理 ---
|
||
/// <summary>
|
||
/// 记录当前显示提示的数据提供者。
|
||
/// 如果没有提示在显示,则为null。
|
||
/// 这是实现“精确关闭”逻辑的核心。
|
||
/// </summary>
|
||
private HintDataProvider _currentActiveDataProvider;
|
||
#endregion
|
||
|
||
public HintUI(GameObject hintWindowRoot)
|
||
{
|
||
if (hintWindowRoot == null)
|
||
{
|
||
Debug.LogError("HintWindowUI的构造函数收到了一个空的GameObject引用!");
|
||
return;
|
||
}
|
||
|
||
this.ROHintWindow = hintWindowRoot;
|
||
this._rectTransform = ROHintWindow.GetComponent<RectTransform>();
|
||
this._rootCanvas = ROHintWindow.GetComponentInParent<Canvas>();
|
||
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<TextMeshProUGUI>();
|
||
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<HintWindowController>().RefreshSize();
|
||
|
||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||
_rectTransform.parent as RectTransform,
|
||
e.Position,
|
||
_rootCanvas.worldCamera,
|
||
out Vector2 localPoint
|
||
);
|
||
ROHintWindow.GetComponent<HintWindowController>().Present(e.Position);
|
||
//_rectTransform.localPosition = localPoint;
|
||
_rectTransform.SetAsLastSibling();
|
||
|
||
|
||
// 在成功显示提示后,记录下它的来源
|
||
_currentActiveDataProvider = e.DataProvider;
|
||
}
|
||
|
||
private void OnHideHint(HideHintEvent e)
|
||
{
|
||
// 由OnPointerExit触发的通用隐藏请求
|
||
HideAndResetState();
|
||
}
|
||
|
||
// ---【新增】---
|
||
/// <summary>
|
||
/// 处理来自HintTrigger的禁用事件
|
||
/// </summary>
|
||
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 --- 新增: 重构的辅助方法 ---
|
||
|
||
/// <summary>
|
||
/// 隐藏窗口并清空当前状态,确保系统干净。
|
||
/// </summary>
|
||
private void HideAndResetState()
|
||
{
|
||
if (ROHintWindow != null)
|
||
{
|
||
ROHintWindow.SetActive(false);
|
||
}
|
||
// 无论是主动隐藏还是被动隐藏,都需要清空状态
|
||
_currentActiveDataProvider = null;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|