I'm trying to wrap my head around what appears to be quite a simple problem.
I want to get four points around a game object. The object may be made up of multiple child primitives such as cylinders and boxes. I should point out that the parent object does not have a renderer. Here's an illustration:
I am able to get the four points by iterating the children's renderers, and encapsulating their bounds like so.
private Bounds GetBounds()
{
var renderers = GetComponentsInChildren<Renderer>();
Bounds bounds = renderers[0].bounds;
for (int i = 1; i < renderers.Length; i )
bounds.Encapsulate(renderers[i].bounds);
return bounds;
}
The problem with this method is that bounds do not take into account rotation. I'd like the points to track the points on the game object regardless of rotation.
I had also considered placing a number of game objects within the prefab which served as each point, but I'd like to be able to do this programmatically.
CodePudding user response:
If I understand correctly you are looking for those min/max bounds points regardless of the parent objects orientation.
One general "issue" with the bounds is that they will always be world axis aligned.
So what you could do is
store parents rotation
var rotation = transform.rotation;
reset parents rotation
transform.rotation = Quaternion.identity;
now calculate the bounds
var renderers = GetComponentsInChildren<Renderer>(); var bounds = renderers[0].bounds; for (int i = 1; i < renderers.Length; i ) bounds.Encapsulate(renderers[i].bounds);
calculate the points (from the image I assumed XY for now but you can adjust accordingly)
Vector2 center = bounds.center; Vector2 min = bounds.min; Vector2 max = bounds.max; Vector2 left = center: left.x = min.x; Vector2 right = center; right.x = max.x; Vector2 top = center; top.y = max.y; Vector2 bottom = center; bottom.y = min.y;
convert them into local space of the parent
left = transform.InverseTransformPoint(left); right = transform.InverseTransformPoint(right); top = transform.InverseTransformPoint(top); bottom = transform.InverseTransformPoint(bottom);
apply rotation back to parent
transform.rotation = rotation;
convert again into world space (if needed at all)
left = transform.TransformPoint(left); right = transform.TransformPoint(right); top = transform.TransformPoint(top); bottom = transform.TransformPoint(bottom);
This way you get clean(er) world space bound positions, always calculated in a world axis aligned space but then rotated back to the actual orientation of the parent