Saiaku
March 12, 2019, 3:50pm
1
I have a GameObject consisting of several children.
Each child holds another set of children that contain actual meshes, but the general shape of the total object can be summed up to a box (think, chest body and lid with meshes for wood and decor).
I haven’t been able to find a way to scale the boxcollider to represent the full size of the parent gameobject in world space. A lot of the answers I find solve similar issues with a Renderer component which seems deprecated.
What should I do here?
(this must be added and scaled dynamically)
Saiaku
March 12, 2019, 5:55pm
2
Thanks to @RobAnthem who led me onto the right tracks.
Here is the solution:
The parent sets up the children by calling something like
SetCollidersFrom<BoxCollider>(m_Body, m_Rotater.GetContainer());
which does
public void SetCollidersFrom<CollType>(params GameObject[] from) where CollType : Collider
{
if (!m_UseCollider) { return; }
if (from == null) { Debug.LogWarning("<color=" + DebugColor + ">" + DebugName + "SetCollidersFrom -> Invalid parameters.</color>"); return; }
int added = 0;
List<MeshRenderer> meshrend = new List<MeshRenderer>();
List<Bounds> boundsForEach = new List<Bounds>();
Bounds totalBounds = new Bounds();
int index = 0;
foreach (GameObject go in from)
{
if (!BlacklistedNames.Any(go.name.Contains))
{
var bounds = _GetChildRendererBounds(go);
boundsForEach.Add(bounds);
totalBounds.Encapsulate(bounds);
}
}
foreach(GameObject go in from)
{
if (typeof(CollType) == typeof(BoxCollider))
{
BoxCollider bc = go.AddComponent<BoxCollider>();
bc.enabled = true;
bc.size = (boundsForEach[index].size * 2) * m_ColliderPadding;
bc.center = new Vector3(0f, (bc.size.y / 2), 0f);
added++;
index++;
}
}
if (added > 0)
{
Debug.Log("<color=" + DebugColor + ">" + DebugName + added.ToString() + " colliders set.</color>");
}
}
which uses helper function:
private Bounds _GetChildRendererBounds(GameObject go)
{
var renderers = go.GetComponentsInChildren<Renderer>();
if (renderers.Length > 0)
{
Bounds bounds = renderers[0].bounds;
foreach (var rend in renderers)
{
if (!BlacklistedNames.Any(rend.gameObject.name.Contains))
{
bounds.Encapsulate(rend.bounds);
}
}
return bounds;
}
else { return new Bounds(); }
}
And the result: