Viewmodel (actually character) arms move with jitter when rotating camera

Looking around in first person causes this jittery effect to occur:


Code follows.

local limbStuff = {
	head = {
		motor = torso:WaitForChild("Neck") :: Motor6D,
		default = CFrame.new(0, 1, 0) * CFrame.Angles(math.rad(-90), math.rad(-180), 0),
		last = CFrame.new(0, 1, 0) * CFrame.Angles(math.rad(-90), math.rad(-180), 0)
	},
	rightarm = {
		motor = torso:WaitForChild("Right Shoulder") :: Motor6D,
		default = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, math.rad(90), 0),
		last = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, math.rad(90), 0)
	},
	leftarm = {
		motor = torso:WaitForChild("Left Shoulder") :: Motor6D,
		default = CFrame.new(-1, 0.5, 0) * CFrame.Angles(0, math.rad(-90), 0),
		last = CFrame.new(-1, 0.5, 0) * CFrame.Angles(0, math.rad(-90), 0)
	},
}

-- Functions

local function fp()
	if head and head.LocalTransparencyModifier >= 0.9 then
		return true
	end
	
	return false
end

local function tween(sender: Player, data: {})
	for _, v in next, data do
		local joint = nil
		local cframe = nil

		for _, v in next, v do
			if typeof(v) == "Instance" and v:IsA("Motor6D") then
				joint = v
			elseif typeof(v) == "CFrame" then
				cframe = v
			end
		end

		if joint and cframe then
			if fp() then
				joint.C0 = cframe -- not tween noob
			else
				TweenService:Create(
					joint,
					TweenInfo.new(sender == player and 0.1 or 0.2),
					{ C0 = cframe }
				):Play()
			end
			
			--joint.C0 = cframe
		end
	end
end

local function arms()
	local camDirection = rootPart.CFrame:ToObjectSpace(camera.CFrame).LookVector
	local something = math.asin(camDirection.Y)
	
	rightArm.LocalTransparencyModifier = rightArm.Transparency
	leftArm.LocalTransparencyModifier = rightArm.Transparency
	
	local data = {
		{limbStuff.head.motor, CFrame.new(0, limbStuff.head.default.Y, 0) 
			* CFrame.Angles(3 * math.pi / 2, 0, math.pi) 
			* CFrame.Angles(0, 0, -math.asin(camDirection.X))
			* CFrame.Angles(-math.asin(camDirection.Y), 0, 0)},
		{limbStuff.rightarm.motor, limbStuff.rightarm.default},
		{limbStuff.leftarm.motor, limbStuff.leftarm.default}
	}
	
	if fp() then
		-- this noob
		data[2][2] = torso.CFrame:ToObjectSpace(camera.CFrame) * CFrame.new(1, -1.25, -0.9) * CFrame.Angles(0, math.rad(90), 0)
		data[3][2] = torso.CFrame:ToObjectSpace(camera.CFrame) * CFrame.new(-1, -1.25, -0.9) * CFrame.Angles(0, math.rad(-90), 0)
	elseif character:FindFirstChildOfClass("Tool") then
		data[2][2] = limbStuff.rightarm.default * CFrame.Angles(0, 0, something)
		data[3][2] = limbStuff.leftarm.default * CFrame.Angles(0, 0, -something)
	end
	
	tween(player, data)
	
	replicateEvent:FireServer(data)
end

-- Main

RunService.RenderStepped:Connect(arms)

Pretty much tweening, would fix that jitteriness.

2 Likes

i think using a .RenderStepped or :BindToRenderStep() would be a lot better than this

This is just what kinda happens when you edit the Motor6D like this. What you can do is create a fake clone of the character (which will be the viewmodel) by making a fake humanoid root part, torso, arms, etc. (make sure to create the Motor6D clones too) And you can pivot that viewmodel to the camera and make it invisible in third person. To get it to animate, in that RenderStep loop you can change the viewmodel’s arms’ Motor6D transforms to your real character’s arms’ Motor6D transforms Motor6D | Documentation - Roblox Creator Hub. Then you can just remove the real arms anti transparency since you wont need that anymore and still edit their Motor6Ds (for third person). Then in a seperate while loop that has a time interval of a second or two, you can fire that remote to replicate your real arm movement and tween it for everyone else except you. Sorry if this was a bit confusing, I don’t really teach well. Hopefully this helped!