I’m trying to make an auto-complete-dropdown inside a multiline-TextField. How can I get the caret position coordinates inside a TextField?
One approach would be finding calculating the current caret position in terms of cursor row and index and then find out font character size. But I can’t find font character size anywhere, is this possible before TextField supports FontAssets (or even then)?
Or is there some other approach I could take? Basically I would need to know where the caret is after each keypress.
I recently had to know the position of a word in a label and the only solution I found was to use the TextGenerator Unity - Scripting API: TextGenerator. From there you can access each individual character and get it’s position and width.
Thanks! Sounds good! It seems this solution requires using Font Assets which (as I understood) aren’t supported by TextField of UI Toolkit just yet (preview 13) although I also understood from another post that they are on the roadmap). I will try this when the Font Asset support manifests. Thanks for the tip!
Thanks! I’m using a monospace font, so I used TextGenerator to generate one character and I’m using the width of this character for all. I managed to get the font size and I’m trying to calculate coordinates with following:
x = currentLineCursorIndex * charWidthFromTextGenerator
y = currentLineNumber * visualElement.resolvedStyle.fontSize
I’m then trying to move my desired VisualElement to these coordinates via:
visualElementReference.style.top = new
StyleLength(y);
visualElementReference.style.left = new
StyleLength(x);
I also tried accounting letter-spacing from visualElement.resolvedStyle.letterSpacing
But for some reason, when I apply the x and y, they fall short of the actual caret position. Is there some multiplier or something I should account for? When I move right, the position is less than the actual character pixels on screen. When I move down, the movement is less than fontSize.
For some reason, cursorPos is Vector2.zero all the time. I do the generation and can see that vertexes are generated (generator.vertexCount returns 696). However, no matter which character position I check, it’s always (0, 0):
Debug.Log("Caret cursor at position " + textField.cursorIndex + " position is " + generator.characters[textField.cursorIndex].cursorPos.x + ", " + generator.characters[textField.cursorIndex].cursorPos.y);
Could this be some bug or is there some behaviour I’m missing? If there is something generated, surely they shouldn’t all be at 0 position?
If someone knows about this, greatly appreciated! I tried to render the window content with the resolved style, but for some reason, the character coordinates from the TextGenerator are way less than the real coordinates on screen. They seem to move in sync so the generator succeeds, but it appears the render is smaller than real world render in the actual window.
Could you be more specific? The character positions are in local space relative to the pivot and generationExtents specified in the TextGenerationSettings. If you want the world position of a character, you’ll have to user VisualElement.LocalToWorld(charPos)
Thanks for the tip on LocalToWorld, didn’t know that!
I’m still stuck one step before that. For some reason, generator.characters[textField.cursorIndex].cursorPos returns 0, 0 as for most of the characters. Some indexes return 3, 0 or 7, 0, but most of them are zero.
The Debug.Log at the end produces 0, 0 for cursor position for most characters. The extents seem correct at 890, 1402 and if I output vertex count from the generator, it’s 916.