Hey! I’m working on a climbing game, but i’ve never been good at CFrame math stuff. In the game, you can hold M1 or M2 and the respective arm of your character will point towards it on a specific axis. I’m having trouble getting the arms to point correctly and not detach from the torso or glitch around.
My code if you need it (kind of rushed):
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local mouse = player:GetMouse()
local holdingM1 = false
local holdingM2 = false
-- Utility: Lock mouse target to player's Z-plane (2.5D)
local function getMousePositionOnPlane()
local character = player.Character
if not character then return Vector3.zero end
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return Vector3.zero end
local mousePos = mouse.Hit.Position
return Vector3.new(mousePos.X, mousePos.Y, root.Position.Z)
end
local function Point_C0_To_Mouse(motor, worldCFrame)
local part1CFrame = motor.Part1.CFrame
local storedC0 = motor.C0
local storedC1 = motor.C1
local relative = storedC0 * storedC1:Inverse() * part1CFrame:Inverse() * worldCFrame * storedC1
relative -= relative.Position
return relative + storedC0.Position
end
-- 🔘 Input listeners
UserInputService.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
holdingM1 = true
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
holdingM2 = true
end
end)
UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
holdingM1 = false
elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
holdingM2 = false
end
end)
RunService.Stepped:Connect(function()
local char = player.Character
if not char then return end
local torso = char:FindFirstChild("Torso")
local leftArm = char:FindFirstChild("Left Arm")
local rightArm = char:FindFirstChild("Right Arm")
local leftShoulder = torso and torso:FindFirstChild("Left Shoulder")
local rightShoulder = torso and torso:FindFirstChild("Right Shoulder")
if not (leftShoulder and rightShoulder and leftArm and rightArm) then return end
local mousePos = getMousePositionOnPlane()
if holdingM1 then
local aimCFrame = CFrame.lookAt(leftArm.Position, mousePos)
leftShoulder.C0 = Point_C0_To_Mouse(leftShoulder, aimCFrame) * CFrame.Angles(0, 0, math.rad(90))
end
if holdingM2 then
local aimCFrame = CFrame.lookAt(rightArm.Position, mousePos)
rightShoulder.C0 = Point_C0_To_Mouse(rightShoulder, aimCFrame) * CFrame.Angles(0, 0, math.rad(-90))
end
end)
Basically what I want (the arm movement):