How can I improve my custom camera?

I took this character camera script from another game, but sometimes it causes lag. How can I improve it?

local module = {}

module.enabled = true
module.mouseLocked = true
module.cameraLocked = false
module.cameraType = "FirstPerson"
module.character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait() :: Model?
module.distance = 0

local camera = game.Workspace.CurrentCamera
local mouse = game.Players.LocalPlayer:GetMouse()

local headOffset = CFrame.new(0, 2, -0.5)
local transparentAccessories = {
	Head = true;
	Hat = true;
	Hair = true
}

local lastMouseRotation = Vector2.zero
local mouseRotationY = 0
local lerpAmount = 0.5
local lastCameraUpdate = os.clock()
local mouseLocked = false


function module.updateCamera(char:Model, camera:Camera)
	if not char:FindFirstChild("Head") then return end
	if not char.Torso:FindFirstChild("Neck") then return end
	
	if module.cameraType == "FirstPerson" then
		char.Torso.Neck.C0 = CFrame.new(0, 1, 0)*CFrame.Angles(math.rad(90)+lastMouseRotation.X, math.rad(-180), 0)
		
		local mainCamCF = char.HumanoidRootPart.CFrame:ToWorldSpace(headOffset):ToWorldSpace(CFrame.Angles(lastMouseRotation.X, 0, 0))
		local camCF = mainCamCF:ToWorldSpace(CFrame.new(0, 0, 0))
		--local camCF = char.Head.CFrame:ToWorldSpace(CFrame.new(0, 0, -0.5))
		local rShoulder = char.Torso:WaitForChild("Right Shoulder")
		local lShoulder = char.Torso:WaitForChild("Left Shoulder")
		
		--rShoulder.C0 = rShoulder.C0:Lerp((camCF * CFrame.new(1, -1.25, -0)):ToObjectSpace(char.Torso.CFrame):Inverse() * CFrame.Angles(0, math.pi/2, 0), lerpAmount)
		--lShoulder.C0 = lShoulder.C0:Lerp((camCF * CFrame.new(-1, -1.25, -0)):ToObjectSpace(char.Torso.CFrame):Inverse() * CFrame.Angles(0, -math.pi/2, 0), lerpAmount)
		
		
		camera.CFrame = camCF
	else
		char.Torso.Neck.C0 = CFrame.new(0, 1, 0)*CFrame.Angles(math.rad(90), math.rad(-180), 0)
		
		local pos = (CFrame.new(char.Head.Position)*CFrame.Angles(0, lastMouseRotation.Y, 0):ToWorldSpace(CFrame.Angles(-lastMouseRotation.X, 0, 0))):ToWorldSpace(CFrame.new(0, 0, -module.distance)).Position
		
		camera.CFrame = CFrame.lookAt(pos, char.Head.Position)
	end
end

function module.updateLocalTransparency(char:Model)
	if module.cameraType == "FirstPerson" then
		for _, desc in char:GetDescendants() do
			if desc:IsA("Accessory") then
				if not transparentAccessories[desc.AccessoryType.Name] then
					desc.Handle.LocalTransparencyModifier = 0
				else
					desc.Handle.Transparency = 1
				end
			elseif desc:IsA("BasePart") then
				if desc.Name ~= "Head" and desc.Name ~= "Torso" then
					desc.LocalTransparencyModifier = 0
				else
					desc.LocalTransparencyModifier = 1
				end
			end
		end
	else
		for _, desc in char:GetDescendants() do
			if desc:IsA("BasePart") then
				desc.LocalTransparencyModifier = 0
			end
		end
	end
end

function module.updateCharRotation(char:Model, camera:Camera)
	if module.cameraType == "FirstPerson" then
		char.HumanoidRootPart.CFrame = char.HumanoidRootPart.CFrame:Lerp(CFrame.new(char.HumanoidRootPart.Position)*CFrame.Angles(0, lastMouseRotation.Y, 0), lerpAmount)
	end
end

function module.run()
	game.UserInputService.InputChanged:Connect(function (inp, gpe)
		if inp.UserInputType == Enum.UserInputType.MouseMovement and module.enabled and not module.cameraLocked then
			local lastY = lastMouseRotation.Y
			lastMouseRotation -= Vector2.new(math.rad(inp.Delta.Y), math.rad(inp.Delta.X))*UserSettings().GameSettings.MouseSensitivity
			lastMouseRotation = Vector2.new(math.clamp(lastMouseRotation.X, math.rad(-70), math.rad(70)), lastMouseRotation.Y)
			--mouseRotationY = lastMouseRotation.Y-lastY
		end
	end)
	
	game["Run Service"].Heartbeat:Connect(function ()
		camera.CameraType = Enum.CameraType.Scriptable
		
		if module.enabled then
			if module.character then
				module.updateCamera(module.character, camera)
				module.updateLocalTransparency(module.character)
				module.updateCharRotation(module.character, camera)
				
				--mouseRotationY = 0
				lastCameraUpdate = os.clock()

				if module.mouseLocked or mouseLocked then
					if module.cameraType == "Default" then
						game.UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
						game.UserInputService.MouseIconEnabled = true
					else
						game.UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
						game.UserInputService.MouseIconEnabled = false
					end
				else
					game.UserInputService.MouseBehavior = Enum.MouseBehavior.Default
					game.UserInputService.MouseIconEnabled = true
				end
				
				if module.character:FindFirstChildOfClass("Tool") then
					module.character.Torso["Right Shoulder"].C0 = module.character.Torso["Right Shoulder"].C0 * CFrame.new(0,0.15,-0.15)
				end
			end
		end
	end)
	
	mouse.Button2Down:Connect(function ()
		if module.cameraType == "Default" then
			mouseLocked = true
		end
	end)
	
	mouse.Button2Up:Connect(function ()
		if module.cameraType == "Default" then
			mouseLocked = false
		end
	end)
	
	game.ReplicatedStorage.Events.Client.CharacterCamera.Event:Connect(function (action:string, ...)
		local pars = {...}
		
		if action == "Set" then
			for i, v in pairs(pars[1]) do
				module[i] = v
			end
		end
	end)
end

return module

Just optimized the camera calculation a bit and it wont lag anymore

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