I’m making a game where you fight enemies in waves and I am trying to implement a feature that allows players to see a “Freecam mode” text whenever they are dead to let them know they are in the free cam. However I noticed in the default free cam provided by Roblox, it sets all screen guis to disabled whenever in free cam mode. There is a part of the script that defines some user settings but I am not sure how to change these setting or set them to true or false. I’ve read the documentation and looked it on google about the usersettings but I have not seen anything.
--!nonstrict
------------------------------------------------------------------------
-- Freecam
-- Cinematic free camera for spectating and video production.
--
-- Camera Positioning:
-- WASD / UHJK / Thumbstick1 to move camera forward, left, backward, right
-- MouseButton2 / Thumbstick2 to rotate camera (full 360 degree rotation in all axes)
-- Q,E / Y,I / L2,R2 to to move camera up, down
-- Z,C / L1,R1 to tilt camera left, right (double-tap Z,C,L1,R1 to reset to 0 degree tilt)
-- Down,Up / DpadDown,DpadUp to adjust movement speed
-- Left,Right / DpadLeft,DpadRight to adjust zoom speed
-- , and . to adjust tilt speed
--
-- Smoothness:
-- [ , ] - movement
-- ; , ' - panning
-- V , B - zoom
-- N , M - tilt
--
-- Depth Of Field: (this setting will disable all existing depth of field effects set by the game creators and enable you to manually control your own depth of field effect in the freecam)
-- \ - toggle
-- Shift and [ or ] : Increase/Decrease FarIntensity
-- Ctrl and [ or ] : Increase/Decrease NearIntensity
-- - or + : Increase/Decrease FocusDistance
-- Shift and - or + : Increase/Decrease InFocusRadius
--
-- Player Lock: (this setting centers focus around a selected player)
-- / - toggle
-- R, T - cycle between players
--
-- Custom GUI:
-- G - toggle custom Freecam GUI
-- X - toggle visible game UI
-- L - toggle player list
------------------------------------------------------------------------
local pi = math.pi
local abs = math.abs
local clamp = math.clamp
local exp = math.exp
local rad = math.rad
local sign = math.sign
local sqrt = math.sqrt
local tan = math.tan
local ContextActionService = game:GetService("ContextActionService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local Settings = UserSettings()
local GameSettings = Settings.GameSettings
local Lighting = game:GetService("Lighting")
local LocalPlayer = Players.LocalPlayer
if not LocalPlayer then
Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
LocalPlayer = Players.LocalPlayer
end
local playerGui = nil
local freecamGui = nil
local Camera = Workspace.CurrentCamera
Workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
local newCamera = Workspace.CurrentCamera
if newCamera then
Camera = newCamera
end
end)
local FreecamDepthOfField = nil
local customGui = nil
local PlayerState = nil
local FFlagUserExitFreecamBreaksWithShiftlock
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserExitFreecamBreaksWithShiftlock")
end)
FFlagUserExitFreecamBreaksWithShiftlock = success and result
end
local FFlagUserShowGuiHideToggles
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserShowGuiHideToggles")
end)
FFlagUserShowGuiHideToggles = success and result
end
local FFlagUserFixFreecamDeltaTimeCalculation
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFixFreecamDeltaTimeCalculation")
end)
FFlagUserFixFreecamDeltaTimeCalculation = success and result
end
local FFlagUserFixFreecamGuiChangeVisibility
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFixFreecamGuiChangeVisibility2")
end)
FFlagUserFixFreecamGuiChangeVisibility = success and result
end
local FFlagUserFreecamControlSpeed
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamControlSpeed")
end)
FFlagUserFreecamControlSpeed = success and result
end
local FFlagUserFreecamTiltControl
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamTiltControl")
end)
FFlagUserFreecamTiltControl = success and result
end
local FFlagUserFreecamSmoothnessControl
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamSmoothnessControl")
end)
FFlagUserFreecamSmoothnessControl = success and result
end
local FFlagUserFreecamGuiDestabilization
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamGuiDestabilization")
end)
FFlagUserFreecamGuiDestabilization = success and result
end
local FFlagUserFreecamDepthOfFieldEffect
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamDepthOfFieldEffect3")
end)
FFlagUserFreecamDepthOfFieldEffect = success and result
end
local FFlagUserFreecamPlayerLock
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamPlayerLock2")
end)
FFlagUserFreecamPlayerLock = success and result
end
local FFlagUserFreecamPlayerLockResetHeight
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamPlayerLockResetHeight")
end)
FFlagUserFreecamPlayerLockResetHeight = success and result
end
local FFlagUserFreecamCustomGui
do
local success, result = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserFreecamCustomGui")
end)
FFlagUserFreecamCustomGui = success and result
end
------------------------------------------------------------------------
local FREECAM_ENABLED_ATTRIBUTE_NAME = "FreecamEnabled"
local TOGGLE_INPUT_PRIORITY = Enum.ContextActionPriority.Low.Value
local INPUT_PRIORITY = Enum.ContextActionPriority.High.Value
local FREECAM_MACRO_KB = {Enum.KeyCode.LeftShift, Enum.KeyCode.P}
local FREECAM_TILT_RESET_KB = {
[Enum.KeyCode.Z] = true,
[Enum.KeyCode.C] = true
}
local FREECAM_TILT_RESET_GP = {
[Enum.KeyCode.ButtonL1] = true,
[Enum.KeyCode.ButtonR1] = true
}
local FREECAM_DOF_TOGGLE = {
[Enum.KeyCode.BackSlash] = true
}
local FREECAM_PLAYER_LOCK_TOGGLE = {[Enum.KeyCode.Slash] = true}
local FREECAM_PLAYER_LOCK_SWITCH = {
[Enum.KeyCode.R] = true,
[Enum.KeyCode.T] = true
}
local FREECAM_CUSTOM_GUI_TOGGLE = {
[Enum.KeyCode.G] = true
}
local FREECAM_PLAYER_GUI_TOGGLE = {
[Enum.KeyCode.X] = true
}
local FREECAM_LEADERBOARD_TOGGLE = {
[Enum.KeyCode.L] = true
}
local NAV_GAIN = Vector3.new(1, 1, 1)*64
local PAN_GAIN = Vector2.new(0.75, 1)*8
local FOV_GAIN = 300
local ROLL_GAIN = -pi/2
local PITCH_LIMIT = rad(90)
local VEL_STIFFNESS = 1.5
local PAN_STIFFNESS = 1.0
local FOV_STIFFNESS = 4.0
local ROLL_STIFFNESS = 1.0
local VEL_ADJ_STIFFNESS = 0.75
local PAN_ADJ_STIFFNESS = 0.75
local FOV_ADJ_STIFFNESS = 0.75
local ROLL_ADJ_STIFFNESS = 0.75
local VEL_MIN_STIFFNESS = 0.01
local PAN_MIN_STIFFNESS = 0.01
local FOV_MIN_STIFFNESS = 0.01
local ROLL_MIN_STIFFNESS = 0.01
local VEL_MAX_STIFFNESS = 10.0
local PAN_MAX_STIFFNESS = 10.0
local FOV_MAX_STIFFNESS = 10.0
local ROLL_MAX_STIFFNESS = 10.0
local lastPressTime = {}
local lastResetTime = 0
local DOUBLE_TAP_TIME_THRESHOLD = 0.25
local DOUBLE_TAP_DEBOUNCE_TIME = 0.1
local postEffects = {}
local playerGuiConnection = nil
local cameraConnection = nil
local lightingConnection = nil
local playerAddedConnection = nil
local playerRemovingConnection = nil
local PLAYER_LOCK_DEFAULT_ZOOM = 20
local PLAYER_LOCK_MIN_ZOOM = 5
local PLAYER_LOCK_MAX_ZOOM = 50
local PLAYER_LOCK_DEFAULT_HEIGHT = 0
local PLAYER_LOCK_HEIGHT_RANGE = 10
local playerLockEnabled = false
local playerLockZoom = 20
local playerLockHeight = 0
local playerList = {}
local currentTargetIndex = 1
local rootPart = nil
local screenGuisEnabled = false
local leaderboardEnabled = false
------------------------------------------------------------------------
local Spring = {} do
Spring.__index = Spring
function Spring.new(freq, pos)
local self = setmetatable({}, Spring)
self.f = freq
self.p = pos
self.v = pos*0
return self
end
function Spring:Update(dt, goal)
local f = self.f*2*pi
local p0 = self.p
local v0 = self.v
local offset = goal - p0
local decay = exp(-f*dt)
local p1 = goal + (v0*dt - offset*(f*dt + 1))*decay
local v1 = (f*dt*(offset*f - v0) + v0)*decay
self.p = p1
self.v = v1
return p1
end
function Spring:SetFreq(freq)
self.f = freq
end
function Spring:Reset(pos)
self.p = pos
self.v = pos*0
end
end
------------------------------------------------------------------------
local cameraPos = Vector3.new()
local cameraRot
if FFlagUserFreecamTiltControl then
cameraRot = Vector3.new()
else
cameraRot = Vector2.new()
end
local cameraFov = 0
local velSpring = Spring.new(VEL_STIFFNESS, Vector3.new())
local panSpring = Spring.new(PAN_STIFFNESS, Vector2.new())
local fovSpring = Spring.new(FOV_STIFFNESS, 0)
local rollSpring = Spring.new(ROLL_STIFFNESS, 0)
------------------------------------------------------------------------
local Input = {} do
local thumbstickCurve do
local K_CURVATURE = 2.0
local K_DEADZONE = 0.15
local function fCurve(x)
return (exp(K_CURVATURE*x) - 1)/(exp(K_CURVATURE) - 1)
end
local function fDeadzone(x)
return fCurve((x - K_DEADZONE)/(1 - K_DEADZONE))
end
function thumbstickCurve(x)
return sign(x)*clamp(fDeadzone(abs(x)), 0, 1)
end
end
local gamepad = {
ButtonX = 0,
ButtonY = 0,
DPadDown = 0,
DPadUp = 0,
DPadLeft = 0,
DPadRight = 0,
ButtonL2 = 0,
ButtonR2 = 0,
ButtonL1 = 0,
ButtonR1 = 0,
Thumbstick1 = Vector2.new(),
Thumbstick2 = Vector2.new(),
}
local keyboard = {
W = 0,
A = 0,
S = 0,
D = 0,
E = 0,
Q = 0,
U = 0,
H = 0,
J = 0,
K = 0,
I = 0,
Y = 0,
Up = 0,
Down = 0,
Left = 0,
Right = 0,
LeftShift = 0,
RightShift = 0,
Z = 0,
C = 0,
Comma = 0,
Period = 0,
LeftBracket = 0,
RightBracket = 0,
Semicolon = 0,
Quote = 0,
V = 0,
B = 0,
N = 0,
M = 0,
BackSlash = 0,
Minus = 0,
Equals = 0,
Slash = 0,
R = 0,
T = 0,
G = 0,
X = 0,
L = 0
}
local mouse = {
Delta = Vector2.new(),
MouseWheel = 0,
}
local DEFAULT_FPS = 60
local NAV_GAMEPAD_SPEED = Vector3.new(1, 1, 1)
local NAV_KEYBOARD_SPEED = Vector3.new(1, 1, 1)
local PAN_MOUSE_SPEED = Vector2.new(1, 1)*(pi/64)
local PAN_MOUSE_SPEED_DT = PAN_MOUSE_SPEED/DEFAULT_FPS
local PAN_GAMEPAD_SPEED = Vector2.new(1, 1)*(pi/8)
local FOV_WHEEL_SPEED = 1.0
local FOV_WHEEL_SPEED_DT = FOV_WHEEL_SPEED/DEFAULT_FPS
local FOV_GAMEPAD_SPEED = 0.25
local ROLL_GAMEPAD_SPEED = 1.0
local ROLL_KEYBOARD_SPEED = 1.0
local NAV_ADJ_SPEED = 0.75
local NAV_MIN_SPEED = 0.01
local NAV_MAX_SPEED = 4.0
local NAV_SHIFT_MUL = 0.25
local FOV_ADJ_SPEED = 0.75
local FOV_MIN_SPEED = 0.01
local FOV_MAX_SPEED = 4.0
local ROLL_ADJ_SPEED = 0.75
local ROLL_MIN_SPEED = 0.01
local ROLL_MAX_SPEED = 4.0
local DoFConstants = {
FarIntensity = {
ADJ = 0.1,
MIN = 0.0,
MAX = 1.0,
},
NearIntensity = {
ADJ = 0.1,
MIN = 0.0,
MAX = 1.0,
},
FocusDistance = {
ADJ = 20.0,
MIN = 0.0,
MAX = 200.0,
},
FocusRadius = {
ADJ = 5.0,
MIN = 0.0,
MAX = 50.0,
},
}
local navSpeed = 1
local rollSpeed = 1
local fovSpeed = 1
function Input.Vel(dt)
if FFlagUserFreecamControlSpeed then
navSpeed = clamp(navSpeed + dt*(keyboard.Up - keyboard.Down + gamepad.DPadUp - gamepad.DPadDown)*NAV_ADJ_SPEED, NAV_MIN_SPEED, NAV_MAX_SPEED)
else
navSpeed = clamp(navSpeed + dt*(keyboard.Up - keyboard.Down)*NAV_ADJ_SPEED, 0.01, 4)
end
local kGamepad = Vector3.new(
thumbstickCurve(gamepad.Thumbstick1.X),
thumbstickCurve(gamepad.ButtonR2) - thumbstickCurve(gamepad.ButtonL2),
thumbstickCurve(-gamepad.Thumbstick1.Y)
)*NAV_GAMEPAD_SPEED
local kKeyboard = Vector3.new(
keyboard.D - keyboard.A + keyboard.K - keyboard.H,
keyboard.E - keyboard.Q + keyboard.I - keyboard.Y,
keyboard.S - keyboard.W + keyboard.J - keyboard.U
)*NAV_KEYBOARD_SPEED
local shift = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
return (kGamepad + kKeyboard)*(navSpeed*(shift and NAV_SHIFT_MUL or 1))
end
function Input.Pan(dt)
local kGamepad = Vector2.new(
thumbstickCurve(gamepad.Thumbstick2.Y),
thumbstickCurve(-gamepad.Thumbstick2.X)
)*PAN_GAMEPAD_SPEED
local kMouse = mouse.Delta*PAN_MOUSE_SPEED
if FFlagUserFixFreecamDeltaTimeCalculation then
if dt > 0 then
kMouse = (mouse.Delta/dt)*PAN_MOUSE_SPEED_DT
end
end
mouse.Delta = Vector2.new()
return kGamepad + kMouse
end
function Input.Fov(dt)
if FFlagUserFreecamControlSpeed then
fovSpeed = clamp(fovSpeed + dt*(keyboard.Right - keyboard.Left + gamepad.DPadRight - gamepad.DPadLeft)*FOV_ADJ_SPEED, FOV_MIN_SPEED, FOV_MAX_SPEED)
end
local kGamepad = (gamepad.ButtonX - gamepad.ButtonY)*FOV_GAMEPAD_SPEED
local kMouse = mouse.MouseWheel*FOV_WHEEL_SPEED
if FFlagUserFixFreecamDeltaTimeCalculation then
if dt > 0 then
kMouse = (mouse.MouseWheel/dt)*FOV_WHEEL_SPEED_DT
end
end
mouse.MouseWheel = 0
if FFlagUserFreecamControlSpeed then
return (kGamepad + kMouse)*fovSpeed
else
return kGamepad + kMouse
end
end
function Input.Roll(dt)
rollSpeed = clamp(rollSpeed + dt*(keyboard.Period - keyboard.Comma)*ROLL_ADJ_SPEED, ROLL_MIN_SPEED, ROLL_MAX_SPEED)
local kGamepad = (gamepad.ButtonR1 - gamepad.ButtonL1)*ROLL_GAMEPAD_SPEED
local kKeyboard = (keyboard.C - keyboard.Z)*ROLL_KEYBOARD_SPEED
return (kGamepad + kKeyboard)*rollSpeed
end
function Input.SpringControl(dt)
if FFlagUserFreecamDepthOfFieldEffect then
local shiftIsDown = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
local ctrlIsDown = UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or UserInputService:IsKeyDown(Enum.KeyCode.RightControl)
if shiftIsDown or ctrlIsDown then
return -- reserve Shift+Keybinds for other actions, in this case Shift+Brackets for Depth of Field controls
end
end
VEL_STIFFNESS = clamp(VEL_STIFFNESS + dt*(keyboard.RightBracket - keyboard.LeftBracket)*VEL_ADJ_STIFFNESS, VEL_MIN_STIFFNESS, VEL_MAX_STIFFNESS)
velSpring:SetFreq(VEL_STIFFNESS)
PAN_STIFFNESS = clamp(PAN_STIFFNESS + dt*(keyboard.Quote - keyboard.Semicolon)*PAN_ADJ_STIFFNESS, PAN_MIN_STIFFNESS, PAN_MAX_STIFFNESS)
panSpring:SetFreq(PAN_STIFFNESS)
FOV_STIFFNESS = clamp(FOV_STIFFNESS + dt*(keyboard.B - keyboard.V)*FOV_ADJ_STIFFNESS, FOV_MIN_STIFFNESS, FOV_MAX_STIFFNESS)
fovSpring:SetFreq(FOV_STIFFNESS)
ROLL_STIFFNESS = clamp(ROLL_STIFFNESS + dt*(keyboard.M - keyboard.N)*ROLL_ADJ_STIFFNESS, ROLL_MIN_STIFFNESS, ROLL_MAX_STIFFNESS)
rollSpring:SetFreq(ROLL_STIFFNESS)
end
function Input.DoF(dt)
local shiftIsDown = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
local ctrlIsDown = UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or UserInputService:IsKeyDown(Enum.KeyCode.RightControl)
if shiftIsDown then
FreecamDepthOfField.FarIntensity = clamp(
FreecamDepthOfField.FarIntensity + dt * (keyboard.RightBracket - keyboard.LeftBracket) * DoFConstants.FarIntensity.ADJ,
DoFConstants.FarIntensity.MIN,
DoFConstants.FarIntensity.MAX
)
FreecamDepthOfField.InFocusRadius = clamp(
FreecamDepthOfField.InFocusRadius + dt * (keyboard.Equals - keyboard.Minus) * DoFConstants.FocusRadius.ADJ,
DoFConstants.FocusRadius.MIN,
DoFConstants.FocusRadius.MAX
)
elseif ctrlIsDown then
FreecamDepthOfField.NearIntensity = clamp(
FreecamDepthOfField.NearIntensity + dt * (keyboard.RightBracket - keyboard.LeftBracket) * DoFConstants.NearIntensity.ADJ,
DoFConstants.NearIntensity.MIN,
DoFConstants.NearIntensity.MAX
)
else
FreecamDepthOfField.FocusDistance = clamp(
FreecamDepthOfField.FocusDistance + dt * (keyboard.Equals - keyboard.Minus) * DoFConstants.FocusDistance.ADJ,
DoFConstants.FocusDistance.MIN,
DoFConstants.FocusDistance.MAX
)
end
end
do
local function resetKeys(keys, table)
for keyEnum, _ in pairs(keys) do
if table[keyEnum.Name] then
table[keyEnum.Name] = 0
end
end
end
local function handleDoubleTapReset(keyCode)
local currentTime = os.clock()
local previousPressTime = lastPressTime[keyCode]
local timeSinceLastPress = previousPressTime and (currentTime - previousPressTime) or -1
if previousPressTime and (timeSinceLastPress <= DOUBLE_TAP_TIME_THRESHOLD) then
if (currentTime - lastResetTime) >= DOUBLE_TAP_DEBOUNCE_TIME then
cameraRot = Vector3.new(cameraRot.x, cameraRot.y, 0)
rollSpring:Reset(0)
if FFlagUserFreecamDepthOfFieldEffect then
resetKeys(FREECAM_TILT_RESET_GP, gamepad)
resetKeys(FREECAM_TILT_RESET_KB, keyboard)
else
gamepad.ButtonL1 = 0
gamepad.ButtonR1 = 0
keyboard.C = 0
keyboard.Z = 0
end
lastResetTime = currentTime
end
end
lastPressTime[keyCode] = currentTime
end
local function findPlayerLockRootPart(switchDirection)
if not playerList or #playerList < 1 then
return nil
end
for i = 1, #playerList do
currentTargetIndex = ((currentTargetIndex - 1) + switchDirection) % #playerList + 1
local targetPlayer = playerList[currentTargetIndex]
local targetCharacter = targetPlayer and targetPlayer.Character
if targetCharacter then
local humanoid = targetCharacter:FindFirstChildOfClass("Humanoid")
if humanoid and humanoid.RootPart then
return humanoid.RootPart
end
end
if switchDirection == 0 then
switchDirection = 1 -- if re-enabling player lock and the previous character wasn't found, start iterating for next character
end
end
playerLockEnabled = false -- couldn't find a valid lockable root part
return nil
end
local function Keypress(action, state, input)
keyboard[input.KeyCode.Name] = state == Enum.UserInputState.Begin and 1 or 0
if FFlagUserFreecamTiltControl then
if FREECAM_TILT_RESET_KB[input.KeyCode] and input.UserInputState == Enum.UserInputState.Begin then
handleDoubleTapReset(input.KeyCode)
end
end
if FFlagUserFreecamDepthOfFieldEffect then
if FREECAM_DOF_TOGGLE[input.KeyCode] and input.UserInputState == Enum.UserInputState.Begin then
if not FreecamDepthOfField.Enabled then
postEffects = {}
-- Disable all existing DepthOfFieldEffects to be controlled by custom Freecam DoF.
for _, effect in ipairs(Camera:GetChildren()) do
if effect:IsA("DepthOfFieldEffect") and effect.Enabled then
postEffects[#postEffects + 1] = effect
effect.Enabled = false
end
end
for _, effect in ipairs(Lighting:GetChildren()) do
if effect:IsA("DepthOfFieldEffect") and effect.Enabled then
postEffects[#postEffects + 1] = effect
effect.Enabled = false
end
end
cameraConnection = Camera.ChildAdded:Connect(function(child)
if child:IsA("DepthOfFieldEffect") and child.Enabled then
postEffects[#postEffects + 1] = child
child.Enabled = false
end
end)
lightingConnection = Lighting.ChildAdded:Connect(function(child)
if child:IsA("DepthOfFieldEffect") and child.Enabled then
postEffects[#postEffects + 1] = child
child.Enabled = false
end
end)
else
-- Re-enable all existing DepthOfFieldEffects when custom Freecam DoF is off.
for _, effect in ipairs(postEffects) do
if effect.Parent then
effect.Enabled = true
end
end
if cameraConnection then
cameraConnection:Disconnect()
cameraConnection = nil
end
if lightingConnection then
lightingConnection:Disconnect()
lightingConnection = nil
end
postEffects = {}
end
FreecamDepthOfField.Enabled = not FreecamDepthOfField.Enabled
resetKeys(FREECAM_DOF_TOGGLE, keyboard)
end
end
if FFlagUserFreecamPlayerLock then
if FREECAM_PLAYER_LOCK_TOGGLE[input.KeyCode] and input.UserInputState == Enum.UserInputState.Begin then
playerLockEnabled = not playerLockEnabled
if playerLockEnabled then
playerLockZoom = PLAYER_LOCK_DEFAULT_ZOOM
if FFlagUserFreecamPlayerLockResetHeight then
playerLockHeight = PLAYER_LOCK_DEFAULT_HEIGHT
end
rootPart = findPlayerLockRootPart(0)
end
resetKeys(FREECAM_PLAYER_LOCK_TOGGLE, keyboard)
end
if FREECAM_PLAYER_LOCK_SWITCH[input.KeyCode] and input.UserInputState == Enum.UserInputState.Begin then
if playerLockEnabled and #playerList > 0 then
local switchDirection = keyboard.T - keyboard.R
rootPart = findPlayerLockRootPart(switchDirection)
end
resetKeys(FREECAM_PLAYER_LOCK_SWITCH, keyboard)
end
end
if FFlagUserFreecamCustomGui then
if FREECAM_CUSTOM_GUI_TOGGLE[input.keyCode] and input.UserInputState == Enum.UserInputState.Begin then
if freecamGui and freecamGui.Parent then
freecamGui.Enabled = not freecamGui.Enabled
end
resetKeys(FREECAM_CUSTOM_GUI_TOGGLE, keyboard)
end
if FREECAM_PLAYER_GUI_TOGGLE[input.keyCode] and input.UserInputState == Enum.UserInputState.Begin then
screenGuisEnabled = not screenGuisEnabled
if PlayerState then
local screenGuis = PlayerState.getScreenGuis()
for _, gui in pairs(screenGuis) do
if gui.Parent and gui ~= freecamGui then
gui.Enabled = screenGuisEnabled
end
end
end
resetKeys(FREECAM_PLAYER_GUI_TOGGLE, keyboard)
end
if FREECAM_LEADERBOARD_TOGGLE[input.keyCode] and input.UserInputState == Enum.UserInputState.Begin then
leaderboardEnabled = not leaderboardEnabled
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, leaderboardEnabled)
resetKeys(FREECAM_LEADERBOARD_TOGGLE, keyboard)
end
end
return Enum.ContextActionResult.Sink
end
local function GpButton(action, state, input)
gamepad[input.KeyCode.Name] = state == Enum.UserInputState.Begin and 1 or 0
if FFlagUserFreecamTiltControl then
if FREECAM_TILT_RESET_GP[input.KeyCode] and input.UserInputState == Enum.UserInputState.Begin then
handleDoubleTapReset(input.KeyCode)
end
end
return Enum.ContextActionResult.Sink
end
local function MousePan(action, state, input)
local delta = input.Delta
mouse.Delta = Vector2.new(-delta.y, -delta.x)
return Enum.ContextActionResult.Sink
end
local function Thumb(action, state, input)
gamepad[input.KeyCode.Name] = input.Position
return Enum.ContextActionResult.Sink
end
local function Trigger(action, state, input)
gamepad[input.KeyCode.Name] = input.Position.z
return Enum.ContextActionResult.Sink
end
local function MouseWheel(action, state, input)
mouse[input.UserInputType.Name] = -input.Position.z
return Enum.ContextActionResult.Sink
end
local function Zero(t)
for k, v in pairs(t) do
t[k] = v*0
end
end
function Input.StartCapture()
if FFlagUserFreecamControlSpeed then
ContextActionService:BindActionAtPriority("FreecamKeyboard", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.W, Enum.KeyCode.U,
Enum.KeyCode.A, Enum.KeyCode.H,
Enum.KeyCode.S, Enum.KeyCode.J,
Enum.KeyCode.D, Enum.KeyCode.K,
Enum.KeyCode.E, Enum.KeyCode.I,
Enum.KeyCode.Q, Enum.KeyCode.Y
)
ContextActionService:BindActionAtPriority("FreecamKeyboardControlSpeed", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.Up, Enum.KeyCode.Down,
Enum.KeyCode.Left, Enum.KeyCode.Right
)
ContextActionService:BindActionAtPriority("FreecamGamepadControlSpeed", GpButton, false, INPUT_PRIORITY,
Enum.KeyCode.DPadUp, Enum.KeyCode.DPadDown,
Enum.KeyCode.DPadLeft, Enum.KeyCode.DPadRight
)
else
ContextActionService:BindActionAtPriority("FreecamKeyboard", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.W, Enum.KeyCode.U,
Enum.KeyCode.A, Enum.KeyCode.H,
Enum.KeyCode.S, Enum.KeyCode.J,
Enum.KeyCode.D, Enum.KeyCode.K,
Enum.KeyCode.E, Enum.KeyCode.I,
Enum.KeyCode.Q, Enum.KeyCode.Y,
Enum.KeyCode.Up, Enum.KeyCode.Down
)
end
if FFlagUserFreecamTiltControl then
ContextActionService:BindActionAtPriority("FreecamKeyboardTiltControl", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.Z, Enum.KeyCode.C
)
ContextActionService:BindActionAtPriority("FreecamGamepadTiltControl", GpButton, false, INPUT_PRIORITY,
Enum.KeyCode.ButtonL1, Enum.KeyCode.ButtonR1
)
ContextActionService:BindActionAtPriority("FreecamKeyboardTiltControlSpeed", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.Comma, Enum.KeyCode.Period
)
if FFlagUserFreecamSmoothnessControl then
ContextActionService:BindActionAtPriority("FreecamKeyboardSmoothnessControl", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.LeftBracket, Enum.KeyCode.RightBracket,
Enum.KeyCode.Semicolon, Enum.KeyCode.Quote,
Enum.KeyCode.V, Enum.KeyCode.B,
Enum.KeyCode.N, Enum.KeyCode.M
)
end
end
if FFlagUserFreecamDepthOfFieldEffect then
ContextActionService:BindActionAtPriority("FreecamKeyboardDoFToggle", Keypress, false, INPUT_PRIORITY, Enum.KeyCode.BackSlash)
ContextActionService:BindActionAtPriority("FreecamKeyboardDoFControls", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.Minus, Enum.KeyCode.Equals
)
end
if FFlagUserFreecamPlayerLock then
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerLockToggle", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.Slash
)
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerLockSwitch", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.R, Enum.KeyCode.T
)
end
if FFlagUserFreecamCustomGui then
ContextActionService:BindActionAtPriority("FreecamKeyboardCustomGuiToggle", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.G
)
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerGuiToggle", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.X
)
ContextActionService:BindActionAtPriority("FreecamKeyboardLeaderboardToggle", Keypress, false, INPUT_PRIORITY,
Enum.KeyCode.L
)
end
ContextActionService:BindActionAtPriority("FreecamMousePan", MousePan, false, INPUT_PRIORITY, Enum.UserInputType.MouseMovement)
ContextActionService:BindActionAtPriority("FreecamMouseWheel", MouseWheel, false, INPUT_PRIORITY, Enum.UserInputType.MouseWheel)
ContextActionService:BindActionAtPriority("FreecamGamepadButton", GpButton, false, INPUT_PRIORITY, Enum.KeyCode.ButtonX, Enum.KeyCode.ButtonY)
ContextActionService:BindActionAtPriority("FreecamGamepadTrigger", Trigger, false, INPUT_PRIORITY, Enum.KeyCode.ButtonR2, Enum.KeyCode.ButtonL2)
ContextActionService:BindActionAtPriority("FreecamGamepadThumbstick", Thumb, false, INPUT_PRIORITY, Enum.KeyCode.Thumbstick1, Enum.KeyCode.Thumbstick2)
end
function Input.StopCapture()
if not FFlagUserFreecamCustomGui then
navSpeed = 1
if FFlagUserFreecamControlSpeed then
fovSpeed = 1
end
if FFlagUserFreecamTiltControl then
rollSpeed = 1
end
end
Zero(gamepad)
Zero(keyboard)
Zero(mouse)
ContextActionService:UnbindAction("FreecamKeyboard")
if FFlagUserFreecamControlSpeed then
ContextActionService:UnbindAction("FreecamKeyboardControlSpeed")
ContextActionService:UnbindAction("FreecamGamepadControlSpeed")
end
if FFlagUserFreecamTiltControl then
ContextActionService:UnbindAction("FreecamKeyboardTiltControl")
ContextActionService:UnbindAction("FreecamGamepadTiltControl")
ContextActionService:UnbindAction("FreecamKeyboardTiltControlSpeed")
if FFlagUserFreecamSmoothnessControl then
ContextActionService:UnbindAction("FreecamKeyboardSmoothnessControl")
end
end
if FFlagUserFreecamDepthOfFieldEffect then
ContextActionService:UnbindAction("FreecamKeyboardDoFToggle")
ContextActionService:UnbindAction("FreecamKeyboardDoFControls")
end
if FFlagUserFreecamPlayerLock then
ContextActionService:UnbindAction("FreecamKeyboardPlayerLockToggle")
ContextActionService:UnbindAction("FreecamKeyboardPlayerLockSwitch")
end
if FFlagUserFreecamCustomGui then
ContextActionService:UnbindAction("FreecamKeyboardCustomGuiToggle")
ContextActionService:UnbindAction("FreecamKeyboardPlayerGuiToggle")
ContextActionService:UnbindAction("FreecamKeyboardLeaderboardToggle")
end
ContextActionService:UnbindAction("FreecamMousePan")
ContextActionService:UnbindAction("FreecamMouseWheel")
ContextActionService:UnbindAction("FreecamGamepadButton")
ContextActionService:UnbindAction("FreecamGamepadTrigger")
ContextActionService:UnbindAction("FreecamGamepadThumbstick")
end
function Input.getNavSpeed()
return navSpeed
end
function Input.getFovSpeed()
return fovSpeed
end
function Input.getRollSpeed()
return rollSpeed
end
end
end
------------------------------------------------------------------------
local function StepFreecam(dt)
if FFlagUserFreecamSmoothnessControl then
Input.SpringControl(dt)
end
if FFlagUserFreecamDepthOfFieldEffect then
if FreecamDepthOfField and FreecamDepthOfField.Parent then
Input.DoF(dt)
end
end
local vel = velSpring:Update(dt, Input.Vel(dt))
local pan = panSpring:Update(dt, Input.Pan(dt))
local fov = fovSpring:Update(dt, Input.Fov(dt))
local roll
if FFlagUserFreecamTiltControl then
roll = rollSpring:Update(dt, Input.Roll(dt))
end
local zoomFactor = sqrt(tan(rad(70/2))/tan(rad(cameraFov/2)))
cameraFov = clamp(cameraFov + fov*FOV_GAIN*(dt/zoomFactor), 1, 120)
local cameraCFrame
if FFlagUserFreecamTiltControl then
local panVector: Vector2 = pan*PAN_GAIN*(dt/zoomFactor)
cameraRot = cameraRot + Vector3.new(panVector.X, panVector.Y, roll*ROLL_GAIN*(dt/zoomFactor))
if FFlagUserFreecamSmoothnessControl then
cameraRot = Vector3.new(cameraRot.x%(2*pi), cameraRot.y%(2*pi), cameraRot.z%(2*pi))
else
cameraRot = Vector3.new(clamp(cameraRot.x, -PITCH_LIMIT, PITCH_LIMIT), cameraRot.y%(2*pi), cameraRot.z)
end
cameraCFrame = CFrame.new(cameraPos)*CFrame.fromOrientation(cameraRot.x, cameraRot.y, cameraRot.z)*CFrame.new(vel*NAV_GAIN*dt)
else
cameraRot = cameraRot + pan*PAN_GAIN*(dt/zoomFactor)
cameraRot = Vector2.new(clamp(cameraRot.x, -PITCH_LIMIT, PITCH_LIMIT), cameraRot.y%(2*pi))
cameraCFrame = CFrame.new(cameraPos)*CFrame.fromOrientation(cameraRot.x, cameraRot.y, 0)*CFrame.new(vel*NAV_GAIN*dt)
end
if FFlagUserFreecamPlayerLock then
if playerLockEnabled and rootPart then
local zoomDelta = vel.Z * NAV_GAIN.Z * dt
local heightDelta = vel.Y * NAV_GAIN.Y * dt
playerLockZoom = clamp(playerLockZoom + zoomDelta, PLAYER_LOCK_MIN_ZOOM, PLAYER_LOCK_MAX_ZOOM)
playerLockHeight = clamp(playerLockHeight + heightDelta, -PLAYER_LOCK_HEIGHT_RANGE, PLAYER_LOCK_HEIGHT_RANGE)
local targetCFrame = CFrame.new(rootPart.Position + Vector3.new(0, playerLockHeight, 0))
local rotationCFrame
if FFlagUserFreecamTiltControl then
rotationCFrame = CFrame.fromOrientation(cameraRot.x, cameraRot.y, cameraRot.z)
else
rotationCFrame = CFrame.fromOrientation(cameraRot.x, cameraRot.y, 0)
end
cameraCFrame = targetCFrame * rotationCFrame * CFrame.new(0, 0, playerLockZoom)
end
end
if FFlagUserFreecamCustomGui then
if customGui and customGui.Parent and freecamGui and freecamGui.Parent and freecamGui.Enabled then
local displayText = ""
if dt > 0 then
local velocity = (cameraCFrame.p - cameraPos) / dt
displayText = displayText .. string.format("Velocity: (%.1f, %.1f, %.1f)\n", velocity.X, velocity.Y, velocity.Z)
end
displayText = displayText .. string.format("FOV: %.1f\n", cameraFov)
if FFlagUserFreecamTiltControl then
displayText = displayText .. string.format("Tilt: %.1f°\n", math.deg(cameraRot.z))
end
if FFlagUserFreecamSmoothnessControl then
displayText = displayText .. string.format("Stiffness (Vel): %.1f\n", VEL_STIFFNESS)
displayText = displayText .. string.format("Stiffness (Pan): %.1f\n", PAN_STIFFNESS)
displayText = displayText .. string.format("Stiffness (FOV): %.1f\n", FOV_STIFFNESS)
displayText = displayText .. string.format("Stiffness (Roll): %.1f\n", ROLL_STIFFNESS)
end
if FFlagUserFreecamControlSpeed then
displayText = displayText .. string.format("Movement Speed: %.1f\n", Input.getNavSpeed())
displayText = displayText .. string.format("Zoom Speed: %.1f\n", Input.getFovSpeed())
displayText = displayText .. string.format("Tilt Speed: %.1f\n", Input.getRollSpeed())
end
if FFlagUserFreecamDepthOfFieldEffect then
if FreecamDepthOfField and FreecamDepthOfField.Parent and FreecamDepthOfField.Enabled then
displayText = displayText .. string.format("Custom Depth Of Field: On\n")
displayText = displayText .. string.format("Custom Depth Of Field Near Intensity: %.1f\n", FreecamDepthOfField.NearIntensity)
displayText = displayText .. string.format("Custom Depth Of Field Far Intensity: %.1f\n", FreecamDepthOfField.FarIntensity)
displayText = displayText .. string.format("Custom Depth Of Field Focus Distance: %.1f\n", FreecamDepthOfField.FocusDistance)
displayText = displayText .. string.format("Custom Depth Of Field Focus Radius: %.1f\n", FreecamDepthOfField.InFocusRadius)
else
displayText = displayText .. string.format("Custom Depth Of Field: Off\n")
end
end
if FFlagUserFreecamPlayerLock then
if playerLockEnabled and #playerList > 0 then
displayText = displayText .. string.format("Player Lock: %s\n", playerList[currentTargetIndex].Name)
else
displayText = displayText .. string.format("Player Lock: Off\n")
end
end
customGui.Text = displayText
end
end
cameraPos = cameraCFrame.p
Camera.CFrame = cameraCFrame
Camera.Focus = cameraCFrame
Camera.FieldOfView = cameraFov
end
local function CheckMouseLockAvailability()
local devAllowsMouseLock = Players.LocalPlayer.DevEnableMouseLock
local devMovementModeIsScriptable = Players.LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.Scriptable
local userHasMouseLockModeEnabled = GameSettings.ControlMode == Enum.ControlMode.MouseLockSwitch
local userHasClickToMoveEnabled = GameSettings.ComputerMovementMode == Enum.ComputerMovementMode.ClickToMove
local MouseLockAvailable = devAllowsMouseLock and userHasMouseLockModeEnabled and not userHasClickToMoveEnabled and not devMovementModeIsScriptable
return MouseLockAvailable
end
------------------------------------------------------------------------
PlayerState = {}
do
local mouseBehavior
local mouseIconEnabled
local cameraType
local cameraFocus
local cameraCFrame
local cameraFieldOfView
local screenGuis = {}
local coreGuis = {
Backpack = true,
Chat = true,
Health = true,
PlayerList = true,
}
local setCores = {
BadgesNotificationsActive = true,
PointsNotificationsActive = true,
}
-- Save state and set up for freecam
function PlayerState.Push()
for name in pairs(coreGuis) do
coreGuis[name] = StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType[name])
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType[name], false)
end
for name in pairs(setCores) do
setCores[name] = StarterGui:GetCore(name)
StarterGui:SetCore(name, false)
end
local playergui = LocalPlayer:FindFirstChildOfClass("PlayerGui")
if playergui then
for _, gui in pairs(playergui:GetChildren()) do
if gui:IsA("ScreenGui") and gui.Enabled then
screenGuis[#screenGuis + 1] = gui
gui.Enabled = false
end
end
if FFlagUserFixFreecamGuiChangeVisibility then
playerGuiConnection = playergui.ChildAdded:Connect(function(child)
if child:IsA("ScreenGui") and child.Enabled then
screenGuis[#screenGuis + 1] = child
if FFlagUserFreecamCustomGui then
child.Enabled = screenGuisEnabled
else
child.Enabled = false
end
end
end)
end
end
cameraFieldOfView = Camera.FieldOfView
Camera.FieldOfView = 70
cameraType = Camera.CameraType
Camera.CameraType = Enum.CameraType.Custom
cameraCFrame = Camera.CFrame
cameraFocus = Camera.Focus
mouseIconEnabled = UserInputService.MouseIconEnabled
UserInputService.MouseIconEnabled = false
if FFlagUserExitFreecamBreaksWithShiftlock and CheckMouseLockAvailability() then
mouseBehavior = Enum.MouseBehavior.Default
else
mouseBehavior = UserInputService.MouseBehavior
end
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
-- Restore state
function PlayerState.Pop()
for name, isEnabled in pairs(coreGuis) do
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType[name], isEnabled)
end
for name, isEnabled in pairs(setCores) do
StarterGui:SetCore(name, isEnabled)
end
for _, gui in pairs(screenGuis) do
if FFlagUserFreecamCustomGui then
if gui.Parent and gui ~= freecamGui then
gui.Enabled = true
end
else
if gui.Parent then
gui.Enabled = true
end
end
end
if FFlagUserFixFreecamGuiChangeVisibility then
if playerGuiConnection then
playerGuiConnection:Disconnect()
playerGuiConnection = nil
end
screenGuis = {}
end
Camera.FieldOfView = cameraFieldOfView
cameraFieldOfView = nil
Camera.CameraType = cameraType
cameraType = nil
Camera.CFrame = cameraCFrame
cameraCFrame = nil
Camera.Focus = cameraFocus
cameraFocus = nil
UserInputService.MouseIconEnabled = mouseIconEnabled
mouseIconEnabled = nil
UserInputService.MouseBehavior = mouseBehavior
mouseBehavior = nil
end
function PlayerState.getScreenGuis()
return screenGuis
end
end
local function removePlayerFromList(player)
for i, p in ipairs(playerList) do
if p == player then
table.remove(playerList, i)
if currentTargetIndex == i and playerLockEnabled then
-- If the player removed is the current target index, disable player lock and turn it back to freecam.
playerLockEnabled = false
currentTargetIndex = 1
end
if currentTargetIndex > i then
-- If the player removed is before the current target index, table.remove() will move all subsequent indices back.
currentTargetIndex = currentTargetIndex - 1
end
if currentTargetIndex > #playerList or currentTargetIndex < 1 then
currentTargetIndex = 1
end
break
end
end
end
local function initializePlayerList()
playerList = Players:GetPlayers()
for i, p in ipairs(playerList) do
if p == LocalPlayer then
currentTargetIndex = i
break
end
end
playerAddedConnection = Players.PlayerAdded:Connect(function(player)
table.insert(playerList, player)
end)
playerRemovingConnection = Players.PlayerRemoving:Connect(removePlayerFromList)
end
local function StartFreecam()
if FFlagUserFreecamPlayerLock then
initializePlayerList()
end
if not FFlagUserFreecamGuiDestabilization then
if FFlagUserShowGuiHideToggles then
script:SetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME, true)
end
end
local cameraCFrame = Camera.CFrame
if FFlagUserFreecamTiltControl then
cameraRot = Vector3.new(cameraCFrame:toEulerAnglesYXZ())
else
cameraRot = Vector2.new(cameraCFrame:toEulerAnglesYXZ())
end
cameraPos = cameraCFrame.p
cameraFov = Camera.FieldOfView
velSpring:Reset(Vector3.new())
panSpring:Reset(Vector2.new())
fovSpring:Reset(0)
if FFlagUserFreecamTiltControl then
rollSpring:Reset(0)
end
if not FFlagUserFreecamCustomGui then
if FFlagUserFreecamSmoothnessControl then
VEL_STIFFNESS = 1.5
PAN_STIFFNESS = 1.0
FOV_STIFFNESS = 4.0
ROLL_STIFFNESS = 1.0
end
end
if FFlagUserFreecamCustomGui then
playerGui = LocalPlayer:WaitForChild("PlayerGui")
freecamGui = playerGui:WaitForChild("Freecam")
if not customGui or not customGui.Parent then
customGui = Instance.new("TextLabel")
customGui.Name = "FreecamCustomGui"
customGui.TextColor3 = Color3.new(1, 1, 1)
customGui.Font = Enum.Font.SourceSansBold
customGui.TextSize = 20
customGui.TextStrokeTransparency = 0
customGui.BackgroundTransparency = 1
customGui.TextWrapped = true
customGui.TextXAlignment = Enum.TextXAlignment.Right
customGui.AutomaticSize = Enum.AutomaticSize.Y
customGui.AnchorPoint = Vector2.new(1, 1)
customGui.Position = UDim2.new(1, -10, 1, -10)
customGui.Size = UDim2.new(0, 400, 0, 0)
customGui.Parent = freecamGui
end
end
PlayerState.Push()
if FFlagUserFreecamDepthOfFieldEffect then
if not FreecamDepthOfField or not FreecamDepthOfField.Parent then
FreecamDepthOfField = Instance.new("DepthOfFieldEffect")
FreecamDepthOfField.Enabled = false
FreecamDepthOfField.Name = "FreecamDepthOfField"
FreecamDepthOfField.Parent = Camera
end
end
RunService:BindToRenderStep("Freecam", Enum.RenderPriority.Camera.Value, StepFreecam)
Input.StartCapture()
end
local function StopFreecam()
if not FFlagUserFreecamGuiDestabilization then
if FFlagUserShowGuiHideToggles then
script:SetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME, false)
end
end
if FFlagUserFreecamPlayerLock then
if playerAddedConnection then
playerAddedConnection:Disconnect()
playerAddedConnection = nil
end
if playerRemovingConnection then
playerRemovingConnection:Disconnect()
playerRemovingConnection = nil
end
playerLockEnabled = false
currentTargetIndex = 1
playerList = {}
end
if FFlagUserFreecamDepthOfFieldEffect then
if FreecamDepthOfField and FreecamDepthOfField.Parent then
if FreecamDepthOfField.Enabled then
for _, effect in ipairs(postEffects) do
if effect.Parent then
effect.Enabled = true
end
end
if cameraConnection then
cameraConnection:Disconnect()
cameraConnection = nil
end
if lightingConnection then
lightingConnection:Disconnect()
lightingConnection = nil
end
postEffects = {}
end
FreecamDepthOfField.Enabled = false
end
end
if FFlagUserFreecamCustomGui then
if freecamGui and freecamGui.Parent then
freecamGui.Enabled = false
end
screenGuisEnabled = false
leaderboardEnabled = false
end
Input.StopCapture()
RunService:UnbindFromRenderStep("Freecam")
PlayerState.Pop()
end
------------------------------------------------------------------------
do
local enabled = false
local function ToggleFreecam()
if enabled then
StopFreecam()
else
StartFreecam()
end
enabled = not enabled
if FFlagUserFreecamGuiDestabilization then
script:SetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME, enabled)
end
end
local function CheckMacro(macro)
for i = 1, #macro - 1 do
if not UserInputService:IsKeyDown(macro[i]) then
return
end
end
ToggleFreecam()
end
local function HandleActivationInput(action, state, input)
if state == Enum.UserInputState.Begin then
if input.KeyCode == FREECAM_MACRO_KB[#FREECAM_MACRO_KB] then
CheckMacro(FREECAM_MACRO_KB)
end
end
return Enum.ContextActionResult.Pass
end
ContextActionService:BindActionAtPriority("FreecamToggle", HandleActivationInput, false, TOGGLE_INPUT_PRIORITY, FREECAM_MACRO_KB[#FREECAM_MACRO_KB])
if FFlagUserFreecamGuiDestabilization or FFlagUserShowGuiHideToggles then
script:SetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME, enabled)
script:GetAttributeChangedSignal(FREECAM_ENABLED_ATTRIBUTE_NAME):Connect(function()
local attributeValue = script:GetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME)
if typeof(attributeValue) ~= "boolean" then
script:SetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME, enabled)
return
end
-- If the attribute's value and `enabled` var don't match, pick attribute value as
-- source of truth
if attributeValue ~= enabled then
if attributeValue then
StartFreecam()
enabled = true
else
StopFreecam()
enabled = false
end
end
end)
end
end
return {}