Here is the link: https://assetstore.unity.com/packages/essentials/beta-projects/textmesh-pro-84126
Unfortunately the documentation is a bit sketchy, some out-of-date, and difficult to find for the newer version.
So to get it to work...
- Update to Unity 5.6 or later.
- Download and install the package.
- From GameObject > UI add a TextMeshPro-Text to the canvas.
- Make sure the scene has an Event System object.
- Add a script to TextMesh Pro Text object based on TMP_Text_Selector_B.cs
- Links in the text need to be tagged like: Some text <link="link_name">this text has a link</link> and this is boring text.
- In TMP_TextInfoDebugTool.cs comment out the contents of method OnDrawGizmos() as this causes errors in the editor.
- There is a sample scene called: 12 - Link Example with links that work.
- If using the color tag (which works a little different to to the Text color tag) make sure that the base text color is white. Color tags are in the form: <#40A0FF>This is a color tag - just specify the color in the tag.</color>
- While I could get the mouseovers to work using the new TMP Text Event Handler script I couldn't get it to register mouse clicks so I used the old TMP_Text_Selector_B version instead.
This is my Selector script based on TMP_Text_Selector_B
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
using TMPro;
// Disabled warning due to SetVertices being deprecated
// until new release with SetMesh() is available.
#pragma warning disable 0618
public class TextOutputTextSelector : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler, IPointerUpHandler
{
public RectTransform TextPopup_Prefab_01;
private RectTransform m_TextPopup_RectTransform;
private TextMeshProUGUI m_TextPopup_TMPComponent;
private const string k_LinkText = "You have selected link <#ffff00>";
private const string k_WordText = "Word Index: <#ffff00>";
private TextMeshProUGUI m_TextMeshPro;
private Canvas m_Canvas;
private Camera m_Camera;
// Flags
private bool isHoveringObject;
private int m_selectedLink = -1;
private int m_selectedWord = -1;
private int m_lastIndex = -1;
private Matrix4x4 m_matrix;
private TMP_MeshInfo[] m_cachedMeshInfoVertexData;
// ----------------------------------------------------------------------------
public void Awake()
{
m_TextMeshPro = gameObject.GetComponent<TextMeshProUGUI>();
m_Canvas = gameObject.GetComponentInParent<Canvas>();
// Get a reference to the camera if Canvas Render Mode is not ScreenSpace Overlay.
if (m_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
m_Camera = null;
else
m_Camera = m_Canvas.worldCamera;
}
// ----------------------------------------------------------------------------
public void OnEnable()
{
// Subscribe to event fired when text object has been regenerated.
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
}
// ----------------------------------------------------------------------------
public void OnDisable()
{
// UnSubscribe to event fired when text object has been regenerated.
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
}
// ----------------------------------------------------------------------------
public void ON_TEXT_CHANGED(Object obj)
{
if (obj == m_TextMeshPro)
{
// Update cached vertex data.
m_cachedMeshInfoVertexData = m_TextMeshPro.textInfo.CopyMeshInfoVertexData();
}
}
// ----------------------------------------------------------------------------
public void LateUpdate()
{
if (isHoveringObject)
{
// LINKS
// Check if mouse intersects with any links.
int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
// Clear previous link selection if one existed.
if ((linkIndex == -1 && m_selectedLink != -1) || linkIndex != m_selectedLink)
{
m_selectedLink = -1;
}
// Handle new Link selection.
if (linkIndex != -1 && linkIndex != m_selectedLink)
{
m_selectedLink = linkIndex;
TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
Debug.Log("(Late Update) Selected Link Index: " + m_selectedLink);
Debug.Log("*** (Late Update) Link ID: \"" + linkInfo.GetLinkID() + "\" Link Text: \"" + linkInfo.GetLinkText() + "\"");
Vector3 worldPointInRectangle = Vector3.zero;
RectTransformUtility.ScreenPointToWorldPointInRectangle(m_TextMeshPro.rectTransform, Input.mousePosition, m_Camera, out worldPointInRectangle);
// change color of link (Doesn't quite work but leaving here for future use)
// Iterate through each of the characters of the word.
/*
Debug.Log("First Character Index: " + linkInfo.linkTextfirstCharacterIndex);
Debug.Log("Link Text Length: " + linkInfo.linkTextLength);
for (int i = 0; i < linkInfo.linkTextLength; i++)
{
int characterIndex = linkInfo.linkTextfirstCharacterIndex + i;
// Get the index of the material / sub text object used by this character.
int meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex;
int vertexIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].vertexIndex;
// Get a reference to the vertex color
Color32[] vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32;
Color32 c = vertexColors[vertexIndex + 0].Tint(0.75f);
vertexColors[vertexIndex + 0] = c;
vertexColors[vertexIndex + 1] = c;
vertexColors[vertexIndex + 2] = c;
vertexColors[vertexIndex + 3] = c;
}
// Update Geometry
m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
*/
}
}
else
{
// Restore any character that may have been modified
if (m_lastIndex != -1)
{
RestoreCachedVertexAttributes(m_lastIndex);
m_lastIndex = -1;
}
}
}
// ----------------------------------------------------------------------------
public void OnPointerEnter(PointerEventData eventData)
{
isHoveringObject = true;
}
// ----------------------------------------------------------------------------
public void OnPointerExit(PointerEventData eventData)
{
//Debug.Log("OnPointerExit()");
isHoveringObject = false;
}
// ----------------------------------------------------------------------------
public void OnPointerClick(PointerEventData eventData)
{
// Check if Mouse intersects any words and if so assign a random color to that word.
int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
if (linkIndex != -1)
{
//TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
Debug.Log("(On Pointer Click) - Selected Link ID: " + m_selectedLink);
Debug.Log("Mouse position - X: " + Input.mousePosition.x + ", Y: " + Input.mousePosition.y);
}
}
// ----------------------------------------------------------------------------
public void OnPointerUp(PointerEventData eventData)
{
//Debug.Log("OnPointerUp()");
}
// ----------------------------------------------------------------------------
void RestoreCachedVertexAttributes(int index)
{
if (index == -1 || index > m_TextMeshPro.textInfo.characterCount - 1) return;
// Get the index of the material / sub text object used by this character.
int materialIndex = m_TextMeshPro.textInfo.characterInfo[index].materialReferenceIndex;
// Get the index of the first vertex of the selected character.
int vertexIndex = m_TextMeshPro.textInfo.characterInfo[index].vertexIndex;
// Restore Vertices
// Get a reference to the cached / original vertices.
Vector3[] src_vertices = m_cachedMeshInfoVertexData[materialIndex].vertices;
// Get a reference to the vertices that we need to replace.
Vector3[] dst_vertices = m_TextMeshPro.textInfo.meshInfo[materialIndex].vertices;
// Restore / Copy vertices from source to destination
dst_vertices[vertexIndex + 0] = src_vertices[vertexIndex + 0];
dst_vertices[vertexIndex + 1] = src_vertices[vertexIndex + 1];
dst_vertices[vertexIndex + 2] = src_vertices[vertexIndex + 2];
dst_vertices[vertexIndex + 3] = src_vertices[vertexIndex + 3];
// Restore Vertex Colors
// Get a reference to the vertex colors we need to replace.
Color32[] dst_colors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32;
// Get a reference to the cached / original vertex colors.
Color32[] src_colors = m_cachedMeshInfoVertexData[materialIndex].colors32;
// Copy the vertex colors from source to destination.
dst_colors[vertexIndex + 0] = src_colors[vertexIndex + 0];
dst_colors[vertexIndex + 1] = src_colors[vertexIndex + 1];
dst_colors[vertexIndex + 2] = src_colors[vertexIndex + 2];
dst_colors[vertexIndex + 3] = src_colors[vertexIndex + 3];
// Restore UV0S
// UVS0
Vector2[] src_uv0s = m_cachedMeshInfoVertexData[materialIndex].uvs0;
Vector2[] dst_uv0s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs0;
dst_uv0s[vertexIndex + 0] = src_uv0s[vertexIndex + 0];
dst_uv0s[vertexIndex + 1] = src_uv0s[vertexIndex + 1];
dst_uv0s[vertexIndex + 2] = src_uv0s[vertexIndex + 2];
dst_uv0s[vertexIndex + 3] = src_uv0s[vertexIndex + 3];
// UVS2
Vector2[] src_uv2s = m_cachedMeshInfoVertexData[materialIndex].uvs2;
Vector2[] dst_uv2s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs2;
dst_uv2s[vertexIndex + 0] = src_uv2s[vertexIndex + 0];
dst_uv2s[vertexIndex + 1] = src_uv2s[vertexIndex + 1];
dst_uv2s[vertexIndex + 2] = src_uv2s[vertexIndex + 2];
dst_uv2s[vertexIndex + 3] = src_uv2s[vertexIndex + 3];
// Restore last vertex attribute as we swapped it as well
int lastIndex = (src_vertices.Length / 4 - 1) * 4;
// Vertices
dst_vertices[lastIndex + 0] = src_vertices[lastIndex + 0];
dst_vertices[lastIndex + 1] = src_vertices[lastIndex + 1];
dst_vertices[lastIndex + 2] = src_vertices[lastIndex + 2];
dst_vertices[lastIndex + 3] = src_vertices[lastIndex + 3];
// Vertex Colors
src_colors = m_cachedMeshInfoVertexData[materialIndex].colors32;
dst_colors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32;
dst_colors[lastIndex + 0] = src_colors[lastIndex + 0];
dst_colors[lastIndex + 1] = src_colors[lastIndex + 1];
dst_colors[lastIndex + 2] = src_colors[lastIndex + 2];
dst_colors[lastIndex + 3] = src_colors[lastIndex + 3];
// UVS0
src_uv0s = m_cachedMeshInfoVertexData[materialIndex].uvs0;
dst_uv0s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs0;
dst_uv0s[lastIndex + 0] = src_uv0s[lastIndex + 0];
dst_uv0s[lastIndex + 1] = src_uv0s[lastIndex + 1];
dst_uv0s[lastIndex + 2] = src_uv0s[lastIndex + 2];
dst_uv0s[lastIndex + 3] = src_uv0s[lastIndex + 3];
// UVS2
src_uv2s = m_cachedMeshInfoVertexData[materialIndex].uvs2;
dst_uv2s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs2;
dst_uv2s[lastIndex + 0] = src_uv2s[lastIndex + 0];
dst_uv2s[lastIndex + 1] = src_uv2s[lastIndex + 1];
dst_uv2s[lastIndex + 2] = src_uv2s[lastIndex + 2];
dst_uv2s[lastIndex + 3] = src_uv2s[lastIndex + 3];
// Need to update the appropriate
m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
}
}
No comments:
Post a Comment