UI.Root Text vs Text3D


In a Urho3D 3D game, if you need to write over a game character its name, I guess there are two solutions:

  • use Text3D to write the name of the character and manage to get the text facing the camera
  • get the 2D coordinates of the character in the UI and write the name over the character.

I don’t do a game but I need to write the name of the stars over each star.
What would be the easiest solution?
What is the easiest way to get the 2D coordinates of the star in the UI rectangle (and to know if the star is in the field of the camera)?


For the UI approach you can use the following function of the camera:

/// Convert a world space point to normalized screen coordinates (0 - 1).
Vector2 WorldToScreenPoint(const Vector3& worldPos) const;

If you multiply this by GetSubsystem<Graphics>()->GetSize() you should have the required position for placing your UI element.


And also, I guess we also need to sort the UI “billboard” according to their distance to the main camera.

…which Text3D would take care of for you, I guess. You’ll probably want to SetFixedScreenSize(true) if you use that component.

Hi @Modanung

I can get the Vector2D in C#:

IntVector2 v2 = viewPort.WorldToScreenPoint(bbi.Position);

But do you have any idea how to GetSubsystem()->GetSize() in C#?

I tried that:

            var graphics = GetSubsystem<Graphics>();

But GetSubsystem is non generic in urhosharp :frowning:

I hope you are not in trouble with COVID-19.


Sorry for this question.
I think the solution is that one:

Urho.BillboardWrapper bbi;
                bbi = StarsBbs.GetBillboardSafe(i);
                IntVector2 v2 = viewPort.WorldToScreenPoint(bbi.Position);
                IntVector2 v2TextPosition = new IntVector2(v2.X * graphics.Width, v2.Y * graphics.Height);

Is this what you mean by "multiply this by GetSubsystem<Graphics>()->GetSize()"?

Yesterday was the worst it seems. I’m feeling a lot better already, but thanks for your concern. :slightly_smiling_face:

This is only required when using Camera::WorldToScreenPoint (which should be named Pos, and not Point, in my opinion), Viewport::WorldToScreenPoint already does this multiplication.

Well, the text seems not to be at the right position on the attached png

Where I don’t multiply:

            var graphics = Graphics;
            Urho.BillboardWrapper bbi;
            for(uint i=0; i< (uint)App.StarsData.Count; i++)
                bbi = StarsBbs.GetBillboardSafe(i);
                IntVector2 v2 = viewPort.WorldToScreenPoint(bbi.Position);

        private void WriteStarName(IntVector2 v2)
            var text = new Text()
                Value = "star",
                Position = v2
            text.SetFont(font: ResourceCache.GetFont("Fonts/Anonymous Pro.ttf"), size: 10);

Try getting it right with a single star first.

You are right.
And moreover, the positions of the names are the same whatever the size of the window. So I have to update the positions after the window is set…
I will find out that tomorrow.
Thanks for your help.

When using Text3D you would not have to update their position separately. With UIElements you’ll probably want your stars to keep a reference to their label.

I am trying that for the cardinal points but it is very difficult to keep the text facing the camera. I still not have succeded. But if I succeed, I could do the same for the stars.

I did it. It seems a little bit slow though. I will try to optimize that.
I have to find a font compatible with greek characters.

1 Like

I think some of the libre office fonts would include them, though I’m not sure what their licenses are (fonts like liberation serif)

Hi @SirNate0,
The first issue was that I was using UTF-16. First I converted my strings to UTF-8. But there are still some greek characters that don’t print. Unfortunately, no chinese characters printed.
I go on with the english names…