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