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)