First person Arms + Tools not aligning

I’m using this tutorial on how to animate tools, and it works well. However, it doesn’t align properly with my first-person arms script. When I look down, the gun moves higher until its handle is sticking out, and when I look up, the gun phases into my hand.
Here’s what I mean:


I’ve tried editing the values of X by multiplying and adding to it, but it always seems slightly off, so I assumed there was a better way to do this that I wasn’t aware of.

Here’s my code:

local RunService = game:GetService('RunService')
local Player = game.Players.LocalPlayer
local Camera = workspace:WaitForChild('Camera')
local Character = script.Parent
local Humanoid = Character:WaitForChild('Humanoid')

local Ang = CFrame.Angles
local aSin = math.asin
local aTan = math.atan

local HeadHorFactor = 0
local HeadVertFactor = 1
local UpdateSpeed = 0.5

local Ang = CFrame.Angles
local aSin = math.asin
local aTan = math.atan

local Head = Character:WaitForChild('Head')
local LeftArm = Character:WaitForChild('Left Arm')
local RightArm = Character:WaitForChild('Right Arm')
local Humanoid = Character:WaitForChild('Humanoid')
local RootPart = Character:WaitForChild('HumanoidRootPart')
local Torso = Character:WaitForChild('Torso')
local Neck = Torso:WaitForChild('Neck')
local NeckOrgnC0 = Neck.C0
local RightShoulder = Torso:WaitForChild('Right Shoulder')
local RightShoulderOrgnC0 = RightShoulder.C1
local LeftShoulder = Torso:WaitForChild('Left Shoulder')
local LeftShoulderOrgnC0 = LeftShoulder.C1
local BodyAttach = Torso:WaitForChild("BodyAttach",5)
local rootJoint = Character.HumanoidRootPart.RootJoint
local function align(CameraCFrame, HeadHorFactor, HeadVertFactor, UpdateSpeed, MouseOriginPosition)
	local Dist = (Head.CFrame.Position-CameraCFrame.Position).Magnitude
	local Diff = Head.CFrame.Y-CameraCFrame.Y

	local HeadPosition = Head.CFrame.Position
	local TorsoLookVector = RootPart.CFrame.lookVector

	local X = -(math.asin((MouseOriginPosition - CameraCFrame.Position).unit.y)) * -1
	Neck.C0 = Neck.C0:Lerp(NeckOrgnC0*Ang(-(aSin(Diff/Dist)*HeadVertFactor), 0, -(((HeadPosition-MouseOriginPosition).Unit):Cross(TorsoLookVector)).Y*HeadHorFactor),UpdateSpeed/2)

	local _, Y, Z = Neck.C0:ToEulerAnglesXYZ()
	Neck.C0  = CFrame.new(Neck.C0.Position) * CFrame.Angles(X - 1.5, Y, Z)

	local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
	RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X, Y, Z)

	local _, Y, Z = LeftShoulder.C0:ToEulerAnglesXYZ()
	LeftShoulder.C0 = CFrame.new(LeftShoulder.C0.Position) * CFrame.Angles(X, Y, Z)

	local _, Y, Z = BodyAttach.C0:ToEulerAnglesXYZ()
	BodyAttach.C0 = CFrame.new(BodyAttach.C0.Position) * CFrame.Angles(X , Y, Z)
end
while task.wait(1/60) do
	local MouseOriginPosition = Player:GetMouse().Origin.Position
	if not Character.Downed.Value then
		align(Camera.CoordinateFrame, HeadHorFactor, HeadVertFactor, UpdateSpeed, MouseOriginPosition)
	end
end

Any help would be appreciated!

1 Like

Why won’t you just weld the gun to the fake arms?

The arms aren’t fake, they’re the real ones. Plus, I don’t want to weld the gun as it prevents the gun from being animated. That’s why I’m using a Motor6D.

It looks like you aren’t doing this in object space. Please convert them to object space.

What should it be relative to? The torso, head or root? Sorry, I’m not that good with CFrame functions : /

I’ve made my system relative to the torso, so the arms bob up and down with it. In your case with R6, it will depend on your animations. You can use either torso or root.

The gun should be relative to the arm.

I chose Torso, but I still don’t fully grasp what you mean.
I did this:

local rShoulderC0 = RightShoulder.C0:ToObjectSpace(Torso.CFrame)
	local _, Y, Z = rShoulderC0:ToEulerAnglesXYZ()
	RightShoulder.C0 = CFrame.new(rShoulderC0.Position) * CFrame.Angles(X, Y, Z)

But now my arm is way off and it doesn’t match up at all.
Could you provide an example of what you mean?

Also, I should add, BodyAttach(the thing that allows the guns to be animated, is attached to the torso, not the hands. Would that Affect it?)

I would recommend attaching it to the hands for simplicity, it should not affect it.

I did not use any sort of ToEulerAnglesXYZ (this does not matter if used or not), nor did I get the object space from the weld’s C0. What I did with my system was I obtained the desired CFrame of the arms then I converted it into object space. None of my calculations depended on the weld/motors CFrame, but rather just an offset (which you seem to have).

In short, I got the object space from the part’s CFrame itself, and then I applied any sort of angle. To smoothly interpolate the angles, I had a CFrame variable I would update.

I can’t really switch now, animations have been made with the Torso, and switching to hands will break those.

I also am trying to figure out exactly what offset I need to get in the first place, as again, my system works it’s just that it doesn’t align with the arms.

In that case, you should be able to make the C0 relative to the arm, but Part0 can be the torso.

To do that I think you’ll need to make the C0 of the weapon the same as the C0 of the arm, but just apply an offset to it. The offset should be something like CFrame.new(0, 0.5, 2)

That seemed to work! I just need to rotate it, thanks man!
For others looking to fix this issue I’ll post my code when I’m finished

Sorry it took this long for me to understand you, I thought you were meaning adding offset to the ToEulerAnglesXYZ rather than the actual CFrame. Thank you so much!

local RunService = game:GetService('RunService')
local Player = game.Players.LocalPlayer
local Camera = workspace:WaitForChild('Camera')
local Character = script.Parent
local Humanoid = Character:WaitForChild('Humanoid')

local Ang = CFrame.Angles
local aSin = math.asin

local HeadHorFactor = 0
local HeadVertFactor = 1
local UpdateSpeed = 0.5


local Head = Character:WaitForChild('Head')
local RootPart = Character:WaitForChild('HumanoidRootPart')
local Torso = Character:WaitForChild('Torso')
local Neck = Torso:WaitForChild('Neck')
local NeckOrgnC0 = Neck.C0
local RightShoulder = Torso:WaitForChild('Right Shoulder')
local LeftShoulder = Torso:WaitForChild('Left Shoulder')
local BodyAttach = Torso:WaitForChild("BodyAttach",5)
local rootJoint = Character.HumanoidRootPart.RootJoint
Character:WaitForChild("Downed",5)

local toolOffset = CFrame.Angles(0,math.rad(-90),0) * CFrame.new(-1, -0.5, 0)
local function align(CameraCFrame, MouseOriginPosition,dt)
	local Dist = (Head.CFrame.Position-CameraCFrame.Position).Magnitude
	local Diff = Head.CFrame.Y-CameraCFrame.Y

	local HeadPosition = Head.CFrame.Position
	local TorsoLookVector = RootPart.CFrame.lookVector

	local X = -(math.asin((MouseOriginPosition - CameraCFrame.Position).unit.y)) * -1
	
	Neck.C0 = Neck.C0:Lerp(NeckOrgnC0*Ang(-(aSin(Diff/Dist)*HeadVertFactor), 0, -(((HeadPosition-MouseOriginPosition).Unit):Cross(TorsoLookVector)).Y*HeadHorFactor),dt)
	local _, Y, Z = Neck.C0:ToEulerAnglesXYZ()
	Neck.C0  = CFrame.new(Neck.C0.Position) * CFrame.Angles(X - 1.5, Y, Z)
	
	
	local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
	RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X, Y, Z)

	local _, Y, Z = LeftShoulder.C0:ToEulerAnglesXYZ()
	LeftShoulder.C0 = CFrame.new(LeftShoulder.C0.Position) * CFrame.Angles(X, Y, Z)

	local _, Y, Z = BodyAttach.C0:ToEulerAnglesXYZ()
	BodyAttach.C0 = RightShoulder.C0 * toolOffset
end
RunService.Heartbeat:Connect(function(dt)
	local MouseOriginPosition = Player:GetMouse().Origin.Position
	if not Character.Downed.Value then
		align(Camera.CoordinateFrame, MouseOriginPosition,dt)
	end
end)

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