I tried to upload the videos on the Devforum but I received error messages so instead, I posted them on YouTube
The blue part’s orientation must match the red part’s orientation on the red and blue axis only. The blue part’s green axis must be left untouched.
To make sure my question is clear, here’s a video that shows the desired behavior of the blue part: https://www.youtube.com/watch?v=XRUQH9Lw8rY
Now let’s see what I get.
Everything works perfectly when I’m trying to rotate the part on all 3 axis, as you can see here: https://www.youtube.com/watch?v=bD_p5ES_3xs
But when I try to ignore the green axis, the blue part becomes corrupted when it tries to rotate after the red part’s red or blue axis!
You can view this bug here: https://www.youtube.com/watch?v=r9Hg6K8sjfs
How do I fix that?
This is my current code:
(Part0 is the red part and Part1 is the blue part)
local rv = workspace.Part0.CFrame.RightVector
local uv = workspace.Part0.CFrame.UpVector
local bv = -workspace.Part0.CFrame.LookVector
local rv1 = workspace.Part1.CFrame.RightVector
local uv1 = workspace.Part1.CFrame.UpVector
local bv1 = -workspace.Part1.CFrame.LookVector
workspace.Part1.CFrame = CFrame.new(6, 9, -25, rv1.X, uv1.X, bv1.X, rv.Y, uv.Y, bv.Y, rv1.Z, uv1.Z, bv1.Z)
Explaining why this happens is hard, but pretty much, the rotational vectors of a CFrame have to be orthogonal to each other, else a CFrame is messed up, and will result into weird behavior, like you experienced. To put it simply, never never play with the rotation vectors when using the
CFrame.new constructor, it doesn’t work the way you think it does.
What yu can do is rather simple. Each time you change the Part1 CFrame, to a new CFrame that has the same position (because you wanna keep the same position, doing something like
CFrame.new(6, 9, -25) results into hardcoded code, meaning if you change the position of
Part1, this will not work and revert it back to
6, 9, -25, to make it work wherever
Part1 is, just do
CFrame.new(Part1.CFrame.Position), generally manually inserting coordinates is really bad), and multiply it by a
CFrame.Angles that has the same rotation
Part1 had before for the Z axis (green axis), and for the X and Y rotations put the Red part’s ones.
tl;dr, but I hate spoonfeeding
local x, y, _ = Part0.CFrame:ToEulerAnglesYXZ() --this function returns the three rotations for the three axes, pretty much the numbers inside of CFrame.Angles, we only care about the first and second, x and y
local _, _, z = Part1.CFrame:ToEulerAnglesYXZ() --this is the z rotation of Part1 which is the one we want to keep
CFrame.new(Part1.CFrame.Position) * CFrame.Angles(x, y, z)
There might be a better way to do this.
After messing around with your script, I was able to achieve what I wanted. Thanks!