Requires some adjustment but will work, same concept and math formulas. However added an extra C1 inverse because R6 has some weird rotation to it’s C1 creating an offset.
I think the R15 one is the wrong actually this formula should work for both R15 and R6 (c1 offset not included)

local motor : Motor6D = script.Parent.HumanoidRootPart.RootJoint -- Assume this is a Motor6D
local part0 = motor.Part0 -- Parent part
local part1 = motor.Part1 -- Child part (e.g., head, torso)
local randomAxis = Vector3.new(0,0,1)
local function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
end
local originalC0 = motor.C0
local originalC1 = motor.C1
local function worldCFrameRotationToC0ObjectSpace(motor6DJoint, worldCFrame)
local part0 = motor6DJoint.Part0
local c1Store = motor6DJoint.C1
local goalC0CFrame = part0.CFrame:Inverse() * worldCFrame * c1Store
return goalC0CFrame
end
-- your previous code...
-- Create debug part for target rotation
local debugPart = Instance.new("Part")
debugPart.TopSurface = Enum.SurfaceType.Motor
debugPart.FrontSurface = Enum.SurfaceType.Motor
debugPart.Size = Vector3.new(3, 3, 0.5)
debugPart.Color = Color3.new(1, 0, 0) -- Red
debugPart.Material = Enum.Material.Neon
debugPart.Anchored = true
debugPart.CanCollide = false
debugPart.CanTouch = false
debugPart.CanQuery = false
debugPart.Name = "DebugTarget"
debugPart.Parent = workspace
-- Create another part for the floor normal gizmo
local floorNormalGizmo = Instance.new("Part")
floorNormalGizmo.Size = Vector3.new(0.2, 0.2, 5) -- Thin arrow
floorNormalGizmo.Color = Color3.new(0, 1, 0) -- Green
floorNormalGizmo.Material = Enum.Material.Neon
floorNormalGizmo.Anchored = true
floorNormalGizmo.CanCollide = false
floorNormalGizmo.CanTouch = false
floorNormalGizmo.CanQuery = false
floorNormalGizmo.Name = "FloorNormalGizmo"
floorNormalGizmo.Parent = workspace
--part0.Transparency = 0 -- make sure part0 is visible
--game["Run Service"].PreSimulation:Connect(function(dt)
-- motor.Transform = CFrame.new()
--end)
local params = RaycastParams.new()
params.FilterDescendantsInstances = {script.Parent, floorNormalGizmo, debugPart}
while true do
local rayResult = workspace:Raycast(part0.Position, -1000 * part0.CFrame.UpVector, params)
if rayResult then
local floorNormal = rayResult.Normal
local hitPosition = rayResult.Position
local angle = part1.CFrame.UpVector:Dot(floorNormal)
--print(math.deg(math.acos(angle))) IDK
--if math.deg(math.acos(angle)) < 0.1 then
-- task.wait()
-- continue
--end
-- Rotate the part1 to align with floor normal
local x,y,z = part1.CFrame:ToOrientation()
local part1NewCF = CFrame.fromOrientation(x,y,0)
local rotateToFloorCFrame = getRotationBetween(part0.CFrame.UpVector, floorNormal, randomAxis)
-- Target worldspace CFrame
local targetWorldCFrame = rotateToFloorCFrame * part0.CFrame*originalC1:Inverse()
-- Move the debug part to the target
--debugPart.CFrame = targetWorldCFrame.Rotation + part0.Position + Vector3.new(0,4,0)
-- Update the Motor6D's C0
motor.C0 = (part0.CFrame:Inverse() * targetWorldCFrame).Rotation + motor.C0.Position
--motor.C1 = CFrame.new()
-- Update the floor normal gizmo
--local lookVector = floorNormal
--local upVector = Vector3.new(0,1,0)
--if math.abs(lookVector:Dot(upVector)) > 0.99 then
-- upVector = Vector3.new(1,0,0) -- avoid gimbal lock
--end
--local rightVector = upVector:Cross(lookVector).Unit
--local newUpVector = lookVector:Cross(rightVector).Unit
--local orientationCFrame = CFrame.lookAlong(hitPosition, floorNormal * 2.5)
--floorNormalGizmo.CFrame = orientationCFrame
end
task.wait(0)
end