Daniel Lip
Daniel Lip

Reputation: 11341

How can get the size of an object and add boxcollider that will cover automatic the object?

if (Selection.gameObjects.Length > 0)
        {
            interactedobjects.Clear();

            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                foreach(Transform trans in Selection.gameObjects[i].transform)
                {
                    if(trans.GetComponent<SkinnedMeshRenderer>() != null)
                    {
                        size = trans.GetComponent<SkinnedMeshRenderer>().bounds.size;
                    }
                }

                if (Selection.gameObjects[i].GetComponent<FPEInteractableActivateScript>() == null)
                {
                    if (Selection.gameObjects[i].GetComponent<BoxCollider>() == null)
                    {
                        Selection.gameObjects[i].AddComponent<BoxCollider>();
                        Selection.gameObjects[i].GetComponent<BoxCollider>().size = size;
                    }
                    Selection.gameObjects[i].AddComponent<FPEInteractableActivateScript>();
                }

                interactedobjects.Add(Selection.gameObjects[i]);
            }

            interacted = true;
        }

The object have a Skinned Mesh Renderer and I'm getting the Skinned Mesh Renderer bounds size and then set this size to the BoxCollider I'm adding to the object in this case a character. but the BoxCollider size very very small then the character size :

Not the right size

On the right in the inspector the added box collider and it's size and on the left the character and the box collider you can see it's very small box collider size in the bottom of the character.

I didn't loop all the children of children recursive but this is the only mesh renderer there is.

I want the box collider to cover automatic when added the character.

Upvotes: 0

Views: 3464

Answers (1)

derHugo
derHugo

Reputation: 90862

Your problem is:

You are setting the size of the BoxCollider BUT the object holding that BoxCollider can be scaled/rotated/translated itself. E.g. in your screenshot I can see that your object has a local scale of 0.1, 0.1, 0.1.

Also if any of the parent objects between the selected object and it's child with the SkinnedMeshRenderer is also scaled/rotated/translated against it's according parent this will also influence the actual world space result of your BoxCollider!

While Renderer.bounds returns values in absolute world-space, you are applying the BoxCollider.size in local space!

You would rather need to translate the values returned from the bounds into the local space of the object holding the collider. You can do that using Transform.InverseTransformPoint for the center position and Transform.InverseTransformVector for the size.

Somewhat like e.g.

foreach(var selectedObject in Selection.gameObjects)
{
    if (!selectedObject.GetComponent<FPEInteractableActivateScript>())
    {
        if (!selectedObject.GetComponent<BoxCollider>())
        {
            var boxCollider = selectedObject.AddComponent<BoxCollider>();

            var renderer = selectedObject. GetComponentInChildren<SkinnedMeshRenderer>(true);

            var bounds = renderer.bounds;
            // In world-space!
            var size = bounds.size;
            var center = bounds.center;

            // converted to local space of the collider
            size = boxCollider.transform.InverseTransformVector(size);
            center = boxCollider.transform.InverseTransformPoint(center);

            boxCollider.size = size;
            boxCollider.center = center;
        }

        selectedObject.AddComponent<FPEInteractableActivateScript>();
    }

    interactedobjects.Add(selectedObject);
}

Note: It could still be that the child with the renderer is rotated differently against the parent with the collider so this might needs to be dealt with as well.


Note: Typed on smartphone so can't test it but I hope the idea gets clear

Upvotes: 2

Related Questions