I wanted to draw a bounding box of some UI elements when in editor, regardless of their orientation.
The easiest way I found that completely handles all cases of nesting, rotation, scaling, anchor offsets, etc. was to use [RectTransform.GetWorldCorners][1] and manually compute the Bounds:
private static Vector3[] WorldCorners = new Vector3[4];
public static Bounds GetRectTransformBounds(RectTransform transform)
{
transform.GetWorldCorners(WorldCorners);
Bounds bounds = new Bounds(WorldCorners[0], Vector3.zero);
for(int i = 1; i < 4; ++i)
{
bounds.Encapsulate(WorldCorners*);*
}
return bounds;
}
----------
Since calls that require a Rect typically are defined as existing on the XY plane (such as [Gizmos.DrawGUITexture][2]), computing a rect from the bounds is trivial.
Here is an example:
private static Texture2D MakeTexture(float opacity)
{
Texture2D texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, true);
texture.SetPixel(0, 0, new Color(1, 0, 0, opacity));
texture.SetPixel(0, 1, new Color(0, 1, 0, opacity));
texture.SetPixel(1, 0, new Color(0, 0, 1, opacity));
texture.SetPixel(1, 1, new Color(1, 1, 1, opacity));
texture.Apply();
texture.filterMode = FilterMode.Point;
return texture;
}
public float opacity = 0.5f;
private Texture2D tex = null;
private void OnValidate() => tex = MakeTexture(opacity);
private void Awake() => tex = MakeTexture(opacity);
private void OnDrawGizmos()
{
Bounds bounds = GetRectTransformBounds(transform as RectTransform);
Rect screenRect = new Rect(bounds.min, bounds.size);
Gizmos.DrawGUITexture(screenRect, tex);
}
And the result:
![alt text][3]
[1]: Unity - Scripting API: RectTransform.GetWorldCorners
[2]: Unity - Scripting API: Gizmos.DrawGUITexture
[3]: https://i.imgur.com/dmCLPda.gif