Namek Dev
a developer's log
NamekDev

Unity - is this point within a box?

April 19, 2014

I am currently using Unity for two weeks and I have started to implement logic and graphical tweaks into mechanics. It happened that I needed a little math to correct some calculation failures based on user mouse or touch input. A simple check was needed - is a given 3D point contained within a box?

I was pretty disappointed that Unity does not have such functions already made. And even more disappointed I couldn’t find ready solution for Unity-specific library code. Actually many folks use Physics.Raycast() instead which is ugly. The sad fact is that many creators do not have any idea what they are doing by using Raycast.

Below you can see the code for such point-box check. If you need it, figure it out yourself how it works.

public class IsPointInBoxTest : MonoBehaviour {
    Transform _box;
    Transform _point;

    void Start () {
        _box = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
        _point = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
        _point.localScale = new Vector3(0.1f, 0.1f, 0.1f);

        testPointInBox(new Vector3(0, 10, 0), new Vector3(1,1,1), Quaternion.AngleAxis(30, Vector3.up), new Vector3(0, 9.56f, 0));
        testPointInBox(new Vector3(0, 10, 0), new Vector3(1,1,1), Quaternion.AngleAxis(30, Vector3.up), new Vector3(0.49f, 10, 0.49f));
        testPointInBox(new Vector3(0, 10, 0), new Vector3(1,1,1), Quaternion.AngleAxis(0, Vector3.up), new Vector3(0.49f, 10, 0.49f));
    }

    private void testPointInBox(Vector3 boxPosition, Vector3 boxSize, Quaternion boxRotation, Vector3 testPoint) {
        _box.position = boxPosition;
        _box.rotation = boxRotation;
        _box.localScale = boxSize;
        _point.position = testPoint;

        Debug.Log(IsPointInBox(boxPosition, boxSize, boxRotation, testPoint).ToString());
    }

    public static bool IsPointInBox(Vector3 boxPosition, Vector3 boxSize, Quaternion boxRotation, Vector3 testPoint) {
        var localPoint = testPoint - boxPosition;
        var rotatedPoint = Quaternion.Inverse(boxRotation) * localPoint;

        return IsPointInBox(boxSize, rotatedPoint);
    }

    public static bool IsPointInBox(Vector3 boxPosition, Vector3 boxSize, Vector3 testPoint) {
        var localPoint = testPoint - boxPosition;

        return IsPointInBox(boxSize, localPoint);
    }

    public static bool IsPointInBox(Vector3 boxSize, Vector3 testPoint) {
        return Mathf.Abs(testPoint.x) < boxSize.x/2
            && Mathf.Abs(testPoint.y) < boxSize.y/2
            && Mathf.Abs(testPoint.z) < boxSize.z/2;
    }
}
csharp, gamedev, unity3d
comments powered by Disqus