Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity UI How to determine string location inside a Text

Discussion in 'UGUI & TextMesh Pro' started by belwar, Feb 21, 2018.

  1. belwar

    belwar

    Joined:
    Feb 21, 2018
    Posts:
    5
    Hi everyone!
    I'm trying to develop a quiz game with the classic fill th gaps method.

    I've a database with some questions with the gaps represented as a "_____" pattern, and I want to create a input field on top of it.

    The problem is that since the position of the pattern is not fixed, I have lo locate it.

    Since the line height is fixed, was easy to locate the y coordinate, but not the x one (of the first '_' char). I tried several ways, but with no success.

    - I tried to get chars width to generate a left offset with:
    textObj.cachedTextGenerator.characters [charPosition].charWidth

    - I tried to locate the char with
    textObj.cachedTextGenerator.characters [charPosition].cursorPos.x

    - I tried to get a monospace font, but it messed all

    Has anyone done something similar?
    Thank you very much!!

    EXAMPLE:
    2 + _ = 5
    Here I want to locate the x position of the '_' char to create an input field on top.
     
  2. tranos

    tranos

    Joined:
    Feb 19, 2014
    Posts:
    180
    why not make the placeholder of inputfield display '_' and the check the input text ?
     
  3. belwar

    belwar

    Joined:
    Feb 21, 2018
    Posts:
    5
    Because the questions are loadedd in a database, so I receive only a string.

    I put this string in a unique Text object because the InputField would not always be in the same position
     
  4. tranos

    tranos

    Joined:
    Feb 19, 2014
    Posts:
    180
    Just an idea

    1. I would split the string to single character and put them in an array with this:
    char[] singleCharacters = "2+3=5".ToCharArray();

    2. Then I would hide randomly a character with this:
    Random random = new Random();
    int randomNumber = random.Next(0, singleCharacters.length);
    "randomNumber is the place of the character in the array"

    3.Then i would create an array of inputFields an assign the characters and set
    inputFields[randomNumber ].placeholder.GetComponent<Text>.text="_"
    inputFields[randomNumber ].interactable=true;
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Perhaps just break the text into 2 components? I think it's possible to do what you want (get the location), but I'm not sure how :) With 2 text components, just insert the inputfield inbetween them.
     
  6. belwar

    belwar

    Joined:
    Feb 21, 2018
    Posts:
    5
    Thanks everyone, finally I got what I want.

    I post my code for future people with the same problem. The solutions isn't elegant at all, but it works. It detects a gap and sets the position and size of a panel to fill the gap.

    Code (CSharp):
    1.  
    2.         float charInsideLine;
    3.         int charPosStart = textComp.text.IndexOf ('_');
    4.         int charPosEnd = charPosStart;
    5.         for (; textComp.text [charPosEnd] == '_'; charPosEnd++);
    6.  
    7.         for (int i = 0; i < textComp.cachedTextGenerator.lines.Count; i++) {
    8.             if (charPosStart > textComp.cachedTextGenerator.lines[i].startCharIdx) {
    9.                 line = i;
    10.                 charInsideLine = charPosStart - textComp.cachedTextGenerator.lines [i].startCharIdx;
    11.             }
    12.         }
    13.  
    14.         // Based on https://answers.unity.com/questions/784199/how-to-get-the-current-best-fit-size-of-a-text-com.html
    15.         string auxstr = textComp.text;
    16.         textComp.cachedTextGenerator.Invalidate();
    17.         Vector2 size = (textComp.transform as RectTransform).rect.size;
    18.         TextGenerationSettings tempSettings = textComp.GetGenerationSettings(size);
    19.         tempSettings.scaleFactor = 1;//dont know why but if I dont set it to 1 it returns a font that is to small.
    20.         if(!textComp.cachedTextGenerator.Populate(auxstr, tempSettings))
    21.             Debug.LogError("Failed to generate fit size");
    22.         Debug.Log("1: "+textComp.cachedTextGenerator.fontSizeUsedForBestFit);textComp.text = "";
    23.         textComp.text = auxstr;
    24.         // End based on https://answers.unity.com/questions/784199/how-to-get-the-current-best-fit-size-of-a-text-com.html
    25.  
    26.         auxText.font = textComp.font;
    27.         auxText.fontSize = textComp.cachedTextGenerator.fontSizeUsedForBestFit;
    28.         auxText.fontStyle = textComp.fontStyle;
    29.         auxText.resizeTextForBestFit = false;
    30.         Debug.Log (textComp.rectTransform.sizeDelta.y);
    31.         auxText.text = textComp.text.Substring (textComp.cachedTextGenerator.lines [line].startCharIdx, charPosStart-textComp.cachedTextGenerator.lines [line].startCharIdx);
    32.         yield return new WaitForEndOfFrame ();
    33.         xoffset = auxText.rectTransform.sizeDelta.x;
    34.  
    35.         auxText.text = textComp.text.Substring (charPosStart, charPosEnd-charPosStart);
    36.         yield return new WaitForEndOfFrame ();
    37.         linesize = auxText.rectTransform.sizeDelta.x;
    38.  
    39.         float lineheight = ysize/lcount;
    40.         float ypos = textComp.rectTransform.anchoredPosition.y+lineheight*lcount/2-lineheight/2-lineheight*line;
    41.  
    42.         panel.rectTransform.anchoredPosition = new Vector2(textComp.rectTransform.anchoredPosition.x-xsize/2+xoffset+linesize/2,ypos);
    43.         panel.rectTransform.sizeDelta = new Vector2 (linesize,lineheight);
    44.  
     
  7. vipulnathani20

    vipulnathani20

    Joined:
    Jul 19, 2018
    Posts:
    3
    can you provide me some more snippet of code? Because i need same requirement.
     
  8. NeverTrustShadows

    NeverTrustShadows

    Joined:
    Mar 15, 2020
    Posts:
    15
    Would you please at least make sure you posted everything..