Created
February 10, 2021 15:57
-
-
Save jhocking/e64a5abdcae9b294f02cec56e26fb14b to your computer and use it in GitHub Desktop.
Create a BoxCollider that surrounds an object and its children
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.