Angelin
Angelin

Reputation: 648

Getting world position to canvas position for Screen Space - Camera canvas

I'm trying to make a text display over a cube in Unity UI when I freely move my camera. The canvas is set to Screen Space - Camera mode and I set the camera property in the inspector. I have also attached a mouse move script to the camera.

My problem is that the text is barely moving and seems to ignore the position of the cube relative to the camera's viewport. Here is my code:

public class UpdateUiMarker : MonoBehaviour {

    public RectTransform element;
    public Transform cube;

    public RectTransform canvas;

    // Update is called once per frame
    void LateUpdate () {
        Vector2 screenPos = Camera.main.WorldToScreenPoint(cube.position);
        Vector2 localPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas, screenPos, Camera.main, out localPos);
        element.localPosition = localPos;
    }
}

Upvotes: 0

Views: 16547

Answers (4)

uscq answer worked for me. However, I needed to know the world position of a UI Image that was in my canvas. My canvas is using Screen Space - Camera and not Overlay. I modified uscq answer to do the opposite. Thank you so much!

    var position = UICamera.WorldToScreenPoint(MyUIObject.transform.position);
    position.z = (thisCanvas.transform.position - UICamera.transform.position).magnitude;
    theLocationOfUIObjectInWorldLocation = Camera.main.ScreenToWorldPoint(position);

Upvotes: 0

caxapexac
caxapexac

Reputation: 914

Working solution for URP (also works on deffered):

    public static Vector2 WorldPositionToScreenSpaceCameraPosition(Camera worldCamera, Canvas canvas, Vector3 position)
    {
        Vector2 viewport = worldCamera.WorldToViewportPoint(position);
        Ray canvasRay = canvas.worldCamera.ViewportPointToRay(viewport);
        return canvasRay.GetPoint(canvas.planeDistance);
    }

Upvotes: 1

uscq
uscq

Reputation: 128

First, you may have a world Camera look at the cube which stuffs as 3D objects, and then other Camera ui see your UI elements while culling off 3D objects. Last, a canvas Canvas places your UI elements. Then, you could code like this:

var screen = world.WorldToScreenPoint(cube.transform.position);
screen.z = (canvas.transform.position - ui.transform.position).magnitude;
var position = ui.ScreenToWorldPoint(screen);
element.position = position; // element is the Text show in the UI.

Upvotes: 5

Mabakay
Mabakay

Reputation: 338

void LateUpdate () {
        element.anchoredPosition = Input.mousePosition;
    }

And set anchors of element to Vector2.zero for min and max.

Upvotes: -1

Related Questions