Written by Janos Szabo.
I had a simple-looking task in Unity: show text on the UI with a link in it that opens a web page. It doesn’t sound complicated, and I thought it would be an easy assignment because this is very common in HTML or anywhere else.
Expectation vs Reality
I thought that Unity already has a ‘rich-text-like’ feature, which means you can put tags into the text. For example, you can give different colours to text or format it in some simple ways. I used TextMesh Pro before and I expected that if it supports such a feature as Links it should provide a callback for clicking on them.
Even though the solution (spoiler!) is only a few lines, the way it works might not be obvious for everybody.
If you dig into this document, you can find the following:
“You can use <link=”ID”>my link</link> to add link metadata to a text segment. The Link ID should be unique to allow you to retrieve its ID and link text content when the user interacts with your text.”

So the above document tells you how to define the text, but it doesn’t tell you how to use the given ID from the code.
First I tried Unity’s manual, but I haven’t found anything useful about using TextMesh Pro, so I went for the quick help button on the inspector panel, and YES! I found the TextMesh Pro User Guide…which I suddenly realised, was dated back in 2016, but I still wanted to give it a go.

I ran through the document and it turned out to be just a manual about using TextMesh Pro, in general.
Good old Google
So I turned to google with all the information I gathered so far and I found bits and pieces here and there: in forums, in blog posts and in online discussions. I found out that the TextMesh Pro component by itself does not provide a simple callback for handling clicks on links, but…
Instead of relying on TextMesh Pro, first, I needed to catch the clicks, using a standard Unity solution, then I needed to get the position where the click occurred, then pass it to TextMesh Pro to see if it hits a linked text.
How does it work?
// Add IPointerClickHandler interface to let Unity know you want to
// catch and handle clicks (or taps on Mobile)
public class MyScreenController : MonoBehaviour, IPointerClickHandler
{
// URLs to open when links clicked
private const string HomePageUrl = "https://www.spongehammergames.com/";
private const string SomeOtherUrl = "https://www.spongehammer.com/";
private const string DefaultUrl = "https://www.spongehammer.com/";
[SerializeField, Tooltip("The UI GameObject having the TextMesh Pro component.")]
private TMP_Text text = default;
// Callback for handling clicks.
public void OnPointerClick(PointerEventData eventData)
{
// First, get the index of the link clicked. Each of the links in the text has its own index.
var linkIndex = TMP_TextUtilities.FindIntersectingLink(text, Input.mousePosition, null);
// As the order of the links can vary easily (e.g. because of multi-language support),
// you need to get the ID assigned to the links instead of using the index as a base for our decisions.
// you need the LinkInfo array from the textInfo member of the TextMesh Pro object for that.
var linkId = text.textInfo.linkInfo[linkIndex].GetLinkID();
// Now finally you have the ID in hand to decide what to do. Don't forget,
// you don't need to make it act like an actual link, instead of opening a web page,
// any kind of functions can be called.
var url = linkId switch
{
"MyLinkID1" => HomePageURL,
"MyLinkID2" => SomeOtherUrl,
_ => DefaultUrl
};
Debug.Log($"URL clicked: linkInfo[{linkIndex}].id={linkId} ==> url={url}");
// Let's see that web page!
Application.OpenURL(url);
}
}
Final words
Interestingly though, I found the key method later among the pages of online Unity documentation here, but it still lacks actual examples or contextual information on how to use it. Despite the solution being only a few lines of code, the investigation took a bit of time and effort.
I hope you found this snippet useful.
Sources
Rich text documentation for TextMesh Pro
If you have any comments, ideas or personal experiences, feel free to share with us. We are curious to hear new ideas, solutions, and perspectives regarding the above. Don’t forget to follow us on our social media!
You can also find the rest of our blog here!