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());
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);
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.
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):
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.
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.
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.