123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- using UnityEngine;
- using UnityEngine.Events;
- using UnityEngine.EventSystems;
- using System.Collections;
- using System.Collections.Generic;
- #pragma warning disable 0618 // Disabled warning due to SetVertices being deprecated until new release with SetMesh() is available.
- namespace TMPro.Examples
- {
- public class TMP_TextSelector_B : 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_selectedWord = -1;
- private int m_selectedLink = -1;
- private int m_lastIndex = -1;
- private Matrix4x4 m_matrix;
- private TMP_MeshInfo[] m_cachedMeshInfoVertexData;
- 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;
- // Create pop-up text object which is used to show the link information.
- m_TextPopup_RectTransform = Instantiate(TextPopup_Prefab_01) as RectTransform;
- m_TextPopup_RectTransform.SetParent(m_Canvas.transform, false);
- m_TextPopup_TMPComponent = m_TextPopup_RectTransform.GetComponentInChildren<TextMeshProUGUI>();
- m_TextPopup_RectTransform.gameObject.SetActive(false);
- }
- void OnEnable()
- {
- // Subscribe to event fired when text object has been regenerated.
- TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
- }
- void OnDisable()
- {
- // UnSubscribe to event fired when text object has been regenerated.
- TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
- }
- void ON_TEXT_CHANGED(Object obj)
- {
- if (obj == m_TextMeshPro)
- {
- // Update cached vertex data.
- m_cachedMeshInfoVertexData = m_TextMeshPro.textInfo.CopyMeshInfoVertexData();
- }
- }
- void LateUpdate()
- {
- if (isHoveringObject)
- {
- // Check if Mouse Intersects any of the characters. If so, assign a random color.
- #region Handle Character Selection
- int charIndex = TMP_TextUtilities.FindIntersectingCharacter(m_TextMeshPro, Input.mousePosition, m_Camera, true);
- // Undo Swap and Vertex Attribute changes.
- if (charIndex == -1 || charIndex != m_lastIndex)
- {
- RestoreCachedVertexAttributes(m_lastIndex);
- m_lastIndex = -1;
- }
- if (charIndex != -1 && charIndex != m_lastIndex && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
- {
- m_lastIndex = charIndex;
- // Get the index of the material / sub text object used by this character.
- int materialIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].materialReferenceIndex;
- // Get the index of the first vertex of the selected character.
- int vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex;
- // Get a reference to the vertices array.
- Vector3[] vertices = m_TextMeshPro.textInfo.meshInfo[materialIndex].vertices;
- // Determine the center point of the character.
- Vector2 charMidBasline = (vertices[vertexIndex + 0] + vertices[vertexIndex + 2]) / 2;
- // Need to translate all 4 vertices of the character to aligned with middle of character / baseline.
- // This is needed so the matrix TRS is applied at the origin for each character.
- Vector3 offset = charMidBasline;
- // Translate the character to the middle baseline.
- vertices[vertexIndex + 0] = vertices[vertexIndex + 0] - offset;
- vertices[vertexIndex + 1] = vertices[vertexIndex + 1] - offset;
- vertices[vertexIndex + 2] = vertices[vertexIndex + 2] - offset;
- vertices[vertexIndex + 3] = vertices[vertexIndex + 3] - offset;
- float zoomFactor = 1.5f;
- // Setup the Matrix for the scale change.
- m_matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * zoomFactor);
- // Apply Matrix operation on the given character.
- vertices[vertexIndex + 0] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
- vertices[vertexIndex + 1] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
- vertices[vertexIndex + 2] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
- vertices[vertexIndex + 3] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
- // Translate the character back to its original position.
- vertices[vertexIndex + 0] = vertices[vertexIndex + 0] + offset;
- vertices[vertexIndex + 1] = vertices[vertexIndex + 1] + offset;
- vertices[vertexIndex + 2] = vertices[vertexIndex + 2] + offset;
- vertices[vertexIndex + 3] = vertices[vertexIndex + 3] + offset;
- // Change Vertex Colors of the highlighted character
- Color32 c = new Color32(255, 255, 192, 255);
- // Get a reference to the vertex color
- Color32[] vertexColors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32;
- vertexColors[vertexIndex + 0] = c;
- vertexColors[vertexIndex + 1] = c;
- vertexColors[vertexIndex + 2] = c;
- vertexColors[vertexIndex + 3] = c;
- // Get a reference to the meshInfo of the selected character.
- TMP_MeshInfo meshInfo = m_TextMeshPro.textInfo.meshInfo[materialIndex];
- // Get the index of the last character's vertex attributes.
- int lastVertexIndex = vertices.Length - 4;
- // Swap the current character's vertex attributes with those of the last element in the vertex attribute arrays.
- // We do this to make sure this character is rendered last and over other characters.
- meshInfo.SwapVertexData(vertexIndex, lastVertexIndex);
- // Need to update the appropriate
- m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
- }
- #endregion
- #region Word Selection Handling
- //Check if Mouse intersects any words and if so assign a random color to that word.
- int wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextMeshPro, Input.mousePosition, m_Camera);
- // Clear previous word selection.
- if (m_TextPopup_RectTransform != null && m_selectedWord != -1 && (wordIndex == -1 || wordIndex != m_selectedWord))
- {
- TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[m_selectedWord];
- // Iterate through each of the characters of the word.
- for (int i = 0; i < wInfo.characterCount; i++)
- {
- int characterIndex = wInfo.firstCharacterIndex + i;
- // Get the index of the material / sub text object used by this character.
- int meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex;
- // Get the index of the first vertex of this character.
- 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(1.33333f);
- vertexColors[vertexIndex + 0] = c;
- vertexColors[vertexIndex + 1] = c;
- vertexColors[vertexIndex + 2] = c;
- vertexColors[vertexIndex + 3] = c;
- }
- // Update Geometry
- m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
- m_selectedWord = -1;
- }
- // Word Selection Handling
- if (wordIndex != -1 && wordIndex != m_selectedWord && !(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
- {
- m_selectedWord = wordIndex;
- TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[wordIndex];
- // Iterate through each of the characters of the word.
- for (int i = 0; i < wInfo.characterCount; i++)
- {
- int characterIndex = wInfo.firstCharacterIndex + 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);
- }
- #endregion
- #region Example of Link Handling
- // 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_TextPopup_RectTransform.gameObject.SetActive(false);
- 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("Link ID: \"" + linkInfo.GetLinkID() + "\" Link Text: \"" + linkInfo.GetLinkText() + "\""); // Example of how to retrieve the Link ID and Link Text.
- Vector3 worldPointInRectangle;
- RectTransformUtility.ScreenPointToWorldPointInRectangle(m_TextMeshPro.rectTransform, Input.mousePosition, m_Camera, out worldPointInRectangle);
- switch (linkInfo.GetLinkID())
- {
- case "id_01": // 100041637: // id_01
- m_TextPopup_RectTransform.position = worldPointInRectangle;
- m_TextPopup_RectTransform.gameObject.SetActive(true);
- m_TextPopup_TMPComponent.text = k_LinkText + " ID 01";
- break;
- case "id_02": // 100041638: // id_02
- m_TextPopup_RectTransform.position = worldPointInRectangle;
- m_TextPopup_RectTransform.gameObject.SetActive(true);
- m_TextPopup_TMPComponent.text = k_LinkText + " ID 02";
- break;
- }
- }
- #endregion
- }
- else
- {
- // Restore any character that may have been modified
- if (m_lastIndex != -1)
- {
- RestoreCachedVertexAttributes(m_lastIndex);
- m_lastIndex = -1;
- }
- }
-
- }
- public void OnPointerEnter(PointerEventData eventData)
- {
- //Debug.Log("OnPointerEnter()");
- isHoveringObject = true;
- }
- public void OnPointerExit(PointerEventData eventData)
- {
- //Debug.Log("OnPointerExit()");
- isHoveringObject = false;
- }
- public void OnPointerClick(PointerEventData eventData)
- {
- //Debug.Log("Click at POS: " + eventData.position + " World POS: " + eventData.worldPosition);
- // Check if Mouse Intersects any of the characters. If so, assign a random color.
- #region Character Selection Handling
- /*
- int charIndex = TMP_TextUtilities.FindIntersectingCharacter(m_TextMeshPro, Input.mousePosition, m_Camera, true);
- if (charIndex != -1 && charIndex != m_lastIndex)
- {
- //Debug.Log("Character [" + m_TextMeshPro.textInfo.characterInfo[index].character + "] was selected at POS: " + eventData.position);
- m_lastIndex = charIndex;
- Color32 c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 255);
- int vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex;
- UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
- uiVertices[vertexIndex + 0].color = c;
- uiVertices[vertexIndex + 1].color = c;
- uiVertices[vertexIndex + 2].color = c;
- uiVertices[vertexIndex + 3].color = c;
- m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
- }
- */
- #endregion
- #region Word Selection Handling
- //Check if Mouse intersects any words and if so assign a random color to that word.
- /*
- int wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextMeshPro, Input.mousePosition, m_Camera);
- // Clear previous word selection.
- if (m_TextPopup_RectTransform != null && m_selectedWord != -1 && (wordIndex == -1 || wordIndex != m_selectedWord))
- {
- TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[m_selectedWord];
- // Get a reference to the uiVertices array.
- UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
- // Iterate through each of the characters of the word.
- for (int i = 0; i < wInfo.characterCount; i++)
- {
- int vertexIndex = m_TextMeshPro.textInfo.characterInfo[wInfo.firstCharacterIndex + i].vertexIndex;
- Color32 c = uiVertices[vertexIndex + 0].color.Tint(1.33333f);
- uiVertices[vertexIndex + 0].color = c;
- uiVertices[vertexIndex + 1].color = c;
- uiVertices[vertexIndex + 2].color = c;
- uiVertices[vertexIndex + 3].color = c;
- }
- m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
- m_selectedWord = -1;
- }
- // Handle word selection
- if (wordIndex != -1 && wordIndex != m_selectedWord)
- {
- m_selectedWord = wordIndex;
- TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[wordIndex];
- // Get a reference to the uiVertices array.
- UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
- // Iterate through each of the characters of the word.
- for (int i = 0; i < wInfo.characterCount; i++)
- {
- int vertexIndex = m_TextMeshPro.textInfo.characterInfo[wInfo.firstCharacterIndex + i].vertexIndex;
- Color32 c = uiVertices[vertexIndex + 0].color.Tint(0.75f);
- uiVertices[vertexIndex + 0].color = c;
- uiVertices[vertexIndex + 1].color = c;
- uiVertices[vertexIndex + 2].color = c;
- uiVertices[vertexIndex + 3].color = c;
- }
- m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
- }
- */
- #endregion
- #region Link Selection Handling
- /*
- // 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];
- int linkHashCode = linkInfo.hashCode;
- //Debug.Log(TMP_TextUtilities.GetSimpleHashCode("id_02"));
- switch (linkHashCode)
- {
- case 291445: // id_01
- if (m_LinkObject01 == null)
- m_LinkObject01 = Instantiate(Link_01_Prefab);
- else
- {
- m_LinkObject01.gameObject.SetActive(true);
- }
- break;
- case 291446: // id_02
- break;
- }
- // Example of how to modify vertex attributes like colors
- #region Vertex Attribute Modification Example
- UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
- Color32 c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 255);
- for (int i = 0; i < linkInfo.characterCount; i++)
- {
- TMP_CharacterInfo cInfo = m_TextMeshPro.textInfo.characterInfo[linkInfo.firstCharacterIndex + i];
- if (!cInfo.isVisible) continue; // Skip invisible characters.
- int vertexIndex = cInfo.vertexIndex;
- uiVertices[vertexIndex + 0].color = c;
- uiVertices[vertexIndex + 1].color = c;
- uiVertices[vertexIndex + 2].color = c;
- uiVertices[vertexIndex + 3].color = c;
- }
- m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
- #endregion
- }
- */
- #endregion
- }
- 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);
- }
- }
- }
|