在 Unity 中构建支持超链接富文本的消息框

1,232 阅读2分钟

Unity 里构建对话框显示包含链接文本

创建对话框

在 Unity 里创建一个 Prefab

屏幕截图 2024-07-04 153904.png

然后在其上创建 MessageBox 的一系列对象

2024-07-04_18-32.png

其中 Info 对象是 TextMesh Pro 对象。

我们给 Info 的初始内容如下:

为了更好地保障您的个人权益,在使用前,请您务必审慎的阅读和理解我们的<color=blue><link=https://www.mygame.com/1.html>《用户协议》</link></color>、<color=blue><link=https://www.mygame.com/2.html>《隐私协议》</link></color>和<color=blue><link=https://www.mygame.com/3.html>《儿童隐私保护指引》</link></color>。如您已详细阅读并同意此协议,请点击“确定”开始游戏。如您拒绝,将无法进入游戏。

因为 TextMesh Pro 的字体问题,现在文字都显示为方框。

引入 TextMesh Pro

使用 TextMesh Pro 这个官方提供的组件。在第一次引入的时候 TextMesh Pro 会向项目里导入所需要的一些代码和资源,都在 Assets\TextMesh Pro 目录下面。

1f2c62ad984e50e1f7123e289ff3d557.png

TextMesh Pro 支持复杂文本样式,包括 <link> 标签、<color> 标签等等。我们这里只需要用到这两个。

添加字体

TextMesh Pro 自带的 LiberationSans 字体不支持中文,中文会显示为方框。所以我们需要添加中文字体。我这里只添加了思源黑体的 Regular,因为暂时没有其它字体需求。

从思源黑体 Release 里下载 Region Specific Subset OTFs Simplified Chinese (简体中文) 包,然后把里面的 SourceHanSansCN-Regular.otf 文件拷贝到项目 Assets\TextMesh Pro\Fonts 目录。

这时我们可以在 Unity 的界面里看到新添加的字体:

9444c63b8b6abdc4082c4354f8dde7f0.png

右键点击导入的字体文件,选择 Create -> TextMeshPro -> Font Asset

371cb83e7594ce7527a79da69c1a330c.png

这样会生成一个 TextMesh Pro 字体资产,点击它,在 Inspector 里可以看到各种设置。

ea243ab3853ae31be3afae279a9f2798.png

选中 Info,修改字体为我们新添加的思源黑体

4671904c7867fe4518c9585dbc7c0b78.png

2024-07-04_17-09.png

添加链接处理

在Unity 的 Assets 目录下创建一个 C# Script LinkHandler.cs,内容为:

using UnityEngine;
using TMPro;
using UnityEngine.EventSystems;
using System.Collections.Generic;

public class LinkHandler : MonoBehaviour, IPointerClickHandler
{
    public TextMeshProUGUI textMeshProUGUI;

    private void Start()
    {
        textMeshProUGUI = GetComponent<TextMeshProUGUI>();

        // 设置文本内容
        //string fullText = "为了更好地保障您的个人权益,在使用前,请您务必审慎的阅读和理解我们的<color=blue><link=https://www.longtugame.com/t2/261/6320.html>《用户协议》</link></color>、<color=blue><link=https://www.longtugame.com/t2/261/6319.html>《隐私协议》</link></color>和<color=blue><link=https://www.longtugame.com/t2/261/6321.html>《儿童隐私保护指引》</link></color>。如您已详细阅读并同意此协议,请点击“同意”开始游戏。如您拒绝,将无法进入游戏。";
        //textMeshProUGUI.text = fullText;
        //textMeshProUGUI.ForceMeshUpdate(); // 确保文本更新

        // 注册链接点击事件的回调函数
        textMeshProUGUI.color = Color.black;
        textMeshProUGUI.richText = true;
        textMeshProUGUI.raycastTarget = true;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        // 检查点击的区域是否是文本链接
        int linkIndex = TMP_TextUtilities.FindIntersectingLink(textMeshProUGUI, Input.mousePosition, null);
        if (linkIndex != -1)
        {
            TMP_LinkInfo linkInfo = textMeshProUGUI.textInfo.linkInfo[linkIndex];
            string url = linkInfo.GetLinkID();
            Application.OpenURL(url);
        }
    }
}

在 Unity 界面上点中此脚本,拖拽到 Info 对象上去,然后选择脚本的 Text Mes Pro UGUI 对象为 Info

2fa9f4061024af395745beefe8b3ffcf.png

OnPointerClick 方法在检测到用户点击后,会检查点击位置是否是一个超链接,并用 Application.OpenURL 方法来打开超链接。