【Unity】创建动态的Tooltip

需求说明

  • 文字内容动态变化;
  • 根据文字的内容自适应宽高;
  • 跟随鼠标移动;
  • 可以隐藏和展示;
  • 鼠标到达窗口边缘,tooltip停靠边缘可见;

成果展示

Scene部分

查看UI相机和Canvas的设置

注意将文字放在最左下角


脚本部分

TooltipScreenSpaceUI脚本绑定至TooltipScreenSpaceUI物体

public class TooltipScreenSpaceUI : MonoBehaviour
{
    [SerializeField] RectTransform canvasRectTransform;
    [SerializeField] Camera uiCamera;

    [SerializeField] Transform player;
    private RectTransform backgroundRectTransform;
    private TextMeshProUGUI textMeshPro;
    private RectTransform rectTransform;

    public static TooltipScreenSpaceUI Instance { get; private set; }
    private Func<string> getTooltipTextFunc;

    private string tooltipText
    {
        get
        {
            return (getTooltipTextFunc != null) ? getTooltipTextFunc() : _tooltipText;
        }
        set
        {
            _tooltipText = value;
        }
    }
    private string _tooltipText;

    private void Awake()
    {
        Instance = this;
        backgroundRectTransform = transform.Find("background").GetComponent<RectTransform>();
        textMeshPro = transform.Find("text").GetComponent<TextMeshProUGUI>();
        rectTransform = transform.GetComponent<RectTransform>();

        HideTooltip();
    }

    private void SetText(string tooltipText)
    {
        textMeshPro.SetText(tooltipText);
        textMeshPro.ForceMeshUpdate();

        Vector2 textSize = textMeshPro.GetRenderedValues(false);
        Vector2 paddingSize = new Vector2(8, 8);

        backgroundRectTransform.sizeDelta = textSize + paddingSize;//让背景适应文字的宽高
    }

    

    private void Update()
    {
        SetText($"MosPos:({Input.mousePosition.x},{Input.mousePosition.y})\n{tooltipText}");

        //tooltip跟随鼠标移动
        //鼠标移动至边缘,tooltip停靠
        var mousePosition = uiCamera.ScreenPointToRay(Input.mousePosition).origin;
        Vector2 anchoredPosition = mousePosition / canvasRectTransform.localScale.x;
        if (anchoredPosition.x + backgroundRectTransform.rect.width > 630f + backgroundRectTransform.rect.width)
        {
            anchoredPosition.x = 630f - backgroundRectTransform.rect.width;
        }
        if (anchoredPosition.y + backgroundRectTransform.rect.height > 350f + backgroundRectTransform.rect.height)
        {
            anchoredPosition.y = 350f - backgroundRectTransform.rect.height;
        }
        if (anchoredPosition.x < -630f)
        {
            anchoredPosition.x = -630f;
        }
        if (anchoredPosition.y < -350f)
        {
            anchoredPosition.y = -350f;
        }
        rectTransform.anchoredPosition = anchoredPosition;
    }



    private void ShowTooltip(string tooltipText)
    {
        this._tooltipText = tooltipText;
        gameObject.SetActive(true);
        SetText(tooltipText);
    }

    private void ShowTooltip(Func<string> getTooltipTextFunc)
    {
        this.getTooltipTextFunc = getTooltipTextFunc;
        gameObject.SetActive(true);
        SetText(tooltipText);
    }
    private void HideTooltip()
    {
        gameObject.SetActive(false);
    }

    public static void ShowTooltip_Static(string tooltipText)
    {

        Instance.ShowTooltip(tooltipText);
    }

    public static void ShowTooltip_Static(Func<string> getTooltipTextFunc)
    {
        Instance.ShowTooltip(getTooltipTextFunc);
    }

    public static void HideTooltip_Static()
    {
        Instance.HideTooltip();
    }
}

TooltipTesting脚本绑定至空物体tooltipTest

public class TooltipTesting : MonoBehaviour
{
    private float timer;
    private string text;

    Func<string> getTooltipTextFunc;

    private bool isShowTooltip = true;

    private void Start()
    {
        getTooltipTextFunc = () =>
        {
            return "<color=#00ff00>testing tooltip....</color>\n " + text + "\n" +
            "<color=#F00>" + timer + "</color>";
        };

        //定时器任务
        FunctionPeriodic.Create(() =>
        {
            string abc = "dfsdvdhhkdVFDVdsVCtuukhnbvcsddasdaxzvBJBFSKBLKAND\n\n\n\n\n\n\n\n\n\n";
            text = "";
            for (int i = 0; i < UnityEngine.Random.Range(5, 100); i++)
            {
                text += abc[UnityEngine.Random.Range(0, abc.Length)];
            }
            //TooltipScreenSpaceUI.ShowTooltip_Static(text);
        }, .5f);

        TooltipScreenSpaceUI.ShowTooltip_Static(getTooltipTextFunc);
    }

    private void Update()
    {
        timer += Time.deltaTime;

		//鼠标右键单击隐藏和展示tooltip
        if (Input.GetMouseButtonUp(1))
        {
            isShowTooltip = !isShowTooltip;
            if (!isShowTooltip)
            {
                TooltipScreenSpaceUI.HideTooltip_Static();
            }
            else {
                TooltipScreenSpaceUI.ShowTooltip_Static(getTooltipTextFunc);
            }

        }
    }
}
posted @ 2024-09-14 14:46  Sitar  阅读(3)  评论(0编辑  收藏  举报