Skip to content

Commit 2d15f04

Browse files
authored
Update BoxColliderFitChildren.cs
fix fitting if some children are wonky
1 parent 84cf73c commit 2d15f04

File tree

1 file changed

+43
-32
lines changed

1 file changed

+43
-32
lines changed
Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Adjust Box Collider to fit child meshes inside
2-
// Usage: You have empty parent transform, with child meshes inside, add box collider to parent then use this
3-
41
using UnityEngine;
52
using UnityEditor;
63

@@ -13,48 +10,62 @@ static void FitColliderToChildren(MenuCommand command)
1310
{
1411
BoxCollider col = (BoxCollider)command.context;
1512

16-
// record undo
13+
// Record undo
1714
Undo.RecordObject(col.transform, "Fit Box Collider To Children");
1815

19-
// first reset transform rotation
20-
var origRot = col.transform.rotation;
21-
col.transform.rotation = Quaternion.identity;
16+
// Get world-space bounds of all child meshes
17+
var worldBounds = GetRecursiveMeshBounds(col.gameObject);
2218

23-
// get child mesh bounds
24-
var b = GetRecursiveMeshBounds(col.gameObject);
19+
if (worldBounds.size == Vector3.zero)
20+
{
21+
Debug.LogWarning("No valid meshes found to fit the BoxCollider.");
22+
return;
23+
}
2524

26-
// set collider local center and size
27-
col.center = col.transform.root.InverseTransformVector(b.center) - col.transform.position;
25+
// Convert world-space center to local space
26+
Vector3 localCenter = col.transform.InverseTransformPoint(worldBounds.center);
2827

29-
// keep size positive
30-
var size = b.size;
31-
size.x = Mathf.Abs(size.x);
32-
size.y = Mathf.Abs(size.y);
33-
size.z = Mathf.Abs(size.z);
28+
// Convert world-space size to local space
29+
Vector3 localSize = col.transform.InverseTransformVector(worldBounds.size);
3430

35-
col.size = b.size;
31+
// Ensure size is positive
32+
localSize = new Vector3(Mathf.Abs(localSize.x), Mathf.Abs(localSize.y), Mathf.Abs(localSize.z));
33+
34+
// Fix potential center flipping
35+
if (Vector3.Dot(col.transform.right, Vector3.right) < 0)
36+
{
37+
localCenter.x = -localCenter.x;
38+
}
39+
if (Vector3.Dot(col.transform.up, Vector3.up) < 0)
40+
{
41+
localCenter.y = -localCenter.y;
42+
}
43+
if (Vector3.Dot(col.transform.forward, Vector3.forward) < 0)
44+
{
45+
localCenter.z = -localCenter.z;
46+
}
3647

37-
// restore rotation
38-
col.transform.rotation = origRot;
48+
// Apply to collider
49+
col.center = localCenter;
50+
col.size = localSize;
3951
}
4052

4153
public static Bounds GetRecursiveMeshBounds(GameObject go)
4254
{
43-
var r = go.GetComponentsInChildren<Renderer>();
44-
if (r.Length > 0)
45-
{
46-
var b = r[0].bounds;
47-
for (int i = 1; i < r.Length; i++)
48-
{
49-
b.Encapsulate(r[i].bounds);
50-
}
51-
return b;
52-
}
53-
else // TODO no renderers?
54-
{
55-
//return new Bounds(Vector3.one, Vector3.one);
55+
Renderer[] renderers = go.GetComponentsInChildren<Renderer>();
56+
57+
if (renderers.Length == 0)
5658
return new Bounds();
59+
60+
// Start with the first renderer’s bounds in world space
61+
Bounds worldBounds = renderers[0].bounds;
62+
63+
for (int i = 1; i < renderers.Length; i++)
64+
{
65+
worldBounds.Encapsulate(renderers[i].bounds);
5766
}
67+
68+
return worldBounds;
5869
}
5970
}
6071
}

0 commit comments

Comments
 (0)