Mouse Tilt Viewmodel Issue

Hello, I’m working on a camera system like bodycam and I have come across an issue.

The camera is buttery smooth but upon moving left or right with A and D the camera tilts like in the video.

game:GetService("RunService").RenderStepped:connect(function()
	checkfirstperson()
	if isfirstperson == true then
		visiblearms(true)
		local delta = uis:GetMouseDelta()
		rightshoulderclone.Transform = rightshoulder.Transform
		leftshoulderclone.Transform = leftshoulder.Transform
		local finalcf = (camera.CFrame*walksway*jumpsway*strafesway*CFrame.Angles(math.rad(sway.Y*swaysize),math.rad(sway.X*swaysize)/10,math.rad(sway.Z*swaysize)/2))+(camera.CFrame.UpVector*(-1.7-(headoffset.Y+(aimoffset.Value.Y))))+(camera.CFrame.LookVector*(headoffset.Z+(aimoffset.Value.Z)))+(camera.CFrame.RightVector*(-headoffset.X-(aimoffset.Value.X)+(-(sway.X*swaysize)/75)))			
		viewmodel:SetPrimaryPartCFrame(CFrame.new(finalcf.Position, Vector3.new(mouse.Hit.Position.X, mouse.Hit.Position.Y, mouse.Hit.Position.Z)))
		if character:FindFirstChildWhichIsA("Tool") then
			if camera.CameraType == Enum.CameraType.Custom then
				enableviewmodel()
			end
			camera.CameraType = Enum.CameraType.Scriptable
		else
			if camera.CameraType == Enum.CameraType.Scriptable then
				disableviewmodel()
			end
			camera.CameraType = Enum.CameraType.Custom
		end
		if camera.CameraType == Enum.CameraType.Scriptable then	
			rootpart.CFrame = rootpart.CFrame:Lerp(CFrame.new(rootpart.Position, Vector3.new(pos.X+5,0,pos.Z)),0.5)
			local divisor = 0.1
			camera.CFrame = camera.CFrame:Lerp(CFrame.new(character.Camera_Part.Position, Vector3.new(pos.X+5,0,pos.Z)),divisor)
		end
	end
end)

That is the script, I have narrowed it down to this part of it

		if camera.CameraType == Enum.CameraType.Scriptable then	
			rootpart.CFrame = rootpart.CFrame:Lerp(CFrame.new(rootpart.Position, Vector3.new(pos.X+5,0,pos.Z)),0.5)
			local divisor = 0.1
			camera.CFrame = camera.CFrame:Lerp(CFrame.new(character.Camera_Part.Position, Vector3.new(pos.X+5,0,pos.Z)),divisor)
		end

If I up the divisor, the A and D mouse tilt is completely gone. No tilt whatsoever. But the mouse becomes uncontrollable, as it moves too fast and the camera spins super quickly. If I lower the divisor again, the camera/mouse becomes manageable and smooth, but the A and D tilt comes back.

Oh yeah, the example I gave might’ve been vague, so basically the higher the lerp number the less control you have over your character, but the tilt is also lessened and the lower it is the more control you have over your character but the tilt is more pronounced.

The problem is that lerp is calculating the intermediate CFrame as something unintended.

Specifically, this line is generating a weird CFrame:

CFrame.new(character.Camera_Part.Position, Vector3.new(pos.X+5,0,pos.Z))

How is the pos variable defined? I don’t think I saw it in there.

Here are potential problems and fixes:

  • The camera is not positioned at character.Camera_Part.Position, so the position and orientation lerp is causing problems. Try adding Camera.CFrame -= Camera.CFrame.Position + character.Camera_Part.Position before doing the camera lerp
  • If that doesn’t fix it, you could try manually removing the camera’s roll:
-- (Use after setting the Camera.CFrame with the lerp)
-- Get roll angle
_, _, az = Camera.CFrame:ToEulerAnglesXYZ()
-- Make CFrame with opposite roll angle
oppositeRoll = CFrame.Angles(0, 0, -az)
-- Apply the opposite roll relatively to the CFrame
Camera.CFrame = Camera.CFrame:ToWorldSpace(oppositeRoll)
1 Like

pos is the players mouse position, here is the code getting pos

mouse.Move:Connect(function()
	if mouse.Target then
		if mouse.Target.Parent:FindFirstChild("Humanoid") then
			pos = mouse.Target.Position
		else
			pos = mouse.Hit.Position
		end
	else
		pos = mouse.Hit.Position
	end
end)

It is either the players mouse position, or the mouse’s target to allow easier aiming.

1 Like

Setting the Camera’s Roll partially works, but, I cannot turn behind myself. I have 180 degrees of vision pretty much, and upon hitting 0 or 180 the Camera will bug out and not allow me to turn any further. I cannot also look down, or it will tilt my Camera upside down while using the roll. Here’s a video:

1 Like

Ah, it appears my roll angle code is wrong: it gets the global z angle, not the relative one. I’m not sure how to get the relative roll besides doing a bunch of operations.

Good that it sort of works though. Please try this instead, it should remove the roll in all cases:

-- (Use after setting the Camera.CFrame with the lerp)
-- Removes the roll of the CFrame
Camera.CFrame = CFrame.lookAt(Camera.CFrame.Position, Camera.CFrame.Position + Camera.CFrame.LookVector)

(This approach to removing the roll is more straight forward, it creates a CFrame based on the look vector and position of the camera and uses the default up vector for the third parameter.)

(I tested the new code in studio and it seemed to remove roll properly.)

1 Like

This worked great, it maintained the smoothness and the tilt is practically non-existant! Thank you!

1 Like

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