To be clear, I understand how to use CFrame.lookAt, I only want to know what the math behind it is, and how it gets the angles on each axis for the CFrame that it returns.
So CFrame.lookAt() is just one constructor for a CFrame, there are 9 others, it creates a new CFrame positioned at the first argument, looking at the position of the second argument, and with an up vector as a direction of the third argument. Are you asking about accessing general information on a CFrame after you create it with this constructor? If you have learned about matrices and vectors in school it shouldn’t be too much of a stretch. Do you want to create your own form of CFrame?
to rotate a CFrame
object to face a given position.
THATS why it’s look at now you can make a part look at a pizza
For the math part it’s advanced calculations with the trigonometry and more
I want to know what math it uses to get the angles from the CFrame that it returns. I know its arguments and how to use it, but I want to know how it works internally
If you look at the CFrame | Documentation - Roblox Creator Hub, you will see what all of the properties mean and do. The first column is the position, then the XVector, YVector, and ZVector. Are you asking how it generates the three vectors using the two positions provided and the optional up vector?
I believe it simply calculates all the angles of the lookAt CFrame relative to the origin CFrame and casts it to the origin CFrame.
Yes. I want to know what equations it uses to get the rotational components of the CFrame it returns. I what a CFrame is, I only want to know how it gets those angles.
I think there’s a function for getting the angles between 2 vectors in the Vector3 library. I’m on mobile so I cannot check.
CFrame.lookAt takes two vectors and returns a CFrame with a rotational component which points towards the second point from the first.
All I am asking is for the equations which calculate said rotational components.
local rotation = Vector3.new(CFrame.lookAt(v1, v2):ToEulerAngles())
you will have to convert it from radians to degrees with math.deg though
But HOW?? What does CFrame.lookAt do internally to get those angles??
function CFrame.lookAt(eye, at)
--// WHAT HAPPENS HERE?
end
you’d probably be better off reading other forums about how to convert a vector3 direction to angles, there are multiple that explains it. Such as this one rotation - Implementation of Vector3.RotateTowards from Unity - Game Development Stack Exchange
Well nobody here knows the official code since it’s not open source. But as I said, you just need the angle calculation formula. The rest should be easy.
I’ve typed this on a mobile device which was a pain, but I tried to make the logic as intuitive as possible
A CFrame is a 4x4 matrix where the first column of 3 from the left is the right vector, the 2nd being the up vector, 3rd being the back vector (look vector but in the opposite direction), where the preceding 3 make up the rotation matrix, and the 4th being the position. CFrame.lookAt
can achieve this by setting the position to the input position and then make the look vector face the point to look at, but we also need to find the directions of the right and up vectors
We can use the cross product operation of two vectors which will give us the directions we want. Given two vectors, the cross product is a vector perpendicular to both input vectors. However without proper constraints get one consistent result, Roblox uses the right-hand rule where if you take your right hand, curl all of your fingers, point your index finger (or finger next to your thumb) in the direction of the 1st vector and your middle finger in the direction of the 2nd vector, then if you extend your thumb, the cross product of those two vectors is the direction your thumb will be pointing in when extended.
CFrame.lookAt
has a 3rd argument which represents the up direction used to calculate the other directions, which by default is 0, 1, 0
or Vector3.yAxis
. We’ll see how this comes into use:
Our look direction will just be a vector pointing from from
to to
:
-- Columns of the rotation must be unit vectors
local look = (to - from).Unit
For argument’s sake, let’s assume that we want lookAt to return a CFrame with its lookVector pointing in the -z direction, which will replicate the alignment of the global axes. We need to calculate the right vector and we can find that by using the look direction and the up direction. If you use the right-hand rule by taking your right hand, point your index finger upwards and your middle finger pointing towards you (this is the back vector i.e: -look), then your thumb will point to your right - your hand is now exactly like the alignment of the global axes:
local right = up:Cross(-look)
We found the right and look, but we have to calculate an up vector for the matrix as the up direction we provided won’t necessarily be perpendicular to -look. If you take your right hand, point your index finger in the direction of the right vector (to your right) and your middle finger pointing away from you (this is the look vector), then your thumb points upwards - just like how it should be based on the orientation of the global axes:
local up = right:Cross(look)
We can construct a matrix with the position and all 3 rotation matrix vectors:
local function lookAt(from, to, up)
local up = up or Vector3.yAxis
local look = (to - from).Unit
local right = up:Cross(-look)
local up = right:Cross(look)
return CFrame.fromMatrix(from, right, up, -look)
end
just to add on CFrame.lookAlong()
now exist, so you can save a tiny bit of performance by skipping having to calculate displacement (assuming that’s what the actual source code does)
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.