Angle calculation explanation

Hi, soo i struggled to make angle calculations long time ago, i did it by cframes last year, but i didn’t knew how to do it mathematically, because math is simply better and faster because you work on numbers, and you doing things like division or multiplication ect. but you don’t even know, but now let’s keen on how to do it:

1. Dot product

Soo simply Dot product it’s how direction of two vectors is the same, for example if you and camera looks at the same direction, the result will be 1, if the direction is opposite then -1 , more about that in this tutorial: https://devforum.roblox.com/t/the-ultimate-guide-to-vector3cross-and-vector3dot/953984

More important thing is the ArcCosine from Dot product is the angle in radians beetween two vectors, then to get angle we have to make:

local dot = VectorA:Dot(VectorB)
local angle = math.acos(dot) * (180/math.pi) -- angle in degree

Note: you can use math.deg instead of (180/math.pi) i did this because it’s more redable,
I didn’t tell that vectors have to be units + we doing degree only if we need to check angle, if we wan’t to use it in calculations later, remove radians to degree conversion

2. Direction of vector

to get direction of vector we can do two things:

A) Relative to the point(0,0,0): VectorA.Unit

B) Relative to the another vector: (VectorA - VectorB).Unit

Note: order matters, soo (VectorA - VectorB).Unit is direction A relative to direction B, if we will change vectors, it will be opposite

3. Calculating angle between two vectors
Soo, if we know what is the Dot and Direction we can calculate angle, photo under:

This scenario is for example, we have NPC - Green that faces Blue Line, and the Red Dot is player, if the angle beetween NPC and Player is less than 40 degree, then NPC will attack player.

But how to do that?, soo if we wan’t to do that independently of what direction player faces, we have to get relative vector of player to NPC. Let’s do that:

local RelativeToNpc = (NPC.Position-Player.Position).unit

this equals to negative

CFrame.LookAt(NPC.Position,Player.Position) 

but we doing this mathematically, no more CFrames!

now let’s find angle between Dots:

local AngleFromDot = math.acos(NPC.LookVector:Dot(RelativeToNPC)) * (180/math.pi)
local FinalAngle = 180 - AngleFromDot

I found methood, that if you’ll subtract AngleFromDot from 180 we will get angle relative to how much degree we need to face Player in this situation

4. Getting angle on one plane only

Methood above is for every axis, soo no matter if we will turn up or down or right or left, to change this, you have to do the same thing for vector2 not vector3. But how to get lookVector on 2D plane???, simply you can’t, but there is one thing left,we can turn LookVector components into Vector2, depends on what you wan’t to get, if you wan’t to get angle up and down, you can do:

local Look = Vector2.new(NPC.LookVector.Z,NPC.LookVector.Y).Unit

you have to experiment with this, but this tutorial covers only basics, soo we will not go into this.

I think i helped you, i know how much effort i had to put to this to work year ago, thank you and have a good day! bye!

7 Likes

This is incorrect. Your equation would be correct ONLY IF both the vectors are unit vectors (vectors whose magnitude is 1), which is not always the case. The angle theta between two vectors of varying magnitudes, A and B, is given by the following equation:
image
Where A . B is the dot product of the two vectors and |A| and |B| are the magnitudes of the vectors.

I would also recommend performing all calculations in radians rather than in degrees since all mathematical (trigonometric) functions internally use radians. It prevents the need for unnecessary computations, i.e. converting from radians to degrees and back to radians when you wanna pass it onto other trigonometric functions.

1 Like

oh sorry, it’s my fault i forgot to tell that VectorA and VectorB have to be units, and for the radians, checking is one thing in degree, in radians it’s hard, soo we are converting it to degree for this specific situation

1 Like

I personally would say it’s good practice to get used to calculating angles in radians.

1 Like

yea, but i made this tutorial for one scenario, we wan’t to find anglee between NPC and player, soo in most cases we wan’t to use degree to be more redable, it’s hard to write math.rad() everywhere when we wan’t to see if Player is in FOV of NPC or not