How to position offscreen arrow indicators?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By bobbydickins

I am making a 3D space shooter and I am having trouble figuring out how to make arrow icons that point in the direction of an offscreen enemy (similar to how no man’s sky does it).

The godot “waypoints” demo project is a good starting point but it doesn’t take into account the z rotation that a ship would normally have. I haven’t found any solutions after googling for a while and it’s a hard concept for me to grasp.

I know that I need to unproject the enemy’s translation but if the enemy is offscreen I’m not sure how to make it so the arrow points in the proper direction.

:bust_in_silhouette: Reply From: Andrea

camera.unproject_position(point) gives you the screen coordinate of a 3D point seen by the camera.
You can easily make an arrow that look at that point when this coordinates are offscreen.
EG:

var point=camera.unproject_position(ship.translation)
if point.x<0 or point.y<0 or point.x>get_viewport().size.x or point.y>get_viewport().size.y:
  arrow.show() 
  positionate_arrow(point)
  arrow.look_at(point)

now you should define a positionate_arrow function to place it on the border of the screen, cant think about anything smart right now, but hopefully you got the point.
if placing the arrow on a circle around the center of the screen is enough for you (as it seems is enough for no man sky), you can go with

 func positionate_arrow(point):
  var circle_radius=min(get_viewport().size.x, get_viewport().size.y)/2
  arrow.position=get_viewport.size()/2+circle_radius*(point-get_viewport().size/2).normalized()