I had this one on my to-do list for a long time, I thought it was time to do it! If you didn’t guess already, this article will cover the :ToWorldSpace()
and :ToObjectSpace()
methods of CFrame, along with other info. The article does expect from you a decent knowledge of vectors, and simple CFrame operations.
Understanding from a Vector point of view first
I think once you get what’s going on from a Vector level of complexity, understanding the CFrame level of complexity would be easy. Let’s say you have vectors a
and b
.
Adding a
and b
is the same as putting the tail of a
on the head of b
, while a
keeps its direction of course, and wherever the head of a
lands is the new vector.
Now, you might already know this, so why am I telling you this? Well, this is a quite useful thing to know, with it you can have a better understanding of when to use vector addition.
For example, let’s suppose you raycasted a ray into a part and you used the Normal
given by RaycastResults
. (If you don’t know about raycasting nor normals, pretty much a surface normal is the direction, which is also a vector, that describes a face/surface of a part.)
But wait! All vectors are supposed to start at the origin of the world, in other words (0,0,0)
. That vector shouldn’t start from the face, it should start from 0,0,0
, keep the same direction and same length.
If you were to print the vector, you can see that the coordinates are small (it is a unit vector after all but let’s not talk about that), so it wouldn’t really make much sense for it to be there. You can place a part and set its position to the vector and you can see the result.
What would I need to do if I wanted to get the vector we expected? Well, take a look at this
Doesn’t this just look like how vector additions works in the second picture in this article? Notice how I moved the normal to start from the green vector, where it visually starts from, while the real one is at 0,0,0
. We put the normal’s tail on the head of part.Position - Vector3.new(part.Size.Z/2, 0, 0)
, the result: the vector we expected, x
! This is the same as:
x = normal + (part.Position - Vector3.new(part.Size.Z/2, 0, 0))
Let’s say we had that x
vector, and the part.Position - Vector3.new(part.Size.Z/2, 0, 0)
vector, and we want to find the normal. It’s possible! It’s actually just
normal = x - (part.Position - Vector3.new(part.Size.Z/2, 0, 0))
And let me actually visualize how vector subtraction works
Summary
Pretty cool right?
Alright, what If I were to tell you that, when raycasting and getting the normal, the normal is given to you in the object space of part.Position - Vector3.new(part.Size.Z/2, 0, 0)
,
and that, doing normal + part.Position - Vector3.new(part.Size.Z/2, 0, 0)
is converting the normal to world space.
Another good example, which I mentioned in this article, is the mouse. The mouse’s origin is actually the camera’s position. If I wanted to get the actual mouse position