- Home /
Bounds vs BoxCollider producing different sizes when provided same values?
I've been working in Unity to build a tool that can read data from a natively unsupported model format.
One of the things this format does is have its bounding boxes connected to the bones. Unity does not support putting Bounds directly onto transforms, so I compromised by using BoxColliders instead. Now here's where things have gotten confusing for me.
I have an array of Bounds that the values are read into (this format lists the maximum and minimum values of the bounding boxes):
for(int i = 0; i < bounds.Length; i++)
{
bounds[i].SetMinMax(new Vector3(fmdl.GetSection0BlockDEntries()[i].minZ, fmdl.GetSection0BlockDEntries()[i].minY, fmdl.GetSection0BlockDEntries()[i].minX), new Vector3(fmdl.GetSection0BlockDEntries()[i].maxZ, fmdl.GetSection0BlockDEntries()[i].maxY, fmdl.GetSection0BlockDEntries()[i].maxX));
} //for
From there, I assign them to the BoxColliders using the center and size values:
BoxCollider collider = bones[i].gameObject.AddComponent<BoxCollider>();
collider.center = bounds[fmdl.GetSection0Block0Entries()[i].boundingBoxId].center;
collider.size = bounds[fmdl.GetSection0Block0Entries()[i].boundingBoxId].size;
Everything seems to work well for the most part. The layout of the boxes is correct, but the BoxColliders are too big:
I thought that maybe the bones were getting layed out incorrectly; But they are not. Here are the bones compared to the BoxColliders:
And even more interesting, if the same Bounds that I've been using the sizes from to create the BoxColliders are applied as the meshes' bounds, their size is correct (not all of the bounds get applied because the bounding boxes are meant to be applied to the bones):
mesh.bounds = bounds[i];
So my question is, what's going on with the BoxColliders? Why are they so big when the same values applied to the meshes' bounds are the correct size? Is there anything I can do to fix this? Thanks in advance.
Answer by BobDoleOwndU · Oct 03, 2017 at 10:08 AM
Found the solution. It was a global vs local issue.
When the bounds are applied to mesh.bounds, they are applied in local space, which puts them at the correct size.
When they're applied to the BoxColliders, it applies them in global space, which is why they were over sized.
The solution was to set the position in local space to the bone by doing:
collider.center = bounds[fmdl.GetSection0Block0Entries()[i].boundingBoxId].center - bones[i].position;
This solution will only work without differing scales, which in my case, there weren't any.
Edit:
A better solution is:
collider.center = bones[i].InverseTransformPoint(bounds[fmdl.GetSection0Block0Entries()[i].boundingBoxId].center);
which handles scales as well.
Answer by Runemark · Sep 28, 2017 at 01:15 PM
The images doesn't really help to find the problem, but I think this happens becouse of scaling, more specifically relative scaling.
When you are assigning the bounds, you use relative positions (relative to the mesh), but the mesh has different scaling (maybe becouse it's exported from the modelling software with a scale different of 1 unit = 1 meter).
Solution should be either changing the imported mesh scale (native import has a scale value), or converting the bound positions to global (using the scale difference).
Hope it helps to figure out what's the problem here!
Hello! Thanks for the reply.
So just to clarify, you're saying to scale the mesh up to the same size as the bounding boxes, or to scale the bounds down to the size of the meshes, using the scale difference? Is there an easy way to go about finding the scale difference?
For reference, I haven't touched the scales anywhere in Unity. All meshes, bone transforms, etc... are created in Unity with the default scales Unity uses.
I was thinking of scaling down the colliders.
Also I found something else, that might be a problem: Are you using mesh.bounds or renderer.bounds for getting the information out?
Collider.bounds is world space bounding volume.
$$anonymous$$esh.bounds is local bounding volume
Renderer.bounds is the same as mesh.bounds but in world space coords
You should assign Renderer.bounds to Collider.bounds if I understand this correctly.
In the bottom image I posted, where the sizes are correct, the bounds were applied as
mesh.bounds = bounds[i];
You can't directly set a collider's bounds, as its bounds property is read only. So I set it by doing this:
collider.center = bounds[fmdl.GetSection0Block0Entries()[i].boundingBoxId].center;
collider.size = bounds[fmdl.GetSection0Block0Entries()[i].boundingBoxId].size;
For getting the information out, I'm just using the BoxColliders.
Your answer
Follow this Question
Related Questions
How Does OnTriggerEnter() Work? 0 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Procedural object generation, objects overlap each other 1 Answer
Remove objects from list when they are out of range. 0 Answers