Trouble with sizing object from world to screenpoint

Hi Folks,

I’ve seen posts regarding getting the size of an object (Eric5h5 has provided good solutions), however I don’t believe that I have my answer yet.

I need to determine the size of the face of an object, how wide and how tall in screen points. I’ll then use those dimensions to size a GUI.Box.

Here is my attempt at implementing Eric’s solution to get the size information of the GameObject called “mem_storage_opaque”:

	var go : GameObject = GameObject.Find("mem_storage_opaque");
	var m3 : Vector3;
	var mf : MeshFilter;
	mf = go.GetComponent(MeshFilter) as MeshFilter;
	m3 = mf.sharedMesh.bounds.size; 
	Debug.Log("mesh * localScale     = " + m3.x * go.transform.localScale.x + " : " + m3.y * go.transform.localScale.y);	

This gives the following output mesh * localScale = 1.218381 : 1.44

I’m not sure how to convert this to information that I can use in the guibox Rect. I hard coded some test data for the GUI.Box and it’s width/height is roughly 100/100. My current screen width/height is 1920/950 (a weird size no doubt since it’s running in the Unity game engine not stand alone).

I’m obviously missing something.

Thank you

By .size I assume you are talking about Mesh.bounds.size. This is the local size of the bounds of the mesh in world units. That is it is the size of the bounding box when the object is not rotated and before scaling is applied. You can calculate the world size by:

var theSize = Vector3.Scale(mesh.bounds.size, transform.localScale);

I’ve hesitated to give an answer, and this can be a complicated problem. It depends on the relationship of the object to the camera and what you mean by “face.” The size/bounds of an object depends on many factors:

  • Field of view of the camera
  • Position on the screen
  • Rotation of the object with respect to the camera
  • Distance from the camera
  • Scaling of the object

For example, in this image, all the cubes are 1x1x1 and at ‘Z’ = 0. I’ve dramatically increased the field of view of the camera to make the problem obvious, though it occurs to a greater or lesser extent at all field of view values if the camera is perspective:

alt text

As for your size conversion, you can only make it work if:

  • The face of the object is at a known distance from the camera
  • The face of the object is parallel to the plane of the camera
  • The object is not rotated (i.e. the mesh.bounds is aligned with the camera rotation).

If this is the case, then you can create a mapping. If the face of your object was at ‘Z = 0’ for example, and your camera was axes aligned and pointed at positive ‘Z’, you could do:

var lowerLeft = Vector3(-0.5, -0.5, 0.0);
var upperRight = Vector3(0.5, 0.5, 0.0);

lowerLeft = Camera.main.WorldToScreenPoint(lowerLeft);
upperRight = Camera.main.WorldToScreenPoint(upperRight);

horzPixelsPerWorldUnit = upperRight.x - lowerLeft.x;
vertPixelsPerWorldUnit = upperRight.y - lowerLeft.y;

The more general solutions is to take all eight points of the mesh.bounds, convert them to world coordinates (Transform.TransformPoint()), find the screen coordinates (Camera.WorldToScreenPoint()), and then take the minimum and maximum values for both x and y to construct the rectangle that bounds the object.