I’ve been having issues where when the object is rotated (even with a 1,1,1 scale and no parent) Bounds.Contains() is returning true when the point isn’t in the bounds.
I thought maybe I had a bug in my code so I wrote a test script - literally 1 line - and the error persists.
Here is the full code of my test script
using UnityEngine;
public class test : MonoBehaviour {
public bool TEST;
public GameObject point;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
TEST = gameObject.GetComponent<Collider>().bounds.Contains(point.transform.position);
}
}
Bounds is an AABB - axis aligned bounding box. It’s defined exclusively by the center and extents, and hold no information about the rotation of the object. For a collider, the .bounds is the smalles axis alligned box that contains the entire collider.
AABBs are used for rough spatialization of things. It’s much faster to check if two axis aligned boxes are overlapping than two general boxes.
If you want to know if something is inside of your box, you’ll have to do the math yourself. If you’re working with other colliders, you could use an OverlapBox check.
I have used it before and it usually works just fine even if rotated, I also tried this code and the issue persisted
using UnityEngine;
public class test : MonoBehaviour {
public bool TEST;
public GameObject point;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
TEST = gameObject.GetComponent<Collider>().bounds.Intersects(point.GetComponent<Collider>().bounds);
}
}
It literally says in the docs that it’s not rotated. If you used it before, you just didn’t notice the bug.
Here’s a script you can add to a GameObject to draw the current bounds for a Collider or Renderer as gizmos. Then you can see the behaviour of the bounds as you rotate the object.
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class DrawBoundsGizmos : MonoBehaviour {
#if UNITY_EDITOR
public enum ColliderOrRenderer {
Collider,
Renderer
}
public enum DrawWhen {
Always,
Selected,
ParentSelected
}
public ColliderOrRenderer type;
public DrawWhen drawWhen;
private static readonly Vector3 gizmosSize = Vector3.one * .1f;
public void OnDrawGizmosSelected() {
if (drawWhen == DrawWhen.ParentSelected) {
DrawGizmos();
} else if (drawWhen == DrawWhen.Selected && Selection.activeTransform == transform) {
DrawGizmos();
}
}
private void OnDrawGizmos() {
if (drawWhen == DrawWhen.Always) {
DrawGizmos();
}
}
private void DrawGizmos() {
try {
Bounds B = type == ColliderOrRenderer.Renderer ? GetComponent<Renderer>().bounds : GetComponent<Collider>().bounds;
DrawGizmosFor(B);
}
catch {
// nothing to draw the bounds of!
}
}
public static void DrawGizmosFor(Bounds B) {
var xVals = new[] {
B.max.x, B.min.x
};
var yVals = new[] {
B.max.y, B.min.y
};
var zVals = new[] {
B.max.z, B.min.z
};
for (int i = 0; i < xVals.Length; i++) {
var x = xVals[i];
for (int j = 0; j < yVals.Length; j++) {
var y = yVals[j];
for (int k = 0; k < zVals.Length; k++) {
var z = zVals[k];
var point = new Vector3(x, y, z);
Gizmos.DrawCube(point, gizmosSize);
if (i == 0) {
Gizmos.DrawLine(point, new Vector3(xVals[1], y, z));
}
if (j == 0) {
Gizmos.DrawLine(point, new Vector3(x, yVals[1], z));
}
if (k == 0) {
Gizmos.DrawLine(point, new Vector3(x, y, zVals[1]));
}
}
}
}
}
#endif
}
Huh, I guess you’re right - and that’s a neat little script thanks
I actually just wrote my own script for checking the bounds
It requires you to do all the transformations (centre, scale etc) on the parent gameobject rather than the collider component (so the collider centre is 0,0,0 and scale is 1,1,1) but that’s fine for me and it works great.
I know this is a very old post, but I just wanted to say: Joe Patrick, lots of thanks for this awesome script, it’s a pretty simple solution but very elegant and it works great!
var box = gameObject.GetComponent<BoxCollider>();
var found = TransformBoxContainsPoint(box.transform, box.center, box.size, testObject.transform.position);