Skip to content

Instantly share code, notes, and snippets.

@jhocking
Created February 10, 2021 15:57
Show Gist options
  • Save jhocking/e64a5abdcae9b294f02cec56e26fb14b to your computer and use it in GitHub Desktop.
Save jhocking/e64a5abdcae9b294f02cec56e26fb14b to your computer and use it in GitHub Desktop.
Create a BoxCollider that surrounds an object and its children
// https://gamedev.stackexchange.com/questions/129116/how-to-create-a-boxcollider-which-surrounds-the-gameobject-and-all-of-his-child
private void AddColliderAroundChildren(GameObject assetModel)
{
var pos = assetModel.transform.localPosition;
var rot = assetModel.transform.localRotation;
var scale = assetModel.transform.localScale;
// need to clear out transforms while encapsulating bounds
assetModel.transform.localPosition = Vector3.zero;
assetModel.transform.localRotation = Quaternion.identity;
assetModel.transform.localScale = Vector3.one;
// start with root object's bounds
var bounds = new Bounds(Vector3.zero, Vector3.zero);
if (assetModel.transform.TryGetComponent<Renderer>(out var mainRenderer))
{
// as mentioned here https://forum.unity.com/threads/what-are-bounds.480975/
// new Bounds() will include 0,0,0 which you may not want to Encapsulate
// because the vertices of the mesh may be way off the model's origin
// so instead start with the first renderer bounds and Encapsulate from there
bounds = mainRenderer.bounds;
}
var descendants = assetModel.GetComponentsInChildren<Transform>();
foreach (Transform desc in descendants)
{
if (desc.TryGetComponent<Renderer>(out var childRenderer))
{
// use this trick to see if initialized to renderer bounds yet
// https://answers.unity.com/questions/724635/how-does-boundsencapsulate-work.html
if (bounds.extents == Vector3.zero)
bounds = childRenderer.bounds;
bounds.Encapsulate(childRenderer.bounds);
}
}
var boxCol = assetModel.AddComponent<BoxCollider>();
boxCol.center = bounds.center - assetModel.transform.position;
boxCol.size = bounds.size;
// restore transforms
assetModel.transform.localPosition = pos;
assetModel.transform.localRotation = rot;
assetModel.transform.localScale = scale;
}
@fmatulic
Copy link

Tried that code but the calculated collider's geometry doesn't fit the encapsulated children when the parent of assetModel has modified position, rotation or scale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment