120 lines
4.3 KiB
C#
120 lines
4.3 KiB
C#
using UnityEngine;
|
||
using TMPro;
|
||
using Logic.Event;
|
||
using System;
|
||
|
||
namespace UI.HintUI
|
||
{
|
||
public class HintUI
|
||
{
|
||
// 视图引用
|
||
private readonly GameObject ROHintWindow;
|
||
private readonly RectTransform _rectTransform;
|
||
private TextMeshProUGUI _hintTextComponent;
|
||
|
||
// 【新增】缓存根Canvas的引用,用于坐标转换
|
||
private readonly Canvas _rootCanvas;
|
||
|
||
// 缓存委托以用于取消订阅
|
||
private readonly Action<ShowHintEvent> _onShowHintAction;
|
||
private readonly Action<HideHintEvent> _onHideHintAction;
|
||
|
||
public HintUI(GameObject hintWindowRoot)
|
||
{
|
||
if (hintWindowRoot == null)
|
||
{
|
||
Debug.LogError("HintWindowUI的构造函数收到了一个空的GameObject引用!");
|
||
return;
|
||
}
|
||
|
||
this.ROHintWindow = hintWindowRoot;
|
||
this._rectTransform = ROHintWindow.GetComponent<RectTransform>();
|
||
|
||
// 【新增】获取UI所在的根Canvas
|
||
// 这是坐标转换所必需的上下文环境
|
||
this._rootCanvas = ROHintWindow.GetComponentInParent<Canvas>();
|
||
if (this._rootCanvas == null)
|
||
{
|
||
Debug.LogError("在HintWindow的父级中找不到Canvas组件!坐标转换将失败。", ROHintWindow);
|
||
}
|
||
|
||
// 缓存Action委托
|
||
_onShowHintAction = OnShowHint;
|
||
_onHideHintAction = OnHideHint;
|
||
|
||
init();
|
||
}
|
||
|
||
private void init()
|
||
{
|
||
Transform textTransform = ROHintWindow.transform.Find("Text");
|
||
if (textTransform != null)
|
||
{
|
||
_hintTextComponent = textTransform.GetComponent<TextMeshProUGUI>();
|
||
}
|
||
if (_hintTextComponent == null)
|
||
{
|
||
Debug.LogError("在ROHintWindow下未能找到路径 'Text' 或其上的TextMeshProUGUI组件!", ROHintWindow);
|
||
return;
|
||
}
|
||
|
||
EventManager.Subscribe(_onShowHintAction);
|
||
EventManager.Subscribe(_onHideHintAction);
|
||
ROHintWindow.SetActive(false);
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
EventManager.Unsubscribe(_onShowHintAction);
|
||
EventManager.Unsubscribe(_onHideHintAction);
|
||
}
|
||
|
||
// --- 事件处理方法 (核心修改点) ---
|
||
private void OnShowHint(ShowHintEvent e)
|
||
{
|
||
// 基础的有效性检查
|
||
if (ROHintWindow == null || _hintTextComponent == null || _rectTransform == null || e.DataProvider == null)
|
||
{
|
||
ROHintWindow.SetActive(false);
|
||
return;
|
||
}
|
||
|
||
string textToShow = e.DataProvider.GetHintText();
|
||
if (string.IsNullOrEmpty(textToShow))
|
||
{
|
||
ROHintWindow.SetActive(false);
|
||
return;
|
||
}
|
||
|
||
// --- 【核心修改逻辑】从这里开始 ---
|
||
ROHintWindow.SetActive(true);
|
||
_hintTextComponent.text = textToShow;
|
||
|
||
// 1. 调用坐标转换工具
|
||
// 参数1: 我们要把坐标转换到哪个RectTransform内部,这里是Hint窗口的父级。
|
||
// 参数2: 屏幕坐标点,从事件中传来 (它已经包含了您在HintTrigger里设置的offset)。
|
||
// 参数3: 当前Canvas使用的渲染相机。对于ScreenSpace-Overlay模式,这个为null,函数能正确处理。
|
||
// 参数4: 输出转换后的局部坐标。
|
||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||
_rectTransform.parent as RectTransform,
|
||
e.Position,
|
||
_rootCanvas.worldCamera,
|
||
out Vector2 localPoint
|
||
);
|
||
|
||
// 2. 将计算出的局部坐标赋值给localPosition
|
||
_rectTransform.localPosition = localPoint;
|
||
|
||
// --- 核心修改逻辑结束 ---
|
||
|
||
_rectTransform.SetAsLastSibling();
|
||
}
|
||
|
||
private void OnHideHint(HideHintEvent e)
|
||
{
|
||
if (ROHintWindow == null) return;
|
||
ROHintWindow.SetActive(false);
|
||
}
|
||
}
|
||
}
|