Scale world UI with object problem -> Perspective

Hi everyone !

I have an object. Let say a cube. I want a world UI (I’m in VR I need a world UI) to fit this object.
First I put my UI in the world at the object position.
Then I scale it with the object. (I want my UI to be a scare. And one size of it have to be the length of the diagonal of the cube which contains the object)

All of that works fine. I place my UI at the object position and I scale it. No problem.
But then, I want to put my UI in front of the object. So I move it closer to my camera to be just in front of the object (obj.size.z / 2). The UI is well placed now BUT :

Since my UI is now closer to my camera, it seems bigger ! (Perspective)

I think I have to find some kind of ratio with the Camera.main.fieldOfView to resize my UI to fit the space it should… But I don’t know how.

How would you do that ?

Sounds like you’d be better off having the UI be in screen space and not world space. You can use Camera.main.WorldToScreenPoint to set the UI element’s X and Y coordinates, and the (1f / Z) from that function (distance to the point) can I think be used to scale the UI element to match its onscreen size.

I can’t use screen space canvas since i’m doing this for cardboard. Screen space canvas can’t be seen in VR. “In non-VR projects, UI is frequently overlaid on top of the screen to show things … This approach usually doesn’t work in VR - our eyes are unable to focus on something so close, and Screen Space-Overlay is not supported in Unity VR.” https://unity3d.com/fr/learn/tutorials/topics/virtual-reality/user-interfaces-vr

Ah, VR changes things.

In that case, you should be able to scale it proportionally with the distance from the camera. If D1 is the original distance and S1 is the original scale, get the new distance (D2), then it should be: S2 = (D2 / D1) * S1

1 Like

Thanks! It helped. But now it seems like my canvas is not at the good position. It seemed to be before I scaled it. Maybe another problem… My canvas seems to have the good size, but its not right in front of my object anymore.

For information, here is my code :

// GetBoxDiagonalLength gives the length between two opposite corners of the box collider. (That's the size I want my canvas to have). I scale it with transform.localScale.x because obj and my canvas do not have the same scale.
float scaledDist = obj.GetBoxDiagonalLength() / transform.localScale.x;
Vector2 newSize = new Vector2 (scaledDist, scaledDist);
_ObjectCanvas.GetComponent<RectTransform>().sizeDelta = newSize;

// GetBoxWorldCenter gives the world position of the center of the box collider of obj
_ObjectCanvas.transform.position = obj.GetBoxWorldCenter ();
float D1 = Vector3.Distance (Camera.main.transform.position, _ObjectCanvas.transform.position);
Vector2 S1 = _ObjectCanvas.GetComponent<RectTransform> ().sizeDelta;

// Here I want my canvas to be in front of the object.
Vector3 newPos = _ObjectCanvas.transform.localPosition;
newPos.z -= obj.GetBoxDiagonalLength() / transform.localScale.x / 2;
_ObjectCanvas.transform.localPosition = newPos;

float D2 = Vector3.Distance (Camera.main.transform.position, _ObjectCanvas.transform.position);
Vector2 S2 = (D2 / D1) * S1;

_ObjectCanvas.GetComponent<RectTransform> ().sizeDelta = S2;