Wrong CFrame math for arm pointing toward object?

I am trying to make a script in which the player’s arm follows the item when it’s grabbed and so i merged this function with another script and made this:


local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer
local mouse = Player:GetMouse()

local Character = Player.Character
local Root = Character:WaitForChild("HumanoidRootPart")
local Neck = Character:FindFirstChild("Neck", true)
local Shoulder = Character.RightUpperArm:FindFirstChild("RightShoulder", true)
local defpos = Shoulder.C0
local YOffset = Neck.C0.Y

local CFNew, CFAng = CFrame.new, CFrame.Angles
local asin = math.asin

game:GetService("RunService").RenderStepped:Connect(function()
    local CameraDirection = Root.CFrame:toObjectSpace(mouse.Hit).lookVector
	
	local armOffset = Character.UpperTorso.CFrame:Inverse() * Character.RightUpperArm.CFrame
	
	if Neck then
		if Character.Humanoid.RigType == Enum.HumanoidRigType.R15 then
        	Neck.C0 = CFNew(0, YOffset, 0) * CFAng(0, -asin(CameraDirection.x), 0) * CFAng(asin(CameraDirection.y), 0, 0)
			if _G.ItemToFace ~= nil then
			local armcframe = CFrame.new(Character.UpperTorso.Position, mouse.Hit.Position) * CFrame.Angles(math.pi/2, 0, 0)
			Shoulder.C0 = armOffset * Character.UpperTorso.CFrame:ToObjectSpace(armcframe)
			else
			Shoulder.C0 = defpos
			end
		elseif Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
			Neck.C0 = CFNew(0, YOffset, 0) * CFAng(3 * math.pi/2, 0, math.pi) * CFAng(0, 0, -asin(CameraDirection.x)) * CFAng(-asin(CameraDirection.y), 0, 0)
			if _G.ItemToFace ~= nil then
			local armcframe = CFrame.new(Character.UpperTorso.Position, mouse.Hit.Position) * CFrame.Angles(math.pi/2, 0, 0)
			Shoulder.C0 = armOffset * Character.UpperTorso.CFrame:ToObjectSpace(armcframe)
			else
			Shoulder.C0 = CFNew(0,0,0) * CFAng(0,0,0)
			end
		end
    end
end)

game.ReplicatedStorage.Look.OnClientEvent:Connect(function(otherPlayer, neckCFrame, ShoulderCFrame)
	local Neck = otherPlayer.Character:FindFirstChild("Neck", true)
	local Shoulder = otherPlayer.Character:FindFirstChild("RightShoulder", true)
	
	if Neck then
		tweenService:Create(Neck, TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = neckCFrame}):Play()
	elseif Shoulder then
		tweenService:Create(Shoulder, TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = ShoulderCFrame}):Play()
	end
end)

while wait() do
	game.ReplicatedStorage.Look:FireServer(Neck.C0, Shoulder.C0)
	
end

https://gyazo.com/cf1625da1e4e0d569c5a844a4a37cce1

https://gyazo.com/34bf1ba7d75b8a26630211c068ea2780
(Screen on the left)

The arm goes into the person’s back and the Elbow isn’t straight it moves according to the roblox animation

Just wanted to point out something important, in first person the character of the player including his arms are invisible, meaning moving the default character arm is useless, so what you can do is make a fake arm that will be moved instead of the original arm, and perhaps that arm would move without any problem

I only want to add the arm moving toward the object so that the other players can see the arm move

1 Like

I’m assuming the code is client sided (you’re using RenderStepped), joint C0 and C1 don’t replicate from the client so you’d need to do it server side.

That wouldn’t make sense though because again, the neck movement works, it’s just the arm

And i forgot to mention, I have a Server-Side script that’s fired from that local script.

game.ReplicatedStorage.Look.OnServerEvent:Connect(function(player, neckCFrame, shoulderCFrame)
	for key, value in pairs(game.Players:GetChildren()) do
		if value ~= player and (value.Character.Head.Position - player.Character.Head.Position).Magnitude < 10 then
			game.ReplicatedStorage.Look:FireClient(value, player, neckCFrame, shoulderCFrame)
		end
	end
end)

you’re using _G table to find a ItemToFace, first off i advise not using the _G for just a normal variable that changes a lot like item to face, you can send info between scripts with many ways for example objectValues or Bindable Events, so i think the if _G.ItemToFace ~= nil then condition doesn’t pass and the arm is kept into a default position.

You’re right about the _G variables, i just rechecked them btw in my other script and now it works however:
https://gyazo.com/61ffe25a67f77a59804b98f864aee819

RotatingArmsToMouse.rbxl (17.7 KB)
seems like you gotta fix the CFrame math…
Luckly i’ve made a simple script a while ago that rotates the arms towards a certain point, in my case it’s the unfiltered mouse position, you’d wanna change that position to be the items position and only affect one arm, hope it helps!

2 Likes

Thats it it worked! Thank you for the help

1 Like

Wait… Sorry it worked but then i re-checked it and it’s still a bit buggy:

https://gyazo.com/cf1625da1e4e0d569c5a844a4a37cce1

https://gyazo.com/34bf1ba7d75b8a26630211c068ea2780
(Screen on the left)

The arm goes into the person’s back and the Elbow isn’t straight it moves according to the roblox animation

You can also set the localtransparency of the limbs, and bodyparts of the character to 0.

Quick issue with your code:
R6 doesn’t have an UpperTorso, change the CFrame.new() to Torso. Thats probably just a copy paste issue.


So, you are using the UpperTorso’s position to calculate the origin of the shoulder/arm. Instead try using the position - the UpperTorso’s right vector (since it’s the left arm). So like:

local armcframe = CFrame.new((Character.UpperTorso.Position - Character.UpperTorso.CFrame.RightVector), mouse.Hit.Position) * CFrame.Angles(math.pi/2, 0, 0)