【Unity】创建动态的Tooltip
需求说明
- 文字内容动态变化;
- 根据文字的内容自适应宽高;
- 跟随鼠标移动;
- 可以隐藏和展示;
- 鼠标到达窗口边缘,tooltip停靠边缘可见;
成果展示
Scene部分
注意将文字放在最左下角
脚本部分
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);
}
}
}
}