| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 | using UnityEngine;using UnityEngine.Events;using UnityEngine.EventSystems;using System;namespace TMPro{    public class TMP_TextEventHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler    {        [Serializable]        public class CharacterSelectionEvent : UnityEvent<char, int> { }        [Serializable]        public class SpriteSelectionEvent : UnityEvent<char, int> { }        [Serializable]        public class WordSelectionEvent : UnityEvent<string, int, int> { }        [Serializable]        public class LineSelectionEvent : UnityEvent<string, int, int> { }        [Serializable]        public class LinkSelectionEvent : UnityEvent<string, string, int> { }        /// <summary>        /// Event delegate triggered when pointer is over a character.        /// </summary>        public CharacterSelectionEvent onCharacterSelection        {            get { return m_OnCharacterSelection; }            set { m_OnCharacterSelection = value; }        }        [SerializeField]        private CharacterSelectionEvent m_OnCharacterSelection = new CharacterSelectionEvent();        /// <summary>        /// Event delegate triggered when pointer is over a sprite.        /// </summary>        public SpriteSelectionEvent onSpriteSelection        {            get { return m_OnSpriteSelection; }            set { m_OnSpriteSelection = value; }        }        [SerializeField]        private SpriteSelectionEvent m_OnSpriteSelection = new SpriteSelectionEvent();        /// <summary>        /// Event delegate triggered when pointer is over a word.        /// </summary>        public WordSelectionEvent onWordSelection        {            get { return m_OnWordSelection; }            set { m_OnWordSelection = value; }        }        [SerializeField]        private WordSelectionEvent m_OnWordSelection = new WordSelectionEvent();        /// <summary>        /// Event delegate triggered when pointer is over a line.        /// </summary>        public LineSelectionEvent onLineSelection        {            get { return m_OnLineSelection; }            set { m_OnLineSelection = value; }        }        [SerializeField]        private LineSelectionEvent m_OnLineSelection = new LineSelectionEvent();        /// <summary>        /// Event delegate triggered when pointer is over a link.        /// </summary>        public LinkSelectionEvent onLinkSelection        {            get { return m_OnLinkSelection; }            set { m_OnLinkSelection = value; }        }        [SerializeField]        private LinkSelectionEvent m_OnLinkSelection = new LinkSelectionEvent();        private TMP_Text m_TextComponent;        private Camera m_Camera;        private Canvas m_Canvas;        private int m_selectedLink = -1;        private int m_lastCharIndex = -1;        private int m_lastWordIndex = -1;        private int m_lastLineIndex = -1;        void Awake()        {            // Get a reference to the text component.            m_TextComponent = gameObject.GetComponent<TMP_Text>();            // Get a reference to the camera rendering the text taking into consideration the text component type.            if (m_TextComponent.GetType() == typeof(TextMeshProUGUI))            {                m_Canvas = gameObject.GetComponentInParent<Canvas>();                if (m_Canvas != null)                {                    if (m_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)                        m_Camera = null;                    else                        m_Camera = m_Canvas.worldCamera;                }            }            else            {                m_Camera = Camera.main;            }        }        void LateUpdate()        {            if (TMP_TextUtilities.IsIntersectingRectTransform(m_TextComponent.rectTransform, Input.mousePosition, m_Camera))            {                #region Example of Character or Sprite Selection                int charIndex = TMP_TextUtilities.FindIntersectingCharacter(m_TextComponent, Input.mousePosition, m_Camera, true);                if (charIndex != -1 && charIndex != m_lastCharIndex)                {                    m_lastCharIndex = charIndex;                    TMP_TextElementType elementType = m_TextComponent.textInfo.characterInfo[charIndex].elementType;                    // Send event to any event listeners depending on whether it is a character or sprite.                    if (elementType == TMP_TextElementType.Character)                        SendOnCharacterSelection(m_TextComponent.textInfo.characterInfo[charIndex].character, charIndex);                    else if (elementType == TMP_TextElementType.Sprite)                        SendOnSpriteSelection(m_TextComponent.textInfo.characterInfo[charIndex].character, charIndex);                }                #endregion                #region Example of Word Selection                // Check if Mouse intersects any words and if so assign a random color to that word.                int wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextComponent, Input.mousePosition, m_Camera);                if (wordIndex != -1 && wordIndex != m_lastWordIndex)                {                    m_lastWordIndex = wordIndex;                    // Get the information about the selected word.                    TMP_WordInfo wInfo = m_TextComponent.textInfo.wordInfo[wordIndex];                    // Send the event to any listeners.                    SendOnWordSelection(wInfo.GetWord(), wInfo.firstCharacterIndex, wInfo.characterCount);                }                #endregion                #region Example of Line Selection                // Check if Mouse intersects any words and if so assign a random color to that word.                int lineIndex = TMP_TextUtilities.FindIntersectingLine(m_TextComponent, Input.mousePosition, m_Camera);                if (lineIndex != -1 && lineIndex != m_lastLineIndex)                {                    m_lastLineIndex = lineIndex;                    // Get the information about the selected word.                    TMP_LineInfo lineInfo = m_TextComponent.textInfo.lineInfo[lineIndex];                    // Send the event to any listeners.                    char[] buffer = new char[lineInfo.characterCount];                    for (int i = 0; i < lineInfo.characterCount && i < m_TextComponent.textInfo.characterInfo.Length; i++)                    {                        buffer[i] = m_TextComponent.textInfo.characterInfo[i + lineInfo.firstCharacterIndex].character;                    }                    string lineText = new string(buffer);                    SendOnLineSelection(lineText, lineInfo.firstCharacterIndex, lineInfo.characterCount);                }                #endregion                #region Example of Link Handling                // Check if mouse intersects with any links.                int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextComponent, Input.mousePosition, m_Camera);                // Handle new Link selection.                if (linkIndex != -1 && linkIndex != m_selectedLink)                {                    m_selectedLink = linkIndex;                    // Get information about the link.                    TMP_LinkInfo linkInfo = m_TextComponent.textInfo.linkInfo[linkIndex];                    // Send the event to any listeners.                    SendOnLinkSelection(linkInfo.GetLinkID(), linkInfo.GetLinkText(), linkIndex);                }                #endregion            }            else            {                // Reset all selections given we are hovering outside the text container bounds.                m_selectedLink = -1;                m_lastCharIndex = -1;                m_lastWordIndex = -1;                m_lastLineIndex = -1;            }        }        public void OnPointerEnter(PointerEventData eventData)        {            //Debug.Log("OnPointerEnter()");        }        public void OnPointerExit(PointerEventData eventData)        {            //Debug.Log("OnPointerExit()");        }        private void SendOnCharacterSelection(char character, int characterIndex)        {            if (onCharacterSelection != null)                onCharacterSelection.Invoke(character, characterIndex);        }        private void SendOnSpriteSelection(char character, int characterIndex)        {            if (onSpriteSelection != null)                onSpriteSelection.Invoke(character, characterIndex);        }        private void SendOnWordSelection(string word, int charIndex, int length)        {            if (onWordSelection != null)                onWordSelection.Invoke(word, charIndex, length);        }        private void SendOnLineSelection(string line, int charIndex, int length)        {            if (onLineSelection != null)                onLineSelection.Invoke(line, charIndex, length);        }        private void SendOnLinkSelection(string linkID, string linkText, int linkIndex)        {            if (onLinkSelection != null)                onLinkSelection.Invoke(linkID, linkText, linkIndex);        }    }}
 |