How do I tell if an object is in front or behind another object in 3D

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sionco
:warning: Old Version Published before Godot 3 was released.

I have a 3D object (an enemy) and I want to tell if the player is behind or in front of them.
I’m not sure how to do it.

Any help is welcome

I’ve tried this (eyeRot is the rotation of the enemy)

	if(eyeRot>-1.2 && eyeRot<1.2):
	print("PLAYER INFRONT: " + str(eyeRot) )
	get_node("Sprite3D").show()
else:
	print("BEHIND: " + str(eyeRot) )

But this doesn’t work, as it prints positive if the player is in front or behind, and only prints negative if the player is to one of the sides.

What I’m trying to do is a basic cone of sight.

:bust_in_silhouette: Reply From: Gokudomatic2

If you want to know if the player is in front or behind a node, simply do a dot from the difference of position between the two nodes and the front axis of the object.

For instance, if the front axis of the object is Z, calculate the dot of the player.pos-object.pos on this Z vector. If it’s negative, then the player is behind the object. And with that you can even simulate a cone of sight. You simply have to calculate the difference of position and dot it on the X axis of the object. That gives you the 2 sides of a right triangle and therefore the angle on the horizontal plane.

Thanks,
But, I’m a bit sure how to do this.

I know the dot product

is enemy.get_translation().dot(player.get_translation())

but how do I set that to the z axis.

Thanks for the help.

sionco | 2016-11-15 16:44

Actually the dot product must be done relatively to the enemy and not to the center of the world.
You can get the absolute z axis from enemy by calling enemy.get_global_transform().basis[2], which returns you a Vector3 of the Z axis. And only then you can make a z_vector.dot(player_relative_position), where player_relative_position is the player.get_translation()-enemy.get_translation().
You see, the z vector is used to define the center axis of the sight cone. So any relative vector opposite to this vector would be behind the enemy, and their dot product will always be negative. And they must be relative vectors since a vector always starts from (0,0,0). That’s why you must dot the difference of position between the player and the enemy and not dot their actual positions, which are relative to the world (no point to check if the player is behind the world, right?).

Gokudomatic2 | 2016-11-17 14:36

For anyone still looking for this, here’s an example based on @Gokudomatic2’s answer:

var z_vector = global_transform.basis.z
var relative_pos = player.global_transform.origin - global_transform.origin
		
var dot = z_vector.dot(relative_pos)

Then you can check if dot is greater or less than 0 to find out which side the player is positioned relative to the object.

DashNothing | 2022-07-30 14:44