Detect Object is below another Object

I am trying to detect if my camera transform falls below/underneath the XZ plane of a target gameobject. This is what I have:

Vector3 targetDir = target.position - transform.position;
Vector3.Angle(target.forward, targetDir);

However, this will always return a positive float, nothing negative… I think I am close. Can someone help me please.

try this script. I wrote it without trying so there might be some sintax mistakes but i think it should do the trick

public var object1 : Transform;
public var object2 : Transform;

function objectsOverlap( t : Transform, t2 : Transform ) {
	var result = false;
	
	var pos = Rect( t.position.x - (t.localScale.x / 2), t.position.z - ( t.localScale.z / 2), t.localScale.x, t.localScale.z );
	var pos1 = Rect( t2.position.x - (t2.localScale.x / 2), t2.position.z - ( t2.localScale.z / 2), t2.localScale.x, t2.localScale.z );
	result = pos.Contains(Vector2(t2.position.x, t2.position.z ));
	return result;
}

function Update () {
    if ( objectsOverlap( object1, object2 ) ) {
          if ( object1.position.y > object2.position.y) {
                //object1 is over object2
          } else {
               //object2 is over object1
          }
     }
}

If you’re fine by just basing it off the position property, you almost have it. Do note, what I’m about to get into defines if the origin (the 0,0,0 point INSIDE the gameobject) is above or below another. If this point is in a weird place relative to some mesh in the gameobject… well it won’t pay attention to said mesh. In this case, you should maybe use bounds and base it off that… or use the collision system which is even more precise. But they’re just basically the same mathematical concept I’m going to cover, just on a more granular level that compensates for the location of any meshes.

Vector3.Angle gives the closest angle between two vectors. It’s based off of the definition of a dot product.

a dot b = ||a||*||b||*cos(theta)
//where theta is the angle between a and b
// ||a|| means ‘magnitude of a’

it can be reversed to be

acos(a dot b / (||a||*||b||)) = theta
//this is essentially what Vector3.Angle does

Anyways, dot products are nice in that they measure a vector projected onto another vector:

The result is a scalar (number) that represents the length of that |------------------|.

If that length is negative it points the opposite direction of the other.

SO, the XZ plane is defined with the plane normal of <0,1,0> (const in unity is Vector3.up).
So we can project onto this normal a vector pointing from A to B. (not the same A and B in that image, A is one transform, B is the other)

If the result is positive, then the vector is pointing near the same direction as up, so it’s pointing upward, which means B is above A.
If the reuslt is negative, then the vector is pointing in the near opposite direction of up, so it’s pointing downward, which means B is below A.

//returns the transform who is above the other
//3rd optional param to define up, in case you're in a world where up changes
public static Transform FindWhoIsAbove(Transform a, Transform b, Vector3 up = Vector3.up)
{
    return (Vector3.Dot(b.position - a.position, up) <= 0) ? a : b;
}

reference to dot product:
http://en.wikipedia.org/wiki/Dot_product

Aww… thank you lordofduct, I will have to look into this Dot stuff. I assume I will be using it a lot more in my coming project.

Thanks for your time and help! :smile:

Granted I’m tired and may be missing something obvious, but based on the title…

transform.position.y < target.position.y ?

yes, that would work

but that works for only one plane, I wanted to get into the answer for more than one