In Roblox, adding CFrames directly to combine position and orientation isn’t possible. Here’s why, and how to achieve the desired result…
You can’t add two CFrames in that approach.
If we see in the Roblox Documentation, CFrame is a datatype that has two components which are position and orientation.
Position is a Vector3 component, whereas rotation data (orientation) is maintained by storing it in matrices, and Roblox uses Euler’s angles for the rotation data, because it lets you describe the orientation of any object with respect to a fixed coordinate system in (In this case, 3D Space)
I believe this is why you can’t add two CFrames in the way you’re trying to do:
workspace.Part.CFrame
-- We asked the datatype CFrame, and it returns two components,
-- one is Vector3 type; which is position, and the second is the orientation, in Euler Angles.
In the runtime, behind the scenes, since we’re asking that datatype and retrieving those two components, here’s how it might look:
CFrame = Vector3.new(5, 5, 5) * CFrame.fromEulerAngles(math.rad(30), 0, 0)
-- Let's suppose, the part's position (Type Vector3), is 5, 5 ,5, and the Euler angles to be something...
Well, as you see, it is Euler Angles here, whereas in your OP, you were asking why it is not possible to do it in that approach, simply; you are getting part A and part B Rotation, and the orientation is returned in degrees, which can’t be added to the CFrame that uses Euler Angles (which is in radians)
This is the point, the CFrame combines two components, one is position which is a Vector type, the second one is Euler Angles which is done in radians and NOT degrees.
But in that equation, you retrieving the rotation of the Part A and B, and that would just return the rotation in degrees and not radians.
Which wouldn’t work for maths, but thankfully, you can convert that rotation value you got to radians using the math.rad()
function.
In the paranthesis of math.rad()
, you can a number in degrees, and it will convert that into radians, and for all intents and purposes regarding the CFrames, this simple trick is all that’s needed to be done!
And regarding, why you can’t add two CFrames, it’s very simple to think of, just add a part into your workspace, and try printing its CFrame, and it should give something like this in the output:
-57, 19.5, 62, 1, 0, 0, 0, 1, 0, 0, 0, 1
The first three numbers are position (Vector3) values, and the remaining numbers are related to the orientation in radians.
Those remaining 9 numbers are arranged in a matrix, as you can see in CFrame Documentation.
And the output just printed them when you used:
print(workspace.Part.CFrame)
So, if you try to add two CFrames, it’s like adding two sets of the numbers I showed you above, and it fails to do so, because you are adding two sets of numbers!
But let’s see it this way, Roblox actually DOES manage both of them for you, so it is handled in the background and if you use the PLUS sign, it understands you are trying to add a value to the existing CFrame and it adds it to the first three numbers which are Vector3, so it expects Vector3 when YOU use the PLUS ( + ) sign.
Because when you say:
workspace.Part.CFrame + CFrame.new(50, 20 ,30)
Behind the scenes of the CFrame.new() function, you are also giving an empty values of orientation i.e., not giving any values of the rotation data, in other words, you are giving the numbers of zeroes and the number ONE!
Because, as I said if you add a part into your workspace, and print its CFrame, using print(workspace.Part.CFrame)
without rotating it at all, since Euler Angles are relative to something, the remaining 9 numbers:
-57, 19.5, 62, 1, 0, 0, 0, 1, 0, 0, 0, 1
There’s three 1s… However, let me put this simply for you.
You are doing addition operation with the plus sign operator, with a CFrame and a CFrame.new()
But let’s think of this like this, when you try to use CFrame.new, it expects Vector3 of the position property. This is because CFrame.new() is specifically for Vector3 values and not orientation.
BUT in another case where you are not using the CFrame.new(), but getting the value of both or
OR, if you try to add two CFrames (Part1.CFrame + Part2.CFrame), it’s like adding two sets of the numbers I showed you above as well, so…
There’s a workaround to overcome this, since when you use the PLUS sign, it expects Vector3, when you use multiplication it expects orientation.
The “IT” here is the CFrame you are doing the equation with.
Since you said you wanted to combine both position and orientation, just do this, this is what I did and it worked for me:
Player.Character:SetPrimaryPartCFrame((Player2.PrimaryPart.CFrame) * CFrame.fromEulerAngles(math.rad(20), math.rad(0), math.rad(20)) + Vector3.new(3, 0, 3))
So, basically, setting the Player’s CFrame to the Player2’s CFrame, but I wanted to keep the Player to stay a bit away, so I used the plus sign operator, and the CFrame expects a Vector3 value in that case.
I also use multiplication sign, and the CFrame expects that it is for orientation, however you must convert, let’s say 45 degrees to radians, use the math.rad() function, and that’s it.
I hope this was helpful, I tried to give some of my insights behind why it works like this, I might’ve got a bit carried away with details, sorry about that.