Hey, I’m currently working on using AlignOrientation and ground normal to align a controllable office chair assembely to the ground below it. I’ve got it all working, except for the fact that I want to make it so the chair can spin freely on the Y-Axis, and because AlignOrientation lacks a MaxTorque vector3 value, I’m trying to do the code myself.
What I’m doing at the moment is compiling a new Orientation CFrame that is inputted by deriving it from the lookvector of the actual chair (this determines the orientation on Y axis) and the upvector of the ground normal (determining X and Z).
But whenever I actually enable the constraint into which I am feeding these vectors via CFrame.fromMatrix, the chair glitches out and just messes up entirely.
If it helps, in a scenario where the two vectors should in theory be identical, the orientations are:
0, -109, 0 — constraint
90, 70, 0 – actual
I feel like something is being rotated relative to something else incorrectly, but I’m entirely lost as to what it actually is, I would greatly appreciate any help!
I think it’s freaking out because the AlignOrientation changes the LookVector that you use on the next frame to recompute the AlignOrientation?
Try enabling PrimaryAxisOnly on the AlignOrientation, so it lets the chair freely spin elsewise. You can probably simplify your CFrame computation a bit also since you no longer care about the look vector, but it should work as is too.
local look = MovePart.CFrame.LookVector
local normal = result.Normal
local proj_look_onto_normal = look:Dot(normal) * normal
local proj_look_onto_ground_plane = look - proj_look_onto_normal
Gizmo.PushProperty("Color3", Color3.new(0.796078, 0.627451, 1))
Gizmo.Arrow:Draw(MovePart.Position, MovePart.Position + look, 0.05, 0.1, 9)
local computed_right = proj_look_onto_ground_plane.Unit:Cross(normal)
Gizmo.PushProperty("Color3", Color3.new(1, 0.184313, 0.184313))
Gizmo.Arrow:Draw(MovePart.Position, MovePart.Position + computed_right, 0.05, 0.1, 9)
-- the 'computed up vector' is the normal
Gizmo.PushProperty("Color3", Color3.new(0.184313, 1, 0.184313))
Gizmo.Arrow:Draw(MovePart.Position, MovePart.Position + normal, 0.05, 0.1, 9)
-- use the computed vectors
-- rotate to match primary axis upward
local CalculatedFrame = CFrame.fromMatrix(MovePart.Position, computed_right, normal, -(proj_look_onto_ground_plane.Unit)) * CFrame.Angles(0, 0, math.pi/2)
AlignOrientation.CFrame = CalculatedFrame
I’ve adjusted the way we calculate the look vector, we’re not interested in the chair’s look vector but rather its projection onto the normal plane. Excuse my coding style if its a bit different
I’ve also moved the attachment from the ‘Core’ to the ‘Mass’ (the Core was upside down) and made sure the attachment was at identity orientation.
Then I set the ‘primary axis only’ on the align orientation to ‘enabled’ and rotated the attachment so that it’s primary (X) axis is upward, and we account for this as well by adding a rotation to the final CalculatedCFrame.
This is the result, baseplate green indicates when the alignorientation was enabled:
Took a bit of tweaking as I needed to make it work with the rest of my code but that works perfectly, thank you so much. I’m terrible at CFrames so you’ve saved me hours of work lol.