5

Unity TMP_Text Clickable Links

I wasn't using Unity for very long before I wanted to to make a clickable link within a TextMeshPro Text area. Sure, you could add a button and have text on both sides of it, but this makes the formatting difficult and changing the text at runtime would be extra annoying. The easiest approach is to use TextMeshPro's markup language!

The core of this technique is using a <link="ID">my link</link> tag in the TMP_Text.text value. If you attach the following script to your text GameObject, you'll get the ID value logged to console:

using TMPro;
using UnityEngine.EventSystems;
using UnityEngine;
[RequireComponent(typeof(TMP_Text))]
public class Interactable : MonoBehaviour, IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        TMP_Text text = GetComponent<TMP_Text>();
        int linkIndex = TMP_TextUtilities.FindIntersectingLink(text, eventData.position, null);
        if (linkIndex != -1)
        {
            TMP_LinkInfo linkInfo = text.textInfo.linkInfo[linkIndex];
            Debug.Log($"Interactable.OnPointerClick: ID={linkInfo.GetLinkID()}");
        }
    }
}

1 2 3 4

Clean it up

To make this a little more obvious/useful, use some other markup to underline the link and preform operations with the ID value and enclosed value. Set the text value to this:

Hello world,
This link works! ->
    <b><u><link="DoWhatYouWant|WithThisField">https://unity3d.com/get-unity/download</link></u></b>

And update

...
public void OnPointerClick(PointerEventData eventData)
{
    TMP_Text text = GetComponent<TMP_Text>();
    int linkIndex = TMP_TextUtilities.FindIntersectingLink(text, eventData.position, null);
    if (linkIndex != -1)
    {
        TMP_LinkInfo linkInfo = text.textInfo.linkInfo[linkIndex];
        string ID = linkInfo.GetLinkID();
        string[] parts = ID.Split("|");
        Debug.Log("Example: You could split fields of the ID to map to different Link operations");
        Debug.Log($"Key={parts[0]} Value={parts[1]}");
        string value = linkInfo.GetLinkText();
        // Open URL in browser
        System.Diagnostics.Process.Start(value);
    }
}
...

And run you're scene! This should inspire what you can do with this!