How To Make Arm Face Another Part (using Motor6D)

Hello! I am currently developing a grappling system using your arm. I want it to point, not face, another part. I don’t know the math behind this system, but I’m hoping to learn.}

I’ve searched this up on the forum, and I even asked ChatGPT. But I fail to get a solid solution.

Here’s the checklist:

  1. Make sure it isn’t affected by animations
  2. Make it point, not face
  3. its r6 btw

Thank you so much for reading this

  1. i think motor6d automatically applies the cframe of part0 to part1 (torso and arm in this case), so you can make it not affected by animations by multiplying the inverse cframe of the torso intendedArmCFrame * Torso.CFrame:Inverse()

  2. point and face are the same thing but rotated; use CFrame.lookAt centered at the origin and pointing towards the part’s offset from the arm, then you can change the upvector (third argument) to rotate as needed

1 Like

thank you for replying but i just asked chatgpt (i was desperate im sorry)

but it gave me a perfect answer

local RunService = game:GetService("RunService")
local char = script.Parent
local torso = char:WaitForChild("Torso")
local leftArm = char:WaitForChild("Left Arm")
local target = workspace:WaitForChild("SomeTargetPart") -- your target

-- store original shoulder
local oldShoulder = torso:FindFirstChild("Left Shoulder")
local savedC0, savedC1
if oldShoulder and oldShoulder:IsA("Motor6D") then
	savedC0 = oldShoulder.C0
	savedC1 = oldShoulder.C1
end

-- axis tweak for arm direction
local AXIS_ADJUSTMENT = CFrame.Angles(math.rad(90),math.rad(90),0)

local armAnchor
local newShoulder
local conn

-- helper for shoulder position
local shoulderOffset = CFrame.new(-1, 0.5, 0)
local function getShoulderPos()
	return (torso.CFrame * shoulderOffset).Position
end

-- enable
local function enablePointing()
	if conn then return end -- already enabled

	-- remove original shoulder
	local old = torso:FindFirstChild("Left Shoulder")
	if old then old:Destroy() end

	-- make anchor
	armAnchor = Instance.new("Part")
	armAnchor.Size = Vector3.new(0.2, 0.2, 0.2)
	armAnchor.Transparency = 1
	armAnchor.Anchored = true
	armAnchor.CanCollide = false
	armAnchor.CFrame = CFrame.new(getShoulderPos())
	armAnchor.Parent = char

	-- new shoulder motor
	newShoulder = Instance.new("Motor6D")
	newShoulder.Name = "CustomLeftShoulder"
	newShoulder.Part0 = armAnchor
	newShoulder.Part1 = leftArm
	newShoulder.C0 = CFrame.new()
	newShoulder.C1 = leftArm.CFrame:toObjectSpace(armAnchor.CFrame)
	newShoulder.Parent = armAnchor

	-- start aiming
	conn = RunService.RenderStepped:Connect(function()
		if target and target.Parent then
			armAnchor.CFrame = CFrame.new(getShoulderPos())
			local aimCF = CFrame.lookAt(armAnchor.Position, target.Position, Vector3.new(0, 1, 0)) * AXIS_ADJUSTMENT
			newShoulder.C0 = armAnchor.CFrame:toObjectSpace(aimCF)
		end
	end)
end

-- disable
local function disablePointing()
	if conn then conn:Disconnect(); conn = nil end
	if newShoulder then newShoulder:Destroy(); newShoulder = nil end
	if armAnchor then armAnchor:Destroy(); armAnchor = nil end

	if savedC0 and savedC1 and not torso:FindFirstChild("Left Shoulder") then
		local restore = Instance.new("Motor6D")
		restore.Name = "Left Shoulder"
		restore.Part0 = torso
		restore.Part1 = leftArm
		restore.C0 = savedC0
		restore.C1 = savedC1
		restore.Parent = torso
	end
end

-- example toggle usage:
enablePointing() -- start

task.wait(5)
disablePointing() -- stop

i understand the code but i just didnt know the math and I hope thisa helps

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.