Problem with camera.WorldToViewportPoint

I have two points in world coordinates and basically I am trying to draw GUI.BOX around these two points with following code

P1=Vector3(x1, y1, z1);
P2=Vector(x2, y1, z2);

var P1Screen=cam.WorldToScreenPoint(P1);
var P2Screen=cam.WorldToScreenPoint(P2);

Gui.Box(P1.x, P1.y, P2.x-P1.x, P2.y-P1.y);

however result is not coming as expected, The Gui.box is not freezed to the world point when I move my first person camera(cam here) around. I have been banging my head over it for last few hours but couldn’t get it working.

Please help. Thanks in advance.

I know it’s an old question, but since it shows up in google I will answer it anyway for future reference:

WorldToViewportPoint doesn’t gives you a suitable coordinate for GUI objects.

You will want to use Camera.WorldToScreenPoint instead or multiply WorldToViewportPoint by Screen.Width and Screen.Height to have it in pixels instead of normalized values.
(and you will probably need to reverse the Y position too using “Screen.Height-Y” )

Note this is for the legacy Unity GUI, now renamed “Immediate Gui” in Unity 5.4
For the new Unity UI you can use WorldToViewportPoint since it uses normalized coordinates. (0 to 1)

A single transform is not enough. You need to transform from 3D world space to main camera’s screenspace (mainCam.WorldToScreenPoint). After that you need to transfer from screen space to UI camera’s world space (uiCam.ScreenToWorldPoint). Now you need to inverse transform this point by your widget’s parent: (widget.transform.parent.InverseTransformPoint). Now you can set the widget’s local position to this value.