Search Unity

Resolved [UI] TextMeshPro - How to get the caracter under the mouse?

Discussion in 'Scripting' started by Quasar47, Nov 28, 2021.

  1. Quasar47

    Quasar47

    Joined:
    Mar 24, 2017
    Posts:
    122
    Hello everyone,

    I'm currently making a roguelite game in ASCII format, aka where all characters are represented in plain text with a simple TextMeshProUGUI Component.

    What I would like is to get any char's position in pixels and compare it to the mouse cursor's position, then if they roughly coincide, get the char's sibling index to determine its order in the TMP's string (See below : The '@' and 'r' caracters are both playable entities in the game with their own stats and behaviours).

    Sans titre.png

    This would allow me to retrieve the actual Character on the Map and display its info to the player. How should I go about this?

    Thank you for your time.
     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,648
    I think you can use TextMeshProUGUI.textInfo.characterInfo[characterIndex].bottomLeft, bottomRight, topLeft, or topRight to get the position of the character. You then can compare your mouse's Canvas position to it.
     
  3. Quasar47

    Quasar47

    Joined:
    Mar 24, 2017
    Posts:
    122
    You were on the right track, but I found this in the TMP Package's example assets :

    Code (CSharp):
    1. TMP_TextUtilities.FindIntersectingCharacter(TextMeshProUGUI component, Vector3 position, Camera main, bool visibleOnly);
    It returns the index of the character I'm hovering over. It needs null in the Camera parameter if the canvas is in Screen Space Overlay.

    I'll update this when I can get the actual coordinates correctly.
     
    ExNinja likes this.
  4. Quasar47

    Quasar47

    Joined:
    Mar 24, 2017
    Posts:
    122
    Alright, I found a solution. Using my last answer, I made this :

    Code (CSharp):
    1.  
    2.             int charIndex = TMP_TextUtilities.FindIntersectingCharacter(_mapTextField, UnityEngine.Input.mousePosition, null, true);
    3.  
    4.             if (charIndex != -1 && charIndex != _mapTextField.textInfo.characterCount)
    5.             {
    6.                 Vector2Int coords = new Vector2Int(charIndex % s_Size.x,  charIndex / s_Size.x);
    7.                 var cellUnderMouse = s_Map[coords.x, coords.y];
    8.             }
    The problem with TMP_TextUtilities.FindIntersectingCharacter() is that it retrieves a char depending on the character's mesh, so if you have small characters (like .,'-) they will be harder to aim with the mouse.
     
    RadRedPanda likes this.
  5. said123sawn

    said123sawn

    Joined:
    Oct 31, 2019
    Posts:
    26
    I think this makes more sense:
    Code (CSharp):
    1. int CaretPos = TMP_TextUtilities.FindNearestCharacter(MyText, UnityEngine.Input.mousePosition, null, true);