Anyway to make camera move smoother?

So I am making some wonderful great code that puts the player in 3rd person, it works pretty well, but its really choppy, only problem is that most solutions I’ve seen requires setting the cameraType to scriptable, which would goof up my camera scripts.

So uh any solutions?

1 Like

It shouldn’t be choppy if you do it correctly

well uh yeah all I did was change the camera offset and put you in first person, so like . . .

Can you show footage of how it looks like?

1 Like

Is it client sided? Does it use RenderStepped, Stepped, Heartbeat or what?

it doesnt use any of them, again all it does, is set the cameraOffset, and the cameraMode to LockFirstPerson

It’s likely Roblox’s issue. I’ve had the same problem with CameraOffset and can’t do anything to fix it.

well yeah I assumed as much, just hoped I could find a way to fix it

You need to Lerp from one orientation to another over multiple frames. Every time you move your mouse right now your character instantly faces it

The camera will move exponentially faster the farther you offset it from the character. I think because of this, the camera is moving around so quickly that it looks choppy. You might be able to fix it by lowering the players mouse sensitivity when they get put in 3rd person. Check out this post that did it.

1 Like

It helps, but the screen is still jittering some.

Wouldnt this require custom coding the camera? AKA setting the CameraType to scriptable

1 Like

A coincidence that I just had a post including this script. Note that this is me taking the core parts of my script and removing all the extras, so it may not be fully functional and the indents are goofy, but you should be able to get some inspiration on how a custom system would work.

local RunService = game:GetService("RunService")
camera.CameraType = Enum.CameraType.Scriptable
local cameraSensitivity = 0.3
cameraOffset = Vector3.new(1.3, 2, 10)

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

--Update the camera every frame
local function updateCamera()

	--Get the player's mouse values
	local delta = UserInputService:GetMouseDelta()

	cameraRotationX = cameraRotationX - delta.Y * cameraSensitivity
	cameraRotationY = cameraRotationY - delta.X * cameraSensitivity

	cameraRotationX = math.clamp(cameraRotationX, -45, 45)
	
--Rotate the HRP
	local targetPart = thePartYouWantToRotateAround (usually the humanoidrootpart)

    if targetPart then
        targetPart.CFrame = CFrame.new(targetPart.Position) * CFrame.Angles(0,math.rad(cameraRotationY),0)
    end

		--Calculate the new camera position and rotation
		local desiredCameraCFrame = CFrame.new(targetPart.Position)
			* CFrame.Angles(0, math.rad(cameraRotationY), 0)
			* CFrame.Angles(math.rad(cameraRotationX), 0, 0)
			* CFrame.new(cameraOffset)

--Adjust the camera
        camera.CFrame = desiredCameraCFrame
end

--Loop call
RunService.RenderStepped:Connect(updateCamera)

--Handle character respawn
local function onCharacterAdded(newCharacter)
	camera.CameraSubject = newCharacter:WaitForChild("Humanoid")
	character = newCharacter
    hrp = character:WaitForChild("HumanoidRootPart")
end

--
player.CharacterAdded:Connect(onCharacterAdded)
2 Likes

Hey so I got most of the code ready to go, my only question is what would cameraRotationX and cameraRotationY be?

1 Like

Those decide how much the camera should rotate around the X and Y axis.
I’m not sure on the math, but you can see the values are being used when rotating both the targetPart and the camera. It is derived from your mouse’s delta which seems to be some sort of pre-frame calculation that the engine does, and of course the sensitivity which is multiplied on the rotation value so that makes sense: higher sensitivity = more rotation when it’s multiplied on the rotation calculation.

Edit: and as you can see you also need to have mouselockcenter on.
This causes the camera to go through objects, so you’ll need a raycast to create a hitbox for the camera, which is what I’m using. The good news is that this also allows you to block parts you’d normally be able to see through like non-collidable parts.

Ok so incase I was like struggling to figure out what all of that meant, could you explain this in very simple terms?


Ooo that sounds like fun to make lol

I don’t understand the math fully. It’s not needed, but useful yes.
I consider it enough to understand the steps to the script and what each variable is used for, so that this;

cameraRotationX = cameraRotationX - delta.Y * cameraSensitivity
cameraRotationY = cameraRotationY - delta.X * cameraSensitivity

sets the rotation by using the 3 values we know what are. Delta being the movement distance of the mouse and sensitivity being the multiplier like any camera has. Why is it using the “-” operator instead of “+” I cannot tell you, but I’ve decided that it’s not worth it for me to understand all the math.

The latter part is just applying the rotation values of the objects with the CFrame.Angles(). Math.rad() is to translate the values from angles 0-360. It’s using the Y rotation here because for some reason when you rotate a character the Y value is the horizontal rotation value, which is what we need to change on the humanoidrootpart.

    if targetPart then
        targetPart.CFrame = CFrame.new(targetPart.Position) * CFrame.Angles(0,math.rad(cameraRotationY),0)
    end

Oh wait I see, ok so I wasnt worried about what the math was doing, more of um:

yeah you reference this here and subtract delta.Y from it:

But its never defined, so like what should it be?

1 Like

This is indeed defined as 0 at the top of the script yes. Forgot to include it.

-- Variables to keep track of camera angles
local cameraRotationX = 0
local cameraRotationY = 0
1 Like

I think this post might interest you Camera Coding (Setting the offset) - #4 by daireb

1 Like