Forking the camera scripts is a lot less simpler. Now you have to maintain that and update it whenever Roblox does.
For R6 you just mess around with the C0 of the Left/RightShoulders inside their torso.
local left_shoulder = torso:WaitForChild("Left Shoulder")
local right_shoulder = torso:WaitForChild("Right Shoulder")
local left_c0 = left_shoulder.C0
local right_c0 = right_shoulder.C0
local NINETY_DEGREES = CFrame.Angles(0, math.pi/2, 0)
local NEG_NINETY_DEGREES = CFrame.Angles(0, -math.pi/2, 0)
From there you want to get the rotation of the camera and torso, multiply the base C0 by -90 degrees, then get the torso rotation relative to the camera’s, then multiply that by 90 degrees.
local camera_rotation = camera.CFrame - camera.CFrame.Position
local torso_rotation = torso.CFrame - torso.Position
right_shoulder.C0 = right_c0*NEG_NINETY_DEGREES*torso_rotation:ToObjectSpace(camera_rotation)*NINETY_DEGREES
right_shoulder.Transform = CFrame.Angles(0, 0, math.pi/2)
left_shoulder.C0 = left_c0*NINETY_DEGREES*torso_rotation:ToObjectSpace(camera_rotation)*NEG_NINETY_DEGREES
left_shoulder.Transform = CFrame.Angles(0, 0, math.pi/2)
You do basically the same on the left shoulder except you multiply everything else by positive 90 degrees otherwise the arm will be backwards.
Do note that this does not replicate to the server so you will need a remote event. You would be doing this code in the same RenderStepped
listener you had for making the arms visible.
To make it replicate to the server you would need to use a remote but firing a remote 60 times a second isn’t very fun for the server. So cutting that down to perhaps 10 times a second, would still look good for the other players.
Btw you would pass the camera’s rotation and base C0’s to the server.
here is some code I used
game:GetService("ReplicatedStorage").Tilt.OnServerEvent:Connect(function(player, left_c0, right_c0, camera_rotation)
local character = player.Character
local torso = character.Torso
local left_shoulder = torso["Left Shoulder"]
local right_shoulder = torso["Right Shoulder"]
local torso_rotation = torso.CFrame - torso.Position
right_shoulder.C0 = right_c0*NEG_NINETY_DEGREES*torso_rotation(camera_rotation)*NINETY_DEGREES
right_shoulder.Transform = CFrame.Angles(0, 0, math.pi/2)
left_shoulder.C0 = left_c0*NINETY_DEGREES*torso_rotation:ToObjectSpace(camera_rotation)*NEG_NINETY_DEGREES
left_shoulder.Transform = CFrame.Angles(0, 0, math.pi/2)
end)
Then every 0.1 seconds you can fire the remote to the server
while true do
tilt_remote:FireServer(left_c0, right_c0, camera_rotation)
wait(0.1)
end