[SOLVED] Get angle between two entities

I’m trying to get the angle between for example the enemy and the player.
My result is NaN or an angle that stays the same.
So how i have to use the method below?

var q = new pc.Quat();
q.setFromAxisAngle(new pc.Vec3(0, 1, 0), 90);
var v = new pc.Vec3();
var angle = q.getAxisAngle(v);
// Should output 90
console.log(angle)
// Should output [0, 1, 0]
console.log(v.toString());

You can use the dot product method to get the angle between two entities.

Take a look here:

Thanks for your reaction.

Also with the code below the result is NaN…

var vecA = this.entity.getPosition();
var vecB = this.player.getPosition();
var dot = vecA.dot(vecB);
var angleInRadians = Math.acos(dot);
var angle = angleInRadians * pc.math.RAD_TO_DEG;
console.log(angle);

For that code to work the vectors need to be normalized, so with a small change it will work:

var vecA = this.entity.getPosition().normalize();
var vecB = this.player.getPosition().normalize();
var dot = vecA.dot(vecB);
var angleInRadians = Math.acos(dot);
var angle = angleInRadians * pc.math.RAD_TO_DEG;
console.log(angle);

What does .normalize() do?
It’s working but i can’t use it on this way i think.

I want to check if the player is inside the view field of the enemy.
So between -45 degrees and 45 degrees.

Any suggestion?

Normalizes scales everything to be between 0-1.

In that case I think you need first to get the vector between the two entities and then get the angle between the forward vector of the enemy (to have a point of reference for the field of view) and that new vector.

Something like this:

var enemyPos = this.entity.getPosition();
var playerPos = this.player.getPosition();

var targetDir = new pc.Vec3().copy(enemyPos);
targetDir.sub(playerPos).normalize();

var dot = targetDir.dot(this.entity.forward);
var angleInRadians = Math.acos(dot);
var angleToPlayer = angleInRadians * pc.math.RAD_TO_DEG;

if (angleToPlayer >= -45 && angleToPlayer <= 45){
   console.log('inside field of view!');
}

Not tested, but I think something like this may work here.

I get this error:

Cannot read property ‘x’ of undefined

Can you provide a simple sample project to debug?

I have to go to work now, but I will continue with it tomorrow.

1 Like

Goodmorning @Leonidas!
Here is a simple sample project with your script:
https://playcanvas.com/editor/scene/867937

Good day Albert!

Here you go, had a mistake in my code on how to get the forward vector of an entity. Now it’s fixed together with a small performance improvement (reuse a helper vector instead of creating a new one per frame):

https://playcanvas.com/editor/scene/868079

1 Like

That’s working! This forum is nothing without you! :heart:

1 Like

Hello!

I have a problem with this way to get the angle between to entities.
Probably there is something wrong with my set up.

I use the code below to get the angle between the view field of the enemy (the green triangle on the ground) and the target (in this case the player).

    this.viewOrgin = new pc.Vec3();
                // Get view angle to target
                var targetDir = this.viewOrgin.copy(targets[i].getPosition());
                targetDir.sub(this.viewField.getPosition()).normalize();
                var dot = targetDir.dot(this.viewField.forward);
                var angleInRadians = Math.acos(dot);
                var angle = angleInRadians * pc.math.RAD_TO_DEG;

In the situation below the angle result is around 30 but I expect it to be around 0. As the player gets closer to the enemy the angle grows and if the player moves away the angle reduced.



Anyone an idea?

I would double check that both of your vectors are normalised.

Hi, Albertos,the code seems fine,make sure the postion.y of the player and the enemy are the same and this.viewField.forward = 0;

1 Like

Thanks for your reply @yaustar and @FBplus.

With your information I realize that the view angle is also determined in height. Since the player’s head is the measuring point, it disappears out of sight if the player gets too close to the enemy. You can see this in the image below.

image

Now you may be wondering why the player’s head is the measuring point. That is because the collider of the head is also the measurement point of the raycast that determines whether or not there is an obstacle between the enemy and the player. But the head should not be the measurement point for angle determination.

So I have to come up with a solution for this.

1 Like