SebastianAurum provided the best way of solving OPs actual problem, but in case someone in the future really does need to find such an angle, here’s how you can do that:
First of all, you can’t find an angle between two points. It just doesn’t make any sense, because an angle needs at least three points to be properly defined: a point each on the legs of the angle, and one for the point/knee of the angle. In OPs case, it looks like they’re really asking for the angle between two vectors, which does make sense (the vector from NPCs head to players head, and vector of direction of NPCs head).
The angle between two vectors a
and b
is
math.acos( a:Dot(b)/(a.Magnitude * b.Magnitude) )
We often deal with the special case where both vectors are unit vectors (i.e. their magnitude is 1), in which case this slightly simpler expression that you might see being used elsewhere works as well:
math.acos( a:Dot(b) )
This technique only returns angles in the interval [0; pi]
because two vectors can never point more away from each other than directly away from each other, which can always be achieved by a rotation of pi radians = 180 degrees
. This means the angle you get in this way has no direction (it’s never negative), so if you need that direction you’ll need a different technique:
First of all, this method works best with a CFrame and a vector (could also use 3 vectors), and then gets the angle between the CFrame’s lookVector and the given vector. Because the CFrame has an upVector as well, we can work with the direction:
local projectedVector = cframe:VectorToObjectSpace(vector) * Vector3.new(1, 0, 1)
local angle = math.atan2(projectedVector.Z, projectedVector.X)
This works by projecting the vector
onto a 2D plane perpendicular to the upVector of the cframe
, and converted to a representation that is in relation to the cframe
. It then uses atan2
to calculate the angle between the lookVector of the cframe
and the vector
in that plane.
EDIT: Please see the following comments for a bit of clarification