Need help in fixing FPS offset

It’s a little hard for me to explain. So when the character enters first person mode, their arms will look wherever the camera is looking.

It works in a way, but the offset is never the same when you move the camera around:

i can’t seem to figure out how to keep the same view of the arms on all camera angles.

Here’s the code currently (LocalScript in StarterCharacterScripts):

local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Camera = workspace.CurrentCamera

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Head = Character:WaitForChild("Head")
local Torso = Character:WaitForChild("Torso")

local R_Arm = Character:WaitForChild("Right Arm")
local L_Arm = Character:WaitForChild("Left Arm")

local R_Shoulder = Torso["Right Shoulder"]
local L_Shoulder = Torso["Left Shoulder"]

local FPEvent

local function S(Arm)
	Arm.Changed:Connect(function()
		Arm.LocalTransparencyModifier = 0
	end)
end


S(R_Arm)
S(L_Arm)

for _,v in pairs(Character:GetDescendants()) do
	if v:IsA("BasePart") then
		v.Massless = true
	end
end

UIS.Changed:Connect(function(prop)
	if prop == "MouseBehavior" then
		if UIS.MouseBehavior == Enum.MouseBehavior.LockCenter then
			print("Player entered first person")
			FPEvent = RunService.RenderStepped:Connect(function()
				local LV = Camera.CFrame.LookVector
				local angle = math.acos(LV:Dot(Vector3.new(0,1,0)))
				
				R_Shoulder.C0 = CFrame.new(1,0.5,0) * CFrame.Angles(math.pi/2 - angle,math.pi/2,0)
				L_Shoulder.C0 = CFrame.new(-1,0.5,0) * CFrame.Angles(math.pi/2 - angle,math.pi + (math.pi/2),0)
			end)
		else
			print("Player exited first person")
			if FPEvent then
				FPEvent:Disconnect()
				FPEvent = nil
			end
		end
	end
end)

Any help is appreciated!

You would want a ViewModel for this.

You could use a viewmodel or i guess you could just animate the hands holding the soda in a way so the hands are closer to your camera.

im actually avoiding viewmodels because i want to skip the process of making another batch of animations for my tools. i did find a solution by assuming the camera as the player’s head.

            FPEvent = RunService.RenderStepped:Connect(function()
				local LV = Camera.CFrame.LookVector
				local angle = math.acos(LV:Dot(Vector3.new(0,1,0)))
				
				local R = CFrame.new(1,0.5,0) * CFrame.Angles(math.pi/2 - angle,math.pi/2,0)
				local L = CFrame.new(-1,0.5,0) * CFrame.Angles(math.pi/2 - angle,math.pi + (math.pi/2),0)
				
				local R2 = Head.CFrame:ToObjectSpace(Torso.CFrame * CFrame.new(1,0.5,0))
				local R3 = Torso.CFrame:ToObjectSpace(Camera.CFrame * R2) * CFrame.new(0,0,-0.5)
				
				local L2 = Head.CFrame:ToObjectSpace(Torso.CFrame * CFrame.new(-1,0.5,0))
				local L3 = Torso.CFrame:ToObjectSpace(Camera.CFrame * L2) * CFrame.new(0,0,-0.5)
				
				R_Shoulder.C0 = CFrame.new(R3.Position) * CFrame.Angles(math.pi/2 - angle,math.pi/2,0)
				L_Shoulder.C0 = CFrame.new(L3.Position) * CFrame.Angles(math.pi/2 - angle,math.pi + (math.pi/2),0)
			end)