2
\$\begingroup\$

Godot has the distance_to methods for Vector3 and Vector2 but what would be the best way to get the distance from a 3d node to a 2d node? For example, I'm looking to see how far away the 3d kinematic body is from a 2d text label.

Currently, I'm trying something like:

var player_global_origin = player.global_transform.origin
var player_vec2 = Vector2(player_global_origin.z, player_global_origin.x)

var distance_to_label = player_vec2.distance_to(label.get_global_transform().origin)

Which seems to work ok when just moving forwards and backwards but it feels like it's easy to break.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Do you want the distance on screen (which depends on the 3D camera)? \$\endgroup\$
    – Theraot
    May 31 at 18:03
  • \$\begingroup\$ @Theraot I think so. I just need to change the size of the text depending on the distance of the player. \$\endgroup\$ May 31 at 18:13
  • \$\begingroup\$ If the label is tied to something in the world (e.g. it represent what an NPC says), you can use the position of that something in the world to compute the distance. \$\endgroup\$
    – Theraot
    May 31 at 18:16
1
\$\begingroup\$

If you want the position of a 3D object on screen, you can do the following:

var position_2d = get_viewport().get_camera().unproject_position(position_3d)

That is, we use the camera projection to get the 3D position into screen coordinates with Camera.unproject_position which takes a Vector3 and returns Vector2. Why is that unproject and not project? Don't know.

However, we need a Camera to do that. Luckily Viewport.get_camera returns the current 3D Camera. Why is there not a 2D counterpart? Don't know.

And of course, to use get_camera we need a Viewport. We can get the Viewport the node belongs to with Node.get_viewport.


Of course, once you have the 2D position on the screen, you can use distance_to to find the distance to any Control on the screen, or whatever you need.

You can also use this to have a control follow a 3D object. This example is from the official documentation:

control.visible = not get_viewport().get_camera().is_position_behind(global_transform.origin)
control.rect_position = get_viewport().get_camera().unproject_position(global_transform.origin)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.