Smooth CameraController

Hello! I just made my first custom camera controller that provides a better and more smoother first person view and third person view! If there is anything that I could improve on

-- services

local Players    	    = game:GetService("Players")
local RunService 	    = game:GetService("RunService")
local UserInputService  = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- constants

local PLAYER = Players.LocalPlayer
local MOUSE    = PLAYER:GetMouse()
	MOUSE.Icon = "http://www.roblox.com/library/?id=3449846314"

local CHARACTER = PLAYER.Character or PLAYER.CharacterAdded:Wait()

local CAMERA = workspace.CurrentCamera or workspace.Camera

local EVENTS = ReplicatedStorage.Events 

local SET_TYPE = EVENTS.SetType
local GET_TYPE = EVENTS.GetType

local CAMERA_WEIGHT = 0.2
local CAMERA_SMOOTH = 0.05

local X,ABS_X = 0,0
local Y,ABS_Y = 0,0

local CAMERA_OFFSET = CFrame.new(2,-0.8,6) -- third person

local STATE       = false
local CAMERA_MODE = false

local BLACKLISTED_TYPES = {
	Head 	   = "Head",
}

-- functions

local function SetTransparency()
	if CAMERA and CHARACTER then
		for _,obj in pairs(CHARACTER:GetDescendants()) do
			if obj:IsA("Accessory") then
				if CAMERA_MODE then
					obj.Handle.LocalTransparencyModifier = 1
				elseif not CAMERA_MODE then
					obj.Handle.LocalTransparencyModifier = 0
				end
			elseif obj:IsA("BasePart") then
				obj.CanCollide = false
				obj.LocalTransparencyModifier = 1
				
				if not BLACKLISTED_TYPES[obj.Name] and CAMERA_MODE then
					obj.CastShadow = false
					obj.LocalTransparencyModifier = 0
				elseif not CAMERA_MODE then
					obj.CastShadow = true
					obj.LocalTransparencyModifier = 0
				end
			elseif obj:IsA("Decal") then
				if CAMERA_MODE then
					obj.LocalTransparencyModifier = 1
				elseif not CAMERA then
					obj.LocalTransparencyModifier = 0
				end
			end
		end		
	else
		warn("Unbinded Arms!")
		RunService:UnbindFromRenderStep("Arms")
	end
end

local function CameraWeight()
	if CAMERA and CHARACTER:WaitForChild("Humanoid",1) then
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

		X = X + (ABS_X - X) * 0.35 
		local dist = ABS_Y - Y 
		dist = math.abs(dist) > 180 and dist - (dist / math.abs(dist)) * 360 or dist 
		Y = (Y + dist * 0.35) %360
		
		CHARACTER.HumanoidRootPart.CFrame = CFrame.new(CHARACTER.HumanoidRootPart.Position) * CFrame.Angles(0,math.rad(Y),0)
		
		CAMERA.CameraType = Enum.CameraType.Scriptable
		CAMERA.CFrame     = CFrame.new(CHARACTER.Head.Position + Vector3.new(0,1,0))
			* CFrame.Angles(0,math.rad(Y),0)
			* CFrame.Angles(math.rad(X),0,0)
			* CAMERA_OFFSET
	else
		warn("Unbinded Camera!")
		RunService:UnbindFromRenderStep("Camera")	
	end
end

local function InputChange(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement then
		local delta = Vector2.new(input.Delta.x/CAMERA_WEIGHT,input.Delta.y/CAMERA_WEIGHT) * CAMERA_SMOOTH

		local X_EST = ABS_X - delta.y 
		ABS_X = (X_EST >= 80 and 80) or (X_EST <= -80 and -80) or X_EST 
		ABS_Y = (ABS_Y - delta.x) %360 
	end
end

local function StateChanged(state)
	STATE = state and true or false 
end

local function GetState()
	return STATE
end

local function ChangeCamera(input)
	if input.KeyCode == Enum.KeyCode.C then
		if CAMERA_MODE then
			CAMERA_OFFSET = CFrame.new(2,-0.8,6)
			CAMERA_MODE = false
		else
			CAMERA_OFFSET = CFrame.new(0,1,-0.5)
			CAMERA_MODE = true
		end
	end
end

GET_TYPE.OnInvoke = GetState
SET_TYPE.OnInvoke = StateChanged

UserInputService.InputBegan:Connect(ChangeCamera)
UserInputService.InputChanged:Connect(InputChange)

RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value,CameraWeight)
RunService:BindToRenderStep("Arms",Enum.RenderPriority.Last.Value,SetTransparency)
2 Likes

Hey, Just tested this! It looks great! One thing I would add to improve emersive camera quality is by adding a “dot” as a mouse icon and lowering the Y Vector for the first person view as it is very high and I am pretty much taller than everyone in game.

2 Likes

Hello! I’ve made some adjustments to the offset of BOTH camera modes but also make sure you grab the updated code if you want to use if (which I dont mind) as theres was this replication glitch when setting the HumanoidRootParts CFrame which I fixed :smiley: :+1:

1 Like

You know its good when you can disable the default Camera Module CFrame sets. Will def be forking this.

Im kinda new to coding and I am trying to use this, can someneone Help me, I cant get this to work.