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.
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()
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
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