Scale a game object to Bounds
        Posted  
        
            by 
                Spikeh
            
        on Game Development
        
        See other posts from Game Development
        
            or by Spikeh
        
        
        
        Published on 2014-06-02T14:23:01Z
        Indexed on 
            2014/06/02
            16:01 UTC
        
        
        Read the original article
        Hit count: 438
        
I'm trying to scale a lot of dynamically created game objects in Unity3D to the bounds of a sphere collider, based on the size of their current mesh. Each object has a different scale and mesh size. Some are bigger than the AABB of the collider, and some are smaller. Here's the script I've written so far:
private void ScaleToCollider(GameObject objectToScale, SphereCollider sphere) {
    var currentScale = objectToScale.transform.localScale;
    var currentSize = objectToScale.GetMeshHierarchyBounds().size;
    var targetSize = (sphere.radius * 2);
    var newScale = new Vector3 {
        x = targetSize * currentScale.x / currentSize.x,
        y = targetSize * currentScale.y / currentSize.y,
        z = targetSize * currentScale.z / currentSize.z
    };
    Debug.Log("{0} Current scale: {1}, targetSize: {2}, currentSize: {3}, newScale: {4}, currentScale.x: {5}, currentSize.x: {6}",
        objectToScale.name, currentScale, targetSize, currentSize, newScale, currentScale.x, currentSize.x);
    //DoorDevice_meshBase                   Current scale: (0.1, 4.0, 3.0), targetSize: 5, currentSize: (2.9, 4.0, 1.1), newScale: (0.2, 5.0, 13.4), currentScale.x: 0.125, currentSize.x: 2.869114
    //RedControlPanelForAirlock_meshBase    Current scale: (1.0, 1.0, 1.0), targetSize: 5, currentSize: (0.0, 0.3, 0.2), newScale: (147.1, 16.7, 25.0), currentScale.x: 1, currentSize.x: 0.03400017
    objectToScale.transform.localScale = newScale;
}
And the supporting extension method:
public static Bounds GetMeshHierarchyBounds(this GameObject go) {
    var bounds = new Bounds(); // Not used, but a struct needs to be instantiated
    if (go.renderer != null) {
        bounds = go.renderer.bounds;
        // Make sure the parent is included
        Debug.Log("Found parent bounds: " + bounds);
        //bounds.Encapsulate(go.renderer.bounds);
    }
    foreach (var c in go.GetComponentsInChildren<MeshRenderer>()) {
        Debug.Log("Found {0} bounds are {1}", c.name, c.bounds);
        if (bounds.size == Vector3.zero) {
            bounds = c.bounds;
        } else {
            bounds.Encapsulate(c.bounds);
        }
    }
    return bounds;
}
After the re-scale, there doesn't seem to be any consistency to the results - some objects with completely uniform scales (x,y,z) seem to resize correctly, but others don't :|
Its one of those things I've been trying to fix for so long I've lost all grasp on any of the logic :| Any help would be appreciated!
© Game Development or respective owner