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.
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.
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)
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.
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;
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