Reputation: 11341
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 :
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
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