2025-07-30 18:03:37 +08:00

120 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}