How can i get an ui element to point towards a position that is in world coordinates in unity?

So im trying to make an arrow point towards a position in my scene, i want to rotate the arrow to that position. I have tried to make the world position into a screen position and then subtracting the position of the arrow from that and then settig the rotation, but im having some trouble converting the rotation to make it right (or maybe i did something wrong another place). The script is attatched to the object i want it to point towards, here is my current code:

    Vector3 viewportPos = Camera.main.WorldToViewportPoint(transform.position);
    Vector2 worldObjScreenPos = new Vector2(
        (viewportPos.x * canvasRectTrans.sizeDelta.x) - (canvasRectTrans.sizeDelta.x * 0.5f),
        (viewportPos.y * canvasRectTrans.sizeDelta.y) - (canvasRectTrans.sizeDelta.y * 0.5f));

    Vector3 rot = worldObjScreenPos - arrowRectTrans.anchoredPosition;
    arrowRectTrans.rotation = Quaternion.Euler(rot);

But this gives me some weird results where the arrow starts spinning like crazy.

>Solution :

If I understand correct you want your 2D Screenspace UI point "towards" a 3D world space coordinate converted into a screen space position.

You could probably simply do

var screenPos = Camera.main.WorldToScreenPoint(transform.position);
// In a Screenspace Overlay Canvas this already comes in Screen/pixel space
var arrowPos = arrowRectTrans.position;

// Get the vector pointing from arrow towards the screenPos
// in screen/pixel space
var direction = screenPos - arrowPos;

// Simply assign the transform.up which will rotate the object 
// so that the up will match the direction
arrowRectTrans.up = direction;

This way you don’t have to deal with any complex math and Quaternion at all 😉

Leave a Reply