mirror of
				https://github.com/DerTyp7/example-top-down-unity.git
				synced 2025-11-04 06:48:57 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			255 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
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);
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
}
 |