Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by nyonge · Jul 27, 2016 at 09:04 PM · uitransformpositiontextrecttransform

Get position of specific letter in UI Text

Is there any way to get the position of a specific letter (or any part of the string) in a UI text? In World Space, Screen Space, Canvas Space, whatever.

Say I have text that can be "Level 1" or "Level 1000". It's middle-aligned so the letter L can be anywhere on the screen, but I want to move a GameObject right beside the L. How would I find that?

This is using Unity's UI canvas. Specifically with Screen Space - Overlay, but ideally I'd like a solution that works regardless of screen space/world space type.

Thanks!

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Sujil-V-S · Nov 14, 2016 at 06:11 AM 0
Share

I want to achieve the same in my project as well. Please let me know if someone already has an answer for this.

avatar image hexagonius · Nov 14, 2016 at 02:15 PM 0
Share

If you just need the left side of the text since the 'L' is the left most character you can use RectTransform.GetWorldCorners for a one liner. for multiple lines you would need the cachedTextGenerator of the Text-Component with GetCharacters or GetCharactersArray. If you know your 'L's index (0 in your case) you'll get the cursor position in local space

4 Replies

· Add your reply
  • Sort: 
avatar image
6

Answer by Pratap-Dafedar · Nov 14, 2016 at 02:50 PM

Hi Here is the scriptsnippet which will help you find exact letter position in Unity UI Text.

 public class TextTest : MonoBehaviour
 {
     public Text textComp;
     public int charIndex;
     public Canvas canvas;
 
     void PrintPos ()
     {
         string text = textComp.text;
 
         if (charIndex >= text.Length)
             return;
 
         TextGenerator textGen = new TextGenerator (text.Length);
         Vector2 extents = textComp.gameObject.GetComponent<RectTransform>().rect.size;
         textGen.Populate (text, textComp.GetGenerationSettings (extents));
 
         int newLine = text.Substring(0, charIndex).Split('\n').Length - 1;
         int whiteSpace = text.Substring(0, charIndex).Split(' ').Length - 1;
         int indexOfTextQuad = (charIndex * 4) + (newLine * 4) - 4;
         if (indexOfTextQuad < textGen.vertexCount)
         {
             Vector3 avgPos = (textGen.verts[indexOfTextQuad].position + 
                 textGen.verts[indexOfTextQuad + 1].position + 
                 textGen.verts[indexOfTextQuad + 2].position + 
                 textGen.verts[indexOfTextQuad + 3].position) / 4f;
 
             print (avgPos);
             PrintWorldPos (avgPos);
         }
         else {
             Debug.LogError ("Out of text bound");
         }
     }
 
     void PrintWorldPos (Vector3 testPoint)
     {
         Vector3 worldPos = textComp.transform.TransformPoint (testPoint);
         print (worldPos);
         new GameObject ("point").transform.position = worldPos;
         Debug.DrawRay (worldPos, Vector3.up, Color.red, 50f);
     }
 
     void OnGUI ()
     {
         if (GUI.Button (new Rect (10, 10, 100, 80), "Test"))
         {
             PrintPos ();
         }
     }
 }[link text][1]

Note: This logic works pretty well with any font and any text properties. Attached unity package to show same script sample.

Tested in : Unity 5.4.0f3 @Sujil-V-S Try this...

[1]: /storage/temp/82165-findletterposinuitext.zip


findletterposinuitext.zip (7.9 kB)
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gkillz · Jan 02, 2017 at 12:23 PM 0
Share

why are we recreating TextGenerator, can we not use the Textgenerator present in the Text, like this- textComp.cachedTextGenerator;

avatar image Halleester · Mar 23, 2017 at 01:52 PM 0
Share

How would I make this work with the canvas scaler in the mode "Scale with Screen Size"? I'm assu$$anonymous$$g that it has something to do with textGen.Populate using the wrong location, but I'm not sure because I've never worked with Text Generators before.

avatar image KVinS · May 17, 2019 at 12:50 AM 0
Share

Thank you for your code. But I don’t really understand what coordinates I get ... I can’t put either Image or SpriteRenderer in its ... It would be great to add an example using it.

avatar image lucasgomesb · Apr 03, 2021 at 06:06 AM 1
Share

I think there is a small error in the Pratap-Dafedar code. The "whitespace" variable is not being used.

I needed to change this line: int indexOfTextQuad = (charIndex 4) + (newLine 4) - 4;

To: int indexOfTextQuad = (charIndex 4) + (newLine 4) - (whiteSpace * 4);

avatar image
4

Answer by hengde · May 26, 2017 at 06:06 PM

@Halleester and anyone else who needs this to work with the canvas set to scale with screen size:

simply divide the position returned for a character by the canvas.scaleFactor

 worldPos /= canvas.scaleFactor

and it should work fine. I just got it working myself.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
2

Answer by Jbaker08 · Oct 16, 2018 at 02:35 PM

@Halleester, if you're using this on a canvas with a canvas scaler component, you need to divide it by the scale factor. @hengde's solution won't actually work due to the canvas scaler being broken, canvas.scalefactor will always return 1 since it takes a frame to get the scale information. To fix this store a variable that either gets defined after the scale value has initalized (one frame will do) or set it in an update function.

 float screen_scale;
  
  void Update()
     {
         screen_scale = canvas.scaleFactor;
     }

Then I had to divide the scalefactor in the actual returned value.

   return PrintWorldPos(avgPos / screen_scale);

For some reason, dividing it by the screen scale didn't work when I added into the 'printworldpos' function.

Thanks

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by abdullahahmetaskin · Jun 20, 2021 at 06:42 PM

Guys if you looking for text mesh pro version of this code i have working one . It is like this

 public GameObject GetPositionOfLastLetterAsGameObject(TextMeshProUGUI tmp_text)
 {

     tmp_text.ForceMeshUpdate();

     Vector3[] vertices = tmp_text.mesh.vertices;
     TMP_CharacterInfo charInfo = tmp_text.textInfo.characterInfo[tmp_text.textInfo.characterCount - 1];
     int vertexIndex = charInfo.vertexIndex;

     Vector2 charMidTopLine = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, (charInfo.bottomLeft.y + charInfo.topLeft.y) / 2);
     Vector3 worldPos = tmp_text.transform.TransformPoint(charMidTopLine);

     GameObject charPositionGameObj = new GameObject("PositionOfLastChar");
     charPositionGameObj.transform.position = worldPos;

     return charPositionGameObj;
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

86 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Changing vertex positions of a uGUI Text Mesh 0 Answers

How to change the Top and Bottom (rect.yMin and yMax) properties of a rectTransform, in a script? 2 Answers

UI Text position not as shown in scene view? 1 Answer

How to change the gameobjects position and transform in a scene when the device orientation changes. 1 Answer

How do I obtain children on UI canvas text 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges