Run it
Copy the script and paste it into your executor.
pi = .pi
abs = .abs
clamp = .clamp
exp = .exp
rad = .rad
sign = .sign
sqrt = .sqrt
tan = .tan
ContextActionService = :()
Players = :()
RunService = :()
StarterGui = :()
UserInputService = :()
Workspace = :()
Settings = ()
GameSettings = Settings.GameSettings
Lighting = :()
TweenService = :()
GuiService = :()
CoreGui = :()
LocalPlayer = Players.LocalPlayer
LocalPlayer
Players:():()
LocalPlayer = Players.LocalPlayer
Camera = Workspace.CurrentCamera
Workspace:():(()
newCamera = Workspace.CurrentCamera
newCamera
Camera = newCamera
)
freecamGui = .()
freecamGui.Name =
freecamGui.ZIndexBehavior = .ZIndexBehavior.Sibling
freecamGui.ResetOnSpawn =
freecamGui.Parent = CoreGui
freecamGui.Enabled =
touchGui =
floatingButton =
uiMainFrame =
FFlagUserExitFreecamBreaksWithShiftlock =
FFlagUserShowGuiHideToggles =
FFlagUserFixFreecamDeltaTimeCalculation =
FFlagUserFixFreecamGuiChangeVisibility =
FFlagUserFreecamControlSpeed =
FFlagUserFreecamTiltControl =
FFlagUserFreecamSmoothnessControl =
FFlagUserFreecamGuiDestabilization =
FFlagUserFreecamDepthOfFieldEffect =
FFlagUserFreecamPlayerLock =
FFlagUserFreecamPlayerLockResetHeight =
FFlagUserFreecamCustomGui =
FREECAM_ENABLED_ATTRIBUTE_NAME =
TOGGLE_INPUT_PRIORITY = .ContextActionPriority.Low.Value
INPUT_PRIORITY = .ContextActionPriority.High.Value
NAV_GAIN = .(, , )*
PAN_GAIN = .(, )*
FOV_GAIN =
ROLL_GAIN = -pi/
PITCH_LIMIT = ()
VEL_STIFFNESS =
PAN_STIFFNESS =
FOV_STIFFNESS =
ROLL_STIFFNESS =
VEL_ADJ_STIFFNESS =
PAN_ADJ_STIFFNESS =
FOV_ADJ_STIFFNESS =
ROLL_ADJ_STIFFNESS =
VEL_MIN_STIFFNESS =
PAN_MIN_STIFFNESS =
FOV_MIN_STIFFNESS =
ROLL_MIN_STIFFNESS =
VEL_MAX_STIFFNESS =
PAN_MAX_STIFFNESS =
FOV_MAX_STIFFNESS =
ROLL_MAX_STIFFNESS =
lastPressTime = {}
lastResetTime =
DOUBLE_TAP_TIME_THRESHOLD =
DOUBLE_TAP_DEBOUNCE_TIME =
postEffects = {}
playerGuiConnection =
cameraConnection =
lightingConnection =
playerAddedConnection =
playerRemovingConnection =
PLAYER_LOCK_DEFAULT_ZOOM =
PLAYER_LOCK_MIN_ZOOM =
PLAYER_LOCK_MAX_ZOOM =
PLAYER_LOCK_DEFAULT_HEIGHT =
PLAYER_LOCK_HEIGHT_RANGE =
playerLockEnabled =
playerLockZoom =
playerLockHeight =
playerList = {}
currentTargetIndex =
rootPart =
screenGuisEnabled =
leaderboardEnabled =
mobileMoveVector = .(, , )
mobileLookVector = .(, )
mobileFovDelta =
mobileNavSpeed =
flyUpActive =
flyDownActive =
tiltLeftActive =
tiltRightActive =
customTiltLeftKeys = {}
customTiltRightKeys = {}
mouseSensitivity =
touchLookSensitivity =
fovSensitivity =
Spring = {}
Spring.__index = Spring
Spring.(freq, pos)
self = ({}, Spring)
self.f = freq
self.p = pos
self.v = pos*
self
Spring:(dt, goal)
f = self.f**pi
p0 = self.p
v0 = self.v
offset = goal - p0
decay = (-f*dt)
p1 = goal + (v0*dt - offset*(f*dt + ))*decay
v1 = (f*dt*(offset*f - v0) + v0)*decay
self.p = p1
self.v = v1
p1
Spring:(freq)
self.f = freq
Spring:(pos)
self.p = pos
self.v = pos*
cameraPos = .()
cameraRot = .()
cameraFov =
velSpring = Spring.(VEL_STIFFNESS, .())
panSpring = Spring.(PAN_STIFFNESS, .())
fovSpring = Spring.(FOV_STIFFNESS, )
rollSpring = Spring.(ROLL_STIFFNESS, )
tiltLeftActiveKB =
tiltRightActiveKB =
(parent)
PADDING =
buttonFrame = .()
buttonFrame.Name =
buttonFrame.BackgroundTransparency =
buttonFrame.Parent = parent
buttonFrame.ZIndex =
flyDownBtn = .()
flyDownBtn.Name =
flyDownBtn.BackgroundTransparency =
flyDownBtn.Image =
flyDownBtn.ImageRectOffset = .(, )
flyDownBtn.ImageRectSize = .(, )
flyDownBtn.Rotation =
flyDownBtn.Parent = buttonFrame
flyDownBtn.ZIndex =
flyUpBtn = .()
flyUpBtn.Name =
flyUpBtn.BackgroundTransparency =
flyUpBtn.Image =
flyUpBtn.ImageRectOffset = .(, )
flyUpBtn.ImageRectSize = .(, )
flyUpBtn.Rotation =
flyUpBtn.Parent = buttonFrame
flyUpBtn.ZIndex =
flyDownBtn.InputBegan:((input)
input.UserInputType == .UserInputType.Touch input.UserInputState == .UserInputState.Begin
flyDownBtn.ImageRectOffset = .(, )
flyDownActive =
)
flyDownBtn.InputEnded:((input)
input.UserInputType == .UserInputType.Touch
flyDownBtn.ImageRectOffset = .(, )
flyDownActive =
)
flyUpBtn.InputBegan:((input)
input.UserInputType == .UserInputType.Touch input.UserInputState == .UserInputState.Begin
flyUpBtn.ImageRectOffset = .(, )
flyUpActive =
)
flyUpBtn.InputEnded:((input)
input.UserInputType == .UserInputType.Touch
flyUpBtn.ImageRectOffset = .(, )
flyUpActive =
)
()
screenSize = parent.AbsoluteSize
isSmallScreen = .(screenSize.X, screenSize.Y) <=
buttonSize = isSmallScreen
totalWidth = (buttonSize * ) + (PADDING * )
totalHeight = buttonSize + (PADDING * )
buttonFrame.Size = .(, totalWidth, , totalHeight)
buttonFrame.Position = .(, -(totalWidth + PADDING), , -(totalHeight + PADDING))
flyDownBtn.Size = .(, buttonSize, , buttonSize)
flyDownBtn.Position = .(, PADDING, , PADDING)
flyUpBtn.Size = .(, buttonSize, , buttonSize)
flyUpBtn.Position = .(, PADDING + buttonSize + PADDING, , PADDING)
parent:():(updateButtonSize)
()
GuiService.MenuOpened:(()
flyDownBtn.ImageRectOffset = .(, )
flyUpBtn.ImageRectOffset = .(, )
flyDownActive =
flyUpActive =
)
buttonFrame, flyDownBtn, flyUpBtn
(parent)
PADDING =
buttonFrame = .()
buttonFrame.Name =
buttonFrame.BackgroundTransparency =
buttonFrame.Parent = parent
buttonFrame.ZIndex =
tiltLeftBtn = .()
tiltLeftBtn.Name =
tiltLeftBtn.BackgroundTransparency =
tiltLeftBtn.Image =
tiltLeftBtn.Parent = buttonFrame
tiltLeftBtn.ZIndex =
tiltRightBtn = .()
tiltRightBtn.Name =
tiltRightBtn.BackgroundTransparency =
tiltRightBtn.Image =
tiltRightBtn.Parent = buttonFrame
tiltRightBtn.ZIndex =
tiltLeftBtn.InputBegan:((input)
input.UserInputType == .UserInputType.Touch input.UserInputState == .UserInputState.Begin
tiltLeftBtn.ImageTransparency =
tiltLeftActive =
)
tiltLeftBtn.InputEnded:((input)
input.UserInputType == .UserInputType.Touch
tiltLeftBtn.ImageTransparency =
tiltLeftActive =
)
tiltRightBtn.InputBegan:((input)
input.UserInputType == .UserInputType.Touch input.UserInputState == .UserInputState.Begin
tiltRightBtn.ImageTransparency =
tiltRightActive =
)
tiltRightBtn.InputEnded:((input)
input.UserInputType == .UserInputType.Touch
tiltRightBtn.ImageTransparency =
tiltRightActive =
)
()
screenSize = parent.AbsoluteSize
isSmallScreen = .(screenSize.X, screenSize.Y) <=
buttonSize = isSmallScreen
totalWidth = (buttonSize * ) + (PADDING * )
buttonFrame.Size = .(, totalWidth, , buttonSize + (PADDING * ))
buttonFrame.Position = .(, PADDING, , -(buttonSize + (PADDING * )))
tiltLeftBtn.Size = .(, buttonSize, , buttonSize)
tiltLeftBtn.Position = .(, PADDING, , PADDING)
tiltRightBtn.Size = .(, buttonSize, , buttonSize)
tiltRightBtn.Position = .(, PADDING + buttonSize + PADDING, , PADDING)
parent:():(updateButtonSize)
()
GuiService.MenuOpened:(()
tiltLeftActive =
tiltRightActive =
tiltLeftBtn.ImageTransparency =
tiltRightBtn.ImageTransparency =
)
buttonFrame, tiltLeftBtn, tiltRightBtn
(parent)
PADDING =
barFrame = .()
barFrame.Name =
barFrame.BackgroundColor3 = .(, , )
barFrame.BackgroundTransparency =
barFrame.BorderSizePixel =
barFrame.Parent = parent
barFrame.ZIndex =
barCorner = .()
barCorner.CornerRadius = .(, )
barCorner.Parent = barFrame
prevBtn = .()
prevBtn.Name =
prevBtn.Text =
prevBtn.TextColor3 = .(, , )
prevBtn.TextSize =
prevBtn.Font = .Font.GothamBold
prevBtn.BackgroundColor3 = .(, , )
prevBtn.BackgroundTransparency =
prevBtn.BorderSizePixel =
prevBtn.Parent = barFrame
prevBtn.ZIndex =
prevCorner = .()
prevCorner.CornerRadius = .(, )
prevCorner.Parent = prevBtn
playerLabel = .()
playerLabel.Name =
playerLabel.Text =
playerLabel.TextColor3 = .(, , )
playerLabel.TextSize =
playerLabel.Font = .Font.GothamBold
playerLabel.BackgroundColor3 = .(, , )
playerLabel.BackgroundTransparency =
playerLabel.BorderSizePixel =
playerLabel.Parent = barFrame
playerLabel.ZIndex =
playerCorner = .()
playerCorner.CornerRadius = .(, )
playerCorner.Parent = playerLabel
nextBtn = .()
nextBtn.Name =
nextBtn.Text =
nextBtn.TextColor3 = .(, , )
nextBtn.TextSize =
nextBtn.Font = .Font.GothamBold
nextBtn.BackgroundColor3 = .(, , )
nextBtn.BackgroundTransparency =
nextBtn.BorderSizePixel =
nextBtn.Parent = barFrame
nextBtn.ZIndex =
nextCorner = .()
nextCorner.CornerRadius = .(, )
nextCorner.Parent = nextBtn
toggleBtn = .()
toggleBtn.Name =
toggleBtn.Text =
toggleBtn.TextColor3 = .(, , )
toggleBtn.TextSize =
toggleBtn.Font = .Font.GothamBold
toggleBtn.BackgroundColor3 = .(, , )
toggleBtn.BackgroundTransparency =
toggleBtn.BorderSizePixel =
toggleBtn.Parent = barFrame
toggleBtn.ZIndex =
toggleCorner = .()
toggleCorner.CornerRadius = .(, )
toggleCorner.Parent = toggleBtn
()
screenSize = parent.AbsoluteSize
isSmallScreen = .(screenSize.X, screenSize.Y) <=
btnSize = isSmallScreen
labelWidth =
totalWidth = btnSize + labelWidth + btnSize +
barFrame.Size = .(, totalWidth, , btnSize)
barFrame.Position = .(, -totalWidth/, , -(btnSize + PADDING * ))
prevBtn.Size = .(, btnSize, , btnSize)
prevBtn.Position = .(, PADDING, , )
playerLabel.Size = .(, labelWidth, , btnSize)
playerLabel.Position = .(, btnSize + PADDING * , , )
nextBtn.Size = .(, btnSize, , btnSize)
nextBtn.Position = .(, -(btnSize + PADDING), , )
toggleBtn.Size = .(, , , btnSize - )
toggleBtn.Position = .(, -(btnSize + PADDING + ), , )
parent:():(updateBarSize)
()
()
playerLockEnabled #playerList >
playerLabel.Text = .. playerList[currentTargetIndex].Name
toggleBtn.Text =
toggleBtn.BackgroundColor3 = .(, , )
playerLabel.Text =
toggleBtn.Text =
toggleBtn.BackgroundColor3 = .(, , )
prevBtn.MouseButton1Click:(()
playerLockEnabled #playerList >
i = , #playerList
currentTargetIndex = currentTargetIndex -
currentTargetIndex < currentTargetIndex = #playerList
targetPlayer = playerList[currentTargetIndex]
targetCharacter = targetPlayer targetPlayer.Character
targetCharacter
humanoid = targetCharacter:()
humanoid humanoid.RootPart
rootPart = humanoid.RootPart
()
)
nextBtn.MouseButton1Click:(()
playerLockEnabled #playerList >
i = , #playerList
currentTargetIndex = currentTargetIndex +
currentTargetIndex > #playerList currentTargetIndex =
targetPlayer = playerList[currentTargetIndex]
targetCharacter = targetPlayer targetPlayer.Character
targetCharacter
humanoid = targetCharacter:()
humanoid humanoid.RootPart
rootPart = humanoid.RootPart
()
)
toggleBtn.MouseButton1Click:(()
playerLockEnabled = playerLockEnabled
playerLockEnabled
playerLockZoom = PLAYER_LOCK_DEFAULT_ZOOM
playerLockHeight = PLAYER_LOCK_DEFAULT_HEIGHT
#playerList >
targetPlayer = playerList[currentTargetIndex]
targetCharacter = targetPlayer targetPlayer.Character
targetCharacter
humanoid = targetCharacter:()
humanoid humanoid.RootPart
rootPart = humanoid.RootPart
()
)
barFrame
()
gui = .()
gui.Name =
gui.ZIndexBehavior = .ZIndexBehavior.Sibling
gui.ResetOnSpawn =
gui.Parent = LocalPlayer:()
thumbstickFrame = .()
thumbstickFrame.Name =
thumbstickFrame.BorderSizePixel =
thumbstickFrame.Visible =
thumbstickFrame.BackgroundTransparency =
thumbstickFrame.BackgroundColor3 = .(, , )
thumbstickFrame.Active =
thumbstickFrame.Size = .(, , , )
thumbstickFrame.Position = .(, , , )
thumbstickFrame.Parent = gui
thumbstickFrame.ZIndex =
startImage = .()
startImage.Name =
startImage.Visible =
startImage.BackgroundTransparency =
startImage.Image =
startImage.ImageRectOffset = .(, )
startImage.ImageRectSize = .(, )
startImage.ImageColor3 = .(, , )
startImage.ImageTransparency =
startImage.AnchorPoint = .(, )
startImage.ZIndex =
startImage.Parent = thumbstickFrame
endImage = .()
endImage.Name =
endImage.Visible =
endImage.BackgroundTransparency =
endImage.Image =
endImage.ImageRectOffset = .(, )
endImage.ImageRectSize = .(, )
endImage.ImageColor3 = .(, , )
endImage.ImageTransparency =
endImage.AnchorPoint = .(, )
endImage.ZIndex =
endImage.Parent = thumbstickFrame
middleImages = {}
originalTransparencies = {, , , , , , }
i = ,
middle = .()
middle.Name =
middle.Visible =
middle.BackgroundTransparency =
middle.Image =
middle.ImageRectOffset = .(, )
middle.ImageRectSize = .(, )
middle.ImageTransparency = originalTransparencies[i]
middle.AnchorPoint = .(, )
middle.ZIndex =
middle.Parent = thumbstickFrame
middleImages[i] = middle
thumbstickSize =
thumbstickRingSize =
middleSize =
middleSpacing =
radiusDeadZone =
radiusMaxSpeed =
moveTouchObject =
moveTouchStartPosition =
moveTouchLockedIn =
moveTouchFirstChanged =
isFirstTouch =
()
baseX = thumbstickRingSize *
baseY = thumbstickRingSize *
startImage.Position = .(, baseX, , -baseY)
startImage.Size = .(, thumbstickRingSize * , , thumbstickRingSize * )
endImage.Position = startImage.Position
endImage.Size = .(, thumbstickSize * , , thumbstickSize * )
thumbstickFrame:():(updatePositions)
.()
()
(startPos, endPos)
centerOffset = thumbstickSize / + middleSize
delta = endPos - startPos
dist = delta.Magnitude - thumbstickRingSize / - middleSize
direction = delta.Unit
totalSpacing = middleSpacing *
stepSize = middleSpacing
totalSpacing < dist
stepSize = dist /
i = ,
img = middleImages[i]
startDist = centerOffset + stepSize * (i - )
endDist = centerOffset + stepSize * (i - )
startDist < dist
pos = endPos - direction * endDist
alpha = - (endDist - dist) / stepSize
clampedAlpha = .(alpha, , )
img.Visible =
img.Position = .(, pos.X, , pos.Y)
img.Size = .(, middleSize * clampedAlpha, , middleSize * clampedAlpha)
img.Visible =
(touchPos)
startPos = .(moveTouchStartPosition.X, moveTouchStartPosition.Y) - thumbstickFrame.AbsolutePosition
endPos = .(touchPos.X, touchPos.Y) - thumbstickFrame.AbsolutePosition
endImage.Position = .(, endPos.X, , endPos.Y)
(startPos, endPos)
(offset)
mag = offset.Magnitude
mag < radiusDeadZone
mobileMoveVector = .(, , )
unit = offset.Unit
speedFactor = (radiusMaxSpeed - mag) / radiusMaxSpeed
scaled = unit * ( - .(, speedFactor))
mobileMoveVector = .(scaled.X, , scaled.Y)
(fadeIn)
tweenInfo = TweenInfo.(, .EasingStyle.Quad, .EasingDirection.InOut)
fadeIn
TweenService:(startImage, tweenInfo, {ImageTransparency = }):()
TweenService:(endImage, tweenInfo, {ImageTransparency = }):()
i = ,
TweenService:(middleImages[i], tweenInfo, {ImageTransparency = originalTransparencies[i]}):()
TweenService:(startImage, tweenInfo, {ImageTransparency = }):()
TweenService:(endImage, tweenInfo, {ImageTransparency = }):()
i = ,
TweenService:(middleImages[i], tweenInfo, {ImageTransparency = }):()
()
moveTouchObject =
mobileMoveVector = .(, , )
()
(touch)
absPos = thumbstickFrame.AbsolutePosition
absSize = thumbstickFrame.AbsoluteSize
touchPos = touch.Position
touchPos.X >= absPos.X touchPos.Y >= absPos.Y
touchPos.X <= absPos.X + absSize.X touchPos.Y <= absPos.Y + absSize.Y
(touch)
moveTouchObject
(touch)
isFirstTouch
isFirstTouch =
growTween = TweenInfo.(, .EasingStyle.Quad, .EasingDirection.Out)
TweenService:(startImage, growTween, {Size = .(, , , )}):()
TweenService:(endImage, growTween, {
Size = .(, thumbstickSize, , thumbstickSize),
ImageColor3 = .(, , )
}):()
moveTouchLockedIn =
moveTouchObject = touch
moveTouchStartPosition = touch.Position
moveTouchFirstChanged =
(touch)
touch ~= moveTouchObject
moveTouchFirstChanged
moveTouchFirstChanged =
startPosRel = .(touch.Position.X - thumbstickFrame.AbsolutePosition.X, touch.Position.Y - thumbstickFrame.AbsolutePosition.Y)
startImage.Visible =
startImage.Position = .(, startPosRel.X, , startPosRel.Y)
endImage.Visible =
endImage.Position = startImage.Position
()
(touch.Position)
moveTouchLockedIn =
offset = .(touch.Position.X - moveTouchStartPosition.X, touch.Position.Y - moveTouchStartPosition.Y)
.(offset.X) > .(offset.Y) >
(offset)
(touch.Position)
(touch)
touch == moveTouchObject
()
beginCon = UserInputService.TouchStarted:(onTouchBegin)
moveCon = UserInputService.TouchMoved:(onTouchMove)
endCon = UserInputService.TouchEnded:(onTouchEnd)
GuiService.MenuOpened:(()
moveTouchObject
()
)
rightDragActive =
rightDragStart =
rightDragTouch =
UserInputService.TouchStarted:((touch)
screenSize = Camera.ViewportSize
touch.Position.X > screenSize.X /
rightDragActive =
rightDragStart = touch.Position
rightDragTouch = touch
)
UserInputService.TouchMoved:((touch)
rightDragActive rightDragTouch == touch rightDragStart
delta = touch.Position - rightDragStart
mobileLookVector = .(-delta.Y * * touchLookSensitivity, -delta.X * * touchLookSensitivity)
rightDragStart = touch.Position
)
UserInputService.TouchEnded:((touch)
rightDragTouch == touch
rightDragActive =
rightDragTouch =
mobileLookVector = .(, )
)
pinchTouch1 =
pinchTouch2 =
pinchActive =
lastPinchDistance =
UserInputService.TouchStarted:((touch)
screenSize = Camera.ViewportSize
touch.Position.X > screenSize.X /
pinchTouch1
pinchTouch1 = touch
pinchTouch2 touch ~= pinchTouch1
pinchTouch2 = touch
pinchActive =
lastPinchDistance = (pinchTouch1.Position - pinchTouch2.Position).Magnitude
)
UserInputService.TouchMoved:((touch)
pinchActive pinchTouch1 pinchTouch2
touch == pinchTouch1
pinchTouch1 = touch
touch == pinchTouch2
pinchTouch2 = touch
currentDistance = (pinchTouch1.Position - pinchTouch2.Position).Magnitude
delta = currentDistance - lastPinchDistance
.(delta) >
mobileFovDelta = -delta * * fovSensitivity
lastPinchDistance = currentDistance
)
UserInputService.TouchEnded:((touch)
touch == pinchTouch1
pinchTouch1 = pinchTouch2
pinchTouch2 =
touch == pinchTouch2
pinchTouch2 =
pinchTouch1 pinchTouch2
pinchActive =
lastPinchDistance =
)
flyButtons = (gui)
tiltButtons = (gui)
playerLockBar = (gui)
gui
Input = {}
thumbstickCurve
K_CURVATURE =
K_DEADZONE =
(x)
((K_CURVATURE*x) - )/((K_CURVATURE) - )
(x)
((x - K_DEADZONE)/( - K_DEADZONE))
(x)
(x)*(((x)), , )
gamepad = {
ButtonX = , ButtonY = , DPadDown = , DPadUp = ,
DPadLeft = , DPadRight = , ButtonL2 = , ButtonR2 = ,
ButtonL1 = , ButtonR1 = , Thumbstick1 = .(), Thumbstick2 = .(),
}
keyboard = {
W = , A = , S = , D = , E = , Q = , U = , H = , J = , K = , I = , Y = ,
Up = , Down = , Left = , Right = , LeftShift = , RightShift = ,
Z = , C = , Comma = , Period = , LeftBracket = , RightBracket = ,
Semicolon = , Quote = , V = , B = , N = , M = , BackSlash = ,
Minus = , Equals = , Slash = , R = , T = , G = , X = , L =
}
mouse = { Delta = .(), MouseWheel = }
DEFAULT_FPS =
NAV_GAMEPAD_SPEED = .(, , )
NAV_KEYBOARD_SPEED = .(, , )
PAN_MOUSE_SPEED = .(, )*(pi/)
PAN_MOUSE_SPEED_DT = PAN_MOUSE_SPEED/DEFAULT_FPS
PAN_GAMEPAD_SPEED = .(, )*(pi/)
FOV_WHEEL_SPEED =
FOV_WHEEL_SPEED_DT = FOV_WHEEL_SPEED/DEFAULT_FPS
FOV_GAMEPAD_SPEED =
ROLL_GAMEPAD_SPEED =
ROLL_KEYBOARD_SPEED =
NAV_ADJ_SPEED =
NAV_MIN_SPEED =
NAV_MAX_SPEED =
NAV_SHIFT_MUL =
FOV_ADJ_SPEED =
FOV_MIN_SPEED =
FOV_MAX_SPEED =
ROLL_ADJ_SPEED =
ROLL_MIN_SPEED =
ROLL_MAX_SPEED =
DoFConstants = {
FarIntensity = { ADJ = , MIN = , MAX = },
NearIntensity = { ADJ = , MIN = , MAX = },
FocusDistance = { ADJ = , MIN = , MAX = },
FocusRadius = { ADJ = , MIN = , MAX = },
}
navSpeed =
rollSpeed =
fovSpeed =
Input.(dt)
FFlagUserFreecamControlSpeed
navSpeed = (navSpeed + dt*(keyboard.Up - keyboard.Down + gamepad.DPadUp - gamepad.DPadDown)*NAV_ADJ_SPEED, NAV_MIN_SPEED, NAV_MAX_SPEED)
navSpeed = (navSpeed + dt*(keyboard.Up - keyboard.Down)*NAV_ADJ_SPEED, , )
flyVertical =
flyUpActive flyVertical = flyVertical +
flyDownActive flyVertical = flyVertical -
mobileMove = .(mobileMoveVector.X, flyVertical, mobileMoveVector.Z) * mobileNavSpeed
kGamepad = .(
(gamepad.Thumbstick1.X),
(gamepad.ButtonR2) - (gamepad.ButtonL2),
(-gamepad.Thumbstick1.Y)
)*NAV_GAMEPAD_SPEED
kKeyboard = .(
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
shift = UserInputService:(.KeyCode.LeftShift) UserInputService:(.KeyCode.RightShift)
(kGamepad + kKeyboard + mobileMove)*(navSpeed*(shift NAV_SHIFT_MUL ))
Input.(dt)
mobilePan = mobileLookVector
kGamepad = .(
(gamepad.Thumbstick2.Y),
(-gamepad.Thumbstick2.X)
)*PAN_GAMEPAD_SPEED
kMouse = mouse.Delta*PAN_MOUSE_SPEED * mouseSensitivity
FFlagUserFixFreecamDeltaTimeCalculation
dt >
kMouse = (mouse.Delta/dt)*PAN_MOUSE_SPEED_DT * mouseSensitivity
mouse.Delta = .()
kGamepad + kMouse + mobilePan
Input.(dt)
FFlagUserFreecamControlSpeed
fovSpeed = (fovSpeed + dt*(keyboard.Right - keyboard.Left + gamepad.DPadRight - gamepad.DPadLeft)*FOV_ADJ_SPEED, FOV_MIN_SPEED, FOV_MAX_SPEED)
kGamepad = (gamepad.ButtonX - gamepad.ButtonY)*FOV_GAMEPAD_SPEED
kMouse = mouse.MouseWheel*FOV_WHEEL_SPEED * fovSensitivity
kMobile = mobileFovDelta
mobileFovDelta =
FFlagUserFixFreecamDeltaTimeCalculation
dt >
kMouse = (mouse.MouseWheel/dt)*FOV_WHEEL_SPEED_DT * fovSensitivity
mouse.MouseWheel =
FFlagUserFreecamControlSpeed
(kGamepad + kMouse + kMobile)*fovSpeed
kGamepad + kMouse + kMobile
Input.(dt)
rollSpeed = (rollSpeed + dt*(keyboard.Period - keyboard.Comma)*ROLL_ADJ_SPEED, ROLL_MIN_SPEED, ROLL_MAX_SPEED)
kGamepad = (gamepad.ButtonR1 - gamepad.ButtonL1)*ROLL_GAMEPAD_SPEED
kKeyboard = (keyboard.C - keyboard.Z)*ROLL_KEYBOARD_SPEED
kTouch =
tiltLeftActive kTouch = kTouch +
tiltRightActive kTouch = kTouch -
kCustomTilt =
tiltLeftActiveKB kCustomTilt = kCustomTilt +
tiltRightActiveKB kCustomTilt = kCustomTilt -
(kGamepad + kKeyboard + kTouch + kCustomTilt)*rollSpeed
Input.(dt)
FFlagUserFreecamDepthOfFieldEffect
shiftIsDown = UserInputService:(.KeyCode.LeftShift) UserInputService:(.KeyCode.RightShift)
ctrlIsDown = UserInputService:(.KeyCode.LeftControl) UserInputService:(.KeyCode.RightControl)
shiftIsDown ctrlIsDown
VEL_STIFFNESS = (VEL_STIFFNESS + dt*(keyboard.RightBracket - keyboard.LeftBracket)*VEL_ADJ_STIFFNESS, VEL_MIN_STIFFNESS, VEL_MAX_STIFFNESS)
velSpring:(VEL_STIFFNESS)
PAN_STIFFNESS = (PAN_STIFFNESS + dt*(keyboard.Quote - keyboard.Semicolon)*PAN_ADJ_STIFFNESS, PAN_MIN_STIFFNESS, PAN_MAX_STIFFNESS)
panSpring:(PAN_STIFFNESS)
FOV_STIFFNESS = (FOV_STIFFNESS + dt*(keyboard.B - keyboard.V)*FOV_ADJ_STIFFNESS, FOV_MIN_STIFFNESS, FOV_MAX_STIFFNESS)
fovSpring:(FOV_STIFFNESS)
ROLL_STIFFNESS = (ROLL_STIFFNESS + dt*(keyboard.M - keyboard.N)*ROLL_ADJ_STIFFNESS, ROLL_MIN_STIFFNESS, ROLL_MAX_STIFFNESS)
rollSpring:(ROLL_STIFFNESS)
Input.(dt)
shiftIsDown = UserInputService:(.KeyCode.LeftShift) UserInputService:(.KeyCode.RightShift)
ctrlIsDown = UserInputService:(.KeyCode.LeftControl) UserInputService:(.KeyCode.RightControl)
shiftIsDown
FreecamDepthOfField.FarIntensity = (
FreecamDepthOfField.FarIntensity + dt * (keyboard.RightBracket - keyboard.LeftBracket) * DoFConstants.FarIntensity.ADJ,
DoFConstants.FarIntensity.MIN, DoFConstants.FarIntensity.MAX
)
FreecamDepthOfField.InFocusRadius = (
FreecamDepthOfField.InFocusRadius + dt * (keyboard.Equals - keyboard.Minus) * DoFConstants.FocusRadius.ADJ,
DoFConstants.FocusRadius.MIN, DoFConstants.FocusRadius.MAX
)
ctrlIsDown
FreecamDepthOfField.NearIntensity = (
FreecamDepthOfField.NearIntensity + dt * (keyboard.RightBracket - keyboard.LeftBracket) * DoFConstants.NearIntensity.ADJ,
DoFConstants.NearIntensity.MIN, DoFConstants.NearIntensity.MAX
)
FreecamDepthOfField.FocusDistance = (
FreecamDepthOfField.FocusDistance + dt * (keyboard.Equals - keyboard.Minus) * DoFConstants.FocusDistance.ADJ,
DoFConstants.FocusDistance.MIN, DoFConstants.FocusDistance.MAX
)
FREECAM_TILT_RESET_GP = {
[.KeyCode.ButtonL1] = ,
[.KeyCode.ButtonR1] = ,
}
FREECAM_TILT_RESET_KB = {
[.KeyCode.Z] = ,
[.KeyCode.C] = ,
}
FREECAM_DOF_TOGGLE = {
[.KeyCode.BackSlash] = ,
}
FREECAM_PLAYER_LOCK_TOGGLE = {
[.KeyCode.Slash] = ,
}
FREECAM_PLAYER_LOCK_SWITCH = {
[.KeyCode.R] = ,
[.KeyCode.T] = ,
}
FREECAM_CUSTOM_GUI_TOGGLE = {
[.KeyCode.G] = ,
}
FREECAM_PLAYER_GUI_TOGGLE = {
[.KeyCode.X] = ,
}
FREECAM_LEADERBOARD_TOGGLE = {
[.KeyCode.L] = ,
}
(keys, )
keyEnum, _ (keys)
[keyEnum.Name]
[keyEnum.Name] =
(keyCode)
currentTime = .()
previousPressTime = lastPressTime[keyCode]
timeSinceLastPress = previousPressTime (currentTime - previousPressTime) -
previousPressTime (timeSinceLastPress <= DOUBLE_TAP_TIME_THRESHOLD)
(currentTime - lastResetTime) >= DOUBLE_TAP_DEBOUNCE_TIME
cameraRot = .(cameraRot.x, cameraRot.y, )
rollSpring:()
FFlagUserFreecamDepthOfFieldEffect
(FREECAM_TILT_RESET_GP, gamepad)
(FREECAM_TILT_RESET_KB, keyboard)
gamepad.ButtonL1 =
gamepad.ButtonR1 =
keyboard.C =
keyboard.Z =
lastResetTime = currentTime
lastPressTime[keyCode] = currentTime
(switchDirection)
playerList #playerList <
startIndex = currentTargetIndex
i = , #playerList
currentTargetIndex = ((currentTargetIndex - ) + switchDirection) % #playerList +
currentTargetIndex < currentTargetIndex = #playerList
targetPlayer = playerList[currentTargetIndex]
targetCharacter = targetPlayer targetPlayer.Character
targetCharacter
humanoid = targetCharacter:()
humanoid humanoid.RootPart
humanoid.RootPart
currentTargetIndex == startIndex
playerLockEnabled =
(action, state, input)
keyboard[input.KeyCode.Name] = state == .UserInputState.Begin
#customTiltLeftKeys >
_, keyName (customTiltLeftKeys)
input.KeyCode.Name == keyName
tiltLeftActiveKB = (state == .UserInputState.Begin)
#customTiltRightKeys >
_, keyName (customTiltRightKeys)
input.KeyCode.Name == keyName
tiltRightActiveKB = (state == .UserInputState.Begin)
FFlagUserFreecamTiltControl
FREECAM_TILT_RESET_KB[input.KeyCode] input.UserInputState == .UserInputState.Begin
(input.KeyCode)
FFlagUserFreecamDepthOfFieldEffect
FREECAM_DOF_TOGGLE[input.KeyCode] input.UserInputState == .UserInputState.Begin
FreecamDepthOfField.Enabled
postEffects = {}
_, effect (Camera:())
effect:() effect.Enabled
postEffects[#postEffects + ] = effect
effect.Enabled =
_, effect (Lighting:())
effect:() effect.Enabled
postEffects[#postEffects + ] = effect
effect.Enabled =
cameraConnection = Camera.ChildAdded:((child)
child:() child.Enabled
postEffects[#postEffects + ] = child
child.Enabled =
)
lightingConnection = Lighting.ChildAdded:((child)
child:() child.Enabled
postEffects[#postEffects + ] = child
child.Enabled =
)
_, effect (postEffects)
effect.Parent
effect.Enabled =
cameraConnection
cameraConnection:()
cameraConnection =
lightingConnection
lightingConnection:()
lightingConnection =
postEffects = {}
FreecamDepthOfField.Enabled = FreecamDepthOfField.Enabled
(FREECAM_DOF_TOGGLE, keyboard)
FFlagUserFreecamPlayerLock
FREECAM_PLAYER_LOCK_TOGGLE[input.KeyCode] input.UserInputState == .UserInputState.Begin
playerLockEnabled = playerLockEnabled
playerLockEnabled
playerLockZoom = PLAYER_LOCK_DEFAULT_ZOOM
FFlagUserFreecamPlayerLockResetHeight
playerLockHeight = PLAYER_LOCK_DEFAULT_HEIGHT
rootPart = ()
(FREECAM_PLAYER_LOCK_TOGGLE, keyboard)
FREECAM_PLAYER_LOCK_SWITCH[input.KeyCode] input.UserInputState == .UserInputState.Begin
playerLockEnabled #playerList >
switchDirection =
input.KeyCode == .KeyCode.T
switchDirection =
input.KeyCode == .KeyCode.R
switchDirection = -
switchDirection ~=
rootPart = (switchDirection)
(FREECAM_PLAYER_LOCK_SWITCH, keyboard)
FFlagUserFreecamCustomGui
FREECAM_CUSTOM_GUI_TOGGLE[input.KeyCode] input.UserInputState == .UserInputState.Begin
freecamGui freecamGui.Parent
freecamGui.Enabled = freecamGui.Enabled
(FREECAM_CUSTOM_GUI_TOGGLE, keyboard)
FREECAM_PLAYER_GUI_TOGGLE[input.KeyCode] input.UserInputState == .UserInputState.Begin
screenGuisEnabled = screenGuisEnabled
PlayerState
screenGuis = PlayerState.()
_, gui (screenGuis)
gui.Parent gui ~= freecamGui
gui.Enabled = screenGuisEnabled
(FREECAM_PLAYER_GUI_TOGGLE, keyboard)
FREECAM_LEADERBOARD_TOGGLE[input.KeyCode] input.UserInputState == .UserInputState.Begin
leaderboardEnabled = leaderboardEnabled
StarterGui:(.CoreGuiType.PlayerList, leaderboardEnabled)
(FREECAM_LEADERBOARD_TOGGLE, keyboard)
.ContextActionResult.Sink
(action, state, input)
gamepad[input.KeyCode.Name] = state == .UserInputState.Begin
FFlagUserFreecamTiltControl
FREECAM_TILT_RESET_GP[input.KeyCode] input.UserInputState == .UserInputState.Begin
(input.KeyCode)
.ContextActionResult.Sink
(action, state, input)
delta = input.Delta
mouse.Delta = .(-delta.y, -delta.x)
.ContextActionResult.Sink
(action, state, input)
gamepad[input.KeyCode.Name] = input.Position
.ContextActionResult.Sink
(action, state, input)
gamepad[input.KeyCode.Name] = input.Position.z
.ContextActionResult.Sink
(action, state, input)
mouse[input.UserInputType.Name] = -input.Position.z
.ContextActionResult.Sink
(t)
k, v (t)
t[k] = v*
Input.()
FFlagUserFreecamControlSpeed
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.W, .KeyCode.U, .KeyCode.A, .KeyCode.H,
.KeyCode.S, .KeyCode.J, .KeyCode.D, .KeyCode.K,
.KeyCode.E, .KeyCode.I, .KeyCode.Q, .KeyCode.Y
)
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.Up, .KeyCode.Down, .KeyCode.Left, .KeyCode.Right
)
ContextActionService:(, GpButton, , INPUT_PRIORITY,
.KeyCode.DPadUp, .KeyCode.DPadDown, .KeyCode.DPadLeft, .KeyCode.DPadRight
)
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.W, .KeyCode.U, .KeyCode.A, .KeyCode.H,
.KeyCode.S, .KeyCode.J, .KeyCode.D, .KeyCode.K,
.KeyCode.E, .KeyCode.I, .KeyCode.Q, .KeyCode.Y,
.KeyCode.Up, .KeyCode.Down
)
FFlagUserFreecamTiltControl
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.Z, .KeyCode.C
)
ContextActionService:(, GpButton, , INPUT_PRIORITY,
.KeyCode.ButtonL1, .KeyCode.ButtonR1
)
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.Comma, .KeyCode.Period
)
FFlagUserFreecamSmoothnessControl
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.LeftBracket, .KeyCode.RightBracket,
.KeyCode.Semicolon, .KeyCode.Quote,
.KeyCode.V, .KeyCode.B, .KeyCode.N, .KeyCode.M
)
FFlagUserFreecamDepthOfFieldEffect
ContextActionService:(, Keypress, , INPUT_PRIORITY, .KeyCode.BackSlash)
ContextActionService:(, Keypress, , INPUT_PRIORITY,
.KeyCode.Minus, .KeyCode.Equals
)
FFlagUserFreecamPlayerLock
ContextActionService:(, Keypress, , INPUT_PRIORITY, .KeyCode.Slash)
ContextActionService:(, Keypress, , INPUT_PRIORITY, .KeyCode.R, .KeyCode.T)
FFlagUserFreecamCustomGui
ContextActionService:(, Keypress, , INPUT_PRIORITY, .KeyCode.G)
ContextActionService:(, Keypress, , INPUT_PRIORITY, .KeyCode.X)
ContextActionService:(, Keypress, , INPUT_PRIORITY, .KeyCode.L)
ContextActionService:(, MousePan, , INPUT_PRIORITY, .UserInputType.MouseMovement)
ContextActionService:(, MouseWheel, , INPUT_PRIORITY, .UserInputType.MouseWheel)
ContextActionService:(, GpButton, , INPUT_PRIORITY, .KeyCode.ButtonX, .KeyCode.ButtonY)
ContextActionService:(, Trigger, , INPUT_PRIORITY, .KeyCode.ButtonR2, .KeyCode.ButtonL2)
ContextActionService:(, Thumb, , INPUT_PRIORITY, .KeyCode.Thumbstick1, .KeyCode.Thumbstick2)
Input.()
FFlagUserFreecamCustomGui
navSpeed =
FFlagUserFreecamControlSpeed fovSpeed =
FFlagUserFreecamTiltControl rollSpeed =
tiltLeftActiveKB =
tiltRightActiveKB =
(gamepad)
(keyboard)
(mouse)
ContextActionService:()
FFlagUserFreecamControlSpeed
ContextActionService:()
ContextActionService:()
FFlagUserFreecamTiltControl
ContextActionService:()
ContextActionService:()
ContextActionService:()
FFlagUserFreecamSmoothnessControl
ContextActionService:()
FFlagUserFreecamDepthOfFieldEffect
ContextActionService:()
ContextActionService:()
FFlagUserFreecamPlayerLock
ContextActionService:()
ContextActionService:()
FFlagUserFreecamCustomGui
ContextActionService:()
ContextActionService:()
ContextActionService:()
ContextActionService:()
ContextActionService:()
ContextActionService:()
ContextActionService:()
ContextActionService:()
Input.() navSpeed
Input.() fovSpeed
Input.() rollSpeed
(dt)
FFlagUserFreecamSmoothnessControl Input.(dt)
FFlagUserFreecamDepthOfFieldEffect
FreecamDepthOfField FreecamDepthOfField.Parent Input.(dt)
vel = velSpring:(dt, Input.(dt))
pan = panSpring:(dt, Input.(dt))
fov = fovSpring:(dt, Input.(dt))
roll
FFlagUserFreecamTiltControl roll = rollSpring:(dt, Input.(dt))
zoomFactor = (((/))/((cameraFov/)))
cameraFov = (cameraFov + fov*FOV_GAIN*(dt/zoomFactor), , )
cameraCFrame
FFlagUserFreecamTiltControl
panVector = pan*PAN_GAIN*(dt/zoomFactor)
cameraRot = cameraRot + .(panVector.X, panVector.Y, roll*ROLL_GAIN*(dt/zoomFactor))
FFlagUserFreecamSmoothnessControl
cameraRot = .(cameraRot.x%(*pi), cameraRot.y%(*pi), cameraRot.z%(*pi))
cameraRot = .((cameraRot.x, -PITCH_LIMIT, PITCH_LIMIT), cameraRot.y%(*pi), cameraRot.z)
cameraCFrame = .(cameraPos)*.(cameraRot.x, cameraRot.y, cameraRot.z)*.(vel*NAV_GAIN*dt)
cameraRot = cameraRot + pan*PAN_GAIN*(dt/zoomFactor)
cameraRot = .((cameraRot.x, -PITCH_LIMIT, PITCH_LIMIT), cameraRot.y%(*pi))
cameraCFrame = .(cameraPos)*.(cameraRot.x, cameraRot.y, )*.(vel*NAV_GAIN*dt)
FFlagUserFreecamPlayerLock
playerLockEnabled rootPart
zoomDelta = vel.Z * NAV_GAIN.Z * dt
heightDelta = vel.Y * NAV_GAIN.Y * dt
playerLockZoom = (playerLockZoom + zoomDelta, PLAYER_LOCK_MIN_ZOOM, PLAYER_LOCK_MAX_ZOOM)
playerLockHeight = (playerLockHeight + heightDelta, -PLAYER_LOCK_HEIGHT_RANGE, PLAYER_LOCK_HEIGHT_RANGE)
targetCFrame = .(rootPart.Position + .(, playerLockHeight, ))
rotationCFrame
FFlagUserFreecamTiltControl
rotationCFrame = .(cameraRot.x, cameraRot.y, cameraRot.z)
rotationCFrame = .(cameraRot.x, cameraRot.y, )
cameraCFrame = targetCFrame * rotationCFrame * .(, , playerLockZoom)
cameraPos = cameraCFrame.p
Camera.CFrame = cameraCFrame
Camera.Focus = cameraCFrame
Camera.FieldOfView = cameraFov
()
devAllowsMouseLock = Players.LocalPlayer.DevEnableMouseLock
devMovementModeIsScriptable = Players.LocalPlayer.DevComputerMovementMode == .DevComputerMovementMode.Scriptable
userHasMouseLockModeEnabled = GameSettings.ControlMode == .ControlMode.MouseLockSwitch
userHasClickToMoveEnabled = GameSettings.ComputerMovementMode == .ComputerMovementMode.ClickToMove
MouseLockAvailable = devAllowsMouseLock userHasMouseLockModeEnabled userHasClickToMoveEnabled devMovementModeIsScriptable
MouseLockAvailable
PlayerState = {}
mouseBehavior =
mouseIconEnabled =
cameraType =
cameraFocus =
cameraCFrame =
cameraFieldOfView =
screenGuis = {}
coreGuis = { Backpack = , Chat = , Health = , PlayerList = }
setCores = { BadgesNotificationsActive = , PointsNotificationsActive = }
PlayerState.()
name (coreGuis)
coreGuis[name] = StarterGui:(.CoreGuiType[name])
StarterGui:(.CoreGuiType[name], )
name (setCores)
setCores[name] = StarterGui:(name)
StarterGui:(name, )
playergui = LocalPlayer:()
playergui
existingGuis = {}
_, gui (playergui:())
gui:() gui.Enabled gui.Name ~=
existingGuis[gui] =
.(screenGuis, gui)
gui.Enabled =
FFlagUserFixFreecamGuiChangeVisibility
playerGuiConnection = playergui.ChildAdded:((child)
child:() child.Enabled child.Name ~= existingGuis[child]
.(screenGuis, child)
FFlagUserFreecamCustomGui
child.Enabled = screenGuisEnabled
child.Enabled =
)
cameraFieldOfView = Camera.FieldOfView
Camera.FieldOfView =
cameraType = Camera.CameraType
Camera.CameraType = .CameraType.Custom
cameraCFrame = Camera.CFrame
cameraFocus = Camera.Focus
mouseIconEnabled = UserInputService.MouseIconEnabled
UserInputService.MouseIconEnabled =
FFlagUserExitFreecamBreaksWithShiftlock ()
mouseBehavior = .MouseBehavior.Default
mouseBehavior = UserInputService.MouseBehavior
UserInputService.MouseBehavior = .MouseBehavior.Default
PlayerState.()
name, isEnabled (coreGuis)
isEnabled ~=
(() StarterGui:(.CoreGuiType[name], isEnabled) )
name, isEnabled (setCores)
isEnabled ~=
(() StarterGui:(name, isEnabled) )
_, gui (screenGuis)
gui gui.Parent
FFlagUserFreecamCustomGui
gui ~= freecamGui
(() gui.Enabled = )
(() gui.Enabled = )
FFlagUserFixFreecamGuiChangeVisibility
playerGuiConnection
playerGuiConnection:()
playerGuiConnection =
screenGuis = {}
cameraFieldOfView
(() Camera.FieldOfView = cameraFieldOfView )
cameraFieldOfView =
cameraType
(() Camera.CameraType = cameraType )
cameraType =
cameraCFrame
(() Camera.CFrame = cameraCFrame )
cameraCFrame =
cameraFocus
(() Camera.Focus = cameraFocus )
cameraFocus =
mouseIconEnabled ~=
(() UserInputService.MouseIconEnabled = mouseIconEnabled )
mouseIconEnabled =
mouseBehavior ~=
(() UserInputService.MouseBehavior = mouseBehavior )
mouseBehavior =
PlayerState.() screenGuis
(player)
i, p (playerList)
p == player
.(playerList, i)
currentTargetIndex == i playerLockEnabled
playerLockEnabled =
currentTargetIndex =
currentTargetIndex > i
currentTargetIndex = currentTargetIndex -
currentTargetIndex > #playerList currentTargetIndex <
currentTargetIndex =
()
playerList = Players:()
i, p (playerList)
p == LocalPlayer
currentTargetIndex = i
playerAddedConnection = Players.PlayerAdded:((player)
.(playerList, player)
)
playerRemovingConnection = Players.PlayerRemoving:(removePlayerFromList)
customGui =
Draggable = {}
Draggable.__index = Draggable
Draggable.(dragFrame, targetFrame, callbacks)
self = ({}, Draggable)
self.dragFrame = dragFrame
self.targetFrame = targetFrame
self.callbacks = callbacks {}
self.dragData = { dragging = , dragStart = , startPos = , dragDistance = , isDraggingStarted = , currentTouch = , originalZIndex = targetFrame.ZIndex, DRAG_THRESHOLD = }
self.connections = { mouseUp = , touchUp = , movement = , began = }
self:()
self
Draggable:()
self.connections.mouseUp self.connections.mouseUp:()
self.connections.touchUp self.connections.touchUp:()
self.connections.movement self.connections.movement:()
self.connections.mouseUp =
self.connections.touchUp =
self.connections.movement =
Draggable:()
self.dragData.dragging =
self.dragData.dragStart =
self.dragData.startPos =
self.dragData.dragDistance =
self.dragData.isDraggingStarted =
self.dragData.currentTouch =
self:()
Draggable:(pos1, pos2)
.((pos2.X - pos1.X)^ + (pos2.Y - pos1.Y)^)
Draggable:(frame, position)
absPos, absSize = frame.AbsolutePosition, frame.AbsoluteSize
position.X >= absPos.X position.X <= absPos.X + absSize.X position.Y >= absPos.Y position.Y <= absPos.Y + absSize.Y
Draggable:(input)
self.dragData.dragging self.dragData.dragStart
delta = input.Position - self.dragData.dragStart
self.dragData.dragDistance = self:(input.Position, self.dragData.dragStart)
self.targetFrame.Position = .(self.dragData.startPos.X.Scale, self.dragData.startPos.X.Offset + delta.X, self.dragData.startPos.Y.Scale, self.dragData.startPos.Y.Offset + delta.Y)
Draggable:()
self.dragData.dragging
wasDragged = self.dragData.dragDistance > self.dragData.DRAG_THRESHOLD
wasDragged self.callbacks.onClick self.callbacks.()
self.callbacks.onDragEnd self.callbacks.(wasDragged)
self:()
Draggable:(input)
self.dragData.dragging
input.UserInputType == .UserInputType.MouseButton1
self:()
input.UserInputType == .UserInputType.Touch input == self.dragData.currentTouch
self:()
Draggable:(input)
self.dragData.dragging
input.UserInputType == .UserInputType.MouseMovement input == self.dragData.currentTouch
self.dragData.isDraggingStarted self.dragData.dragDistance > self.dragData.DRAG_THRESHOLD
self.dragData.isDraggingStarted =
self.callbacks.onDragStart self.callbacks.()
self:(input)
Draggable:(input)
isClick = input.UserInputState == .UserInputState.Begin (input.UserInputType == .UserInputType.MouseButton1 input.UserInputType == .UserInputType.Touch)
isClick self.dragData.dragging
self:(self.dragFrame, input.Position)
self.dragData.dragging =
self.dragData.dragStart = input.Position
self.dragData.startPos = self.targetFrame.Position
self.dragData.dragDistance =
self.dragData.isDraggingStarted =
self.dragData.currentTouch = (input.UserInputType == .UserInputType.Touch) input
self:()
self.connections.mouseUp = UserInputService.InputEnded:((endInput)
endInput.UserInputType == .UserInputType.MouseButton1 self:(endInput)
)
self.connections.touchUp = UserInputService.InputEnded:((endInput)
endInput.UserInputType == .UserInputType.Touch self:(endInput)
)
self.connections.movement = UserInputService.InputChanged:((moveInput)
moveInput.UserInputType == .UserInputType.MouseMovement moveInput.UserInputType == .UserInputType.Touch
self:(moveInput)
)
Draggable:()
self.connections.began = self.dragFrame.InputBegan:((input) self:(input) )
Draggable:()
self:()
self.connections.began self.connections.began:()
Slider = {}
Slider.__index = Slider
Slider.(sliderBar, sliderHandle, onChange)
self = ({}, Slider)
self.sliderBar = sliderBar
self.sliderHandle = sliderHandle
self.onChange = onChange
self.dragData = { dragging = , currentTouch = , lastValue = }
self.connections = { began = , mouseUp = , touchUp = , movement = }
self:()
self
Slider:()
self.connections.mouseUp self.connections.mouseUp:()
self.connections.touchUp then self.connections.touchUp:Disconnect() end
if self.connections.movement then self.connections.movement:Disconnect() end
self.connections.mouseUp = nil
self.connections.touchUp = nil
self.connections.movement = nil
end
function Slider:isMouseOverFrame(frame, position)
local absPos, absSize = frame.AbsolutePosition, frame.AbsoluteSize
return position.X >= absPos.X and position.X <= absPos.X + absSize.X and position.Y >= absPos.Y and position.Y <= absPos.Y + absSize.Y
end
function Slider:updatePosition(input)
if not self.dragData.dragging then return end
local mousePos = input.Position.X
local barPos = self.sliderBar.AbsolutePosition.X
local barWidth = self.sliderBar.AbsoluteSize.X
if barWidth <= 0 then return end
local newX = math.clamp(mousePos - barPos - 7, -7, barWidth - 7)
if not self.dragData.lastValue or math.abs(newX - self.dragData.lastValue) > 0.5 then
self.sliderHandle.Position = UDim2.new(0, newX, 0, -5)
local normalizedValue = math.clamp((newX + 7) / barWidth, 0, 1)
if self.onChange then self.onChange(normalizedValue) end
self.dragData.lastValue = newX
end
end
function Slider:onDragEnd() if self.dragData.dragging then self:resetState() end end
function Slider:resetState() self.dragData.dragging = false; self.dragData.currentTouch = nil; self.dragData.lastValue = nil; self:cleanupConnections() end
function Slider:onInputEnded(input)
if not self.dragData.dragging then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then self:onDragEnd()
elseif input.UserInputType == Enum.UserInputType.Touch and input == self.dragData.currentTouch then self:onDragEnd() end
end
function Slider:onMovement(input)
if not self.dragData.dragging then return end
if input.UserInputType == Enum.UserInputType.MouseMovement or input == self.dragData.currentTouch then
self:updatePosition(input)
end
end
function Slider:onInputBegan(input)
local isClick = input.UserInputState == Enum.UserInputState.Begin and (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch)
if isClick and not self.dragData.dragging and self:isMouseOverFrame(self.sliderHandle, input.Position) then
self.dragData.dragging = true
self.dragData.currentTouch = (input.UserInputType == Enum.UserInputType.Touch) and input or nil
self:cleanupConnections()
self.connections.mouseUp = UserInputService.InputEnded:Connect(function(endInput)
if endInput.UserInputType == Enum.UserInputType.MouseButton1 then self:onInputEnded(endInput) end
end)
self.connections.touchUp = UserInputService.InputEnded:Connect(function(endInput)
if endInput.UserInputType == Enum.UserInputType.Touch then self:onInputEnded(endInput) end
end)
self.connections.movement = UserInputService.InputChanged:Connect(function(moveInput)
if moveInput.UserInputType == Enum.UserInputType.MouseMovement or moveInput.UserInputType == Enum.UserInputType.Touch then
self:onMovement(moveInput)
end
end)
self:updatePosition(input)
end
end
function Slider:setup() self.connections.began = self.sliderHandle.InputBegan:Connect(function(input) self:onInputBegan(input) end) end
function Slider:Destroy() self:cleanupConnections(); if self.connections.began then self.connections.began:Disconnect() end end
function Slider:SetValue(normalizedValue) local barWidth = self.sliderBar.AbsoluteSize.X; local newX = math.clamp(normalizedValue * barWidth - 7, -7, barWidth - 7); self.sliderHandle.Position = UDim2.new(0, newX, 0, -5) end
local Toggle = {}
Toggle.__index = Toggle
function Toggle.new(toggleContainer, toggleThumb, onChange)
local self = setmetatable({}, Toggle)
self.toggleContainer = toggleContainer
self.toggleThumb = toggleThumb
self.onChange = onChange
self.state = false
self:setup()
return self
end
function Toggle:animateOn()
local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
TweenService:Create(self.toggleContainer, tweenInfo, {BackgroundColor3 = Color3.fromRGB(100, 200, 255)}):Play()
TweenService:Create(self.toggleThumb, tweenInfo, {Position = UDim2.new(0, self.toggleContainer.AbsoluteSize.X - 22, 0, 2)}):Play()
end
function Toggle:animateOff()
local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
TweenService:Create(self.toggleContainer, tweenInfo, {BackgroundColor3 = Color3.fromRGB(80, 80, 100)}):Play()
TweenService:Create(self.toggleThumb, tweenInfo, {Position = UDim2.new(0, 2, 0, 2)}):Play()
end
function Toggle:SetState(state) self.state = state; if state then self:animateOn() else self:animateOff() end; if self.onChange then self.onChange(state) end end
function Toggle:GetState() return self.state end
function Toggle:Toggle() self:SetState(not self.state) end
function Toggle:setup() local clickBtn = Instance.new("TextButton"); clickBtn.Size = UDim2.new(1,0,1,0); clickBtn.BackgroundTransparency = 1; clickBtn.Text = ""; clickBtn.AutoButtonColor = false; clickBtn.Parent = self.toggleContainer; clickBtn.MouseButton1Click:Connect(function() self:Toggle() end); self.toggleThumb.MouseButton1Click:Connect(function() self:Toggle() end) end
local DummyUI = {}
DummyUI.__index = DummyUI
function DummyUI.new(title, size)
local self = setmetatable({}, DummyUI)
self.title = title or "Freecam Control"
self.size = size or UDim2.new(0, 300, 0, 380)
self.position = UDim2.new(0.5, -150, 0.5, -200)
self.tabs = {}
self.currentTab = nil
self.components = {}
self:createUI()
self:setupAlwaysOnTop()
self:setupDraggable()
return self
end
function DummyUI:createUI()
self.mainFrame = Instance.new("Frame")
self.mainFrame.Name = "DummyUI"
self.mainFrame.Size = self.size
self.mainFrame.Position = self.position
self.mainFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
self.mainFrame.BackgroundTransparency = 0.05
self.mainFrame.BorderSizePixel = 0
self.mainFrame.ClipsDescendants = true
self.mainFrame.Active = true
self.mainFrame.ZIndex = 1000
self.mainFrame.Parent = freecamGui
local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 12)
mainCorner.Parent = self.mainFrame
self.topBar = Instance.new("TextButton")
self.topBar.Size = UDim2.new(1, 0, 0, 40)
self.topBar.Position = UDim2.new(0, 0, 0, 0)
self.topBar.BackgroundColor3 = Color3.fromRGB(35, 35, 45)
self.topBar.BackgroundTransparency = 0.2
self.topBar.BorderSizePixel = 0
self.topBar.Text = ""
self.topBar.AutoButtonColor = false
self.topBar.ZIndex = 1001
self.topBar.Parent = self.mainFrame
local topCorner = Instance.new("UICorner")
topCorner.CornerRadius = UDim.new(0, 12)
topCorner.Parent = self.topBar
local titleLabel = Instance.new("TextLabel")
titleLabel.Size = UDim2.new(1, -50, 1, 0)
titleLabel.Position = UDim2.new(0, 15, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextSize = 14
titleLabel.Text = " " .. self.title
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.TextYAlignment = Enum.TextYAlignment.Center
titleLabel.Parent = self.topBar
self.closeButton = Instance.new("TextButton")
self.closeButton.Size = UDim2.new(0, 32, 0, 32)
self.closeButton.Position = UDim2.new(1, -38, 0, 4)
self.closeButton.BackgroundColor3 = Color3.fromRGB(255, 70, 70)
self.closeButton.BackgroundTransparency = 0.8
self.closeButton.TextColor3 = Color3.fromRGB(255, 255, 255)
self.closeButton.Font = Enum.Font.GothamBold
self.closeButton.TextSize = 16
self.closeButton.Text = "✕"
self.closeButton.AutoButtonColor = false
self.closeButton.BorderSizePixel = 0
self.closeButton.Parent = self.topBar
local closeCorner = Instance.new("UICorner")
closeCorner.CornerRadius = UDim.new(0, 16)
closeCorner.Parent = self.closeButton
self.closeButton.MouseButton1Click:Connect(function()
self.mainFrame.Visible = false
if floatingButton then floatingButton.Visible = true end
end)
self.tabScrollingFrame = Instance.new("ScrollingFrame")
self.tabScrollingFrame.Size = UDim2.new(1, -20, 0, 40)
self.tabScrollingFrame.Position = UDim2.new(0, 10, 0, 48)
self.tabScrollingFrame.BackgroundTransparency = 1
self.tabScrollingFrame.BorderSizePixel = 0
self.tabScrollingFrame.ScrollBarThickness = 3
self.tabScrollingFrame.ScrollBarImageColor3 = Color3.fromRGB(80, 80, 100)
self.tabScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
self.tabScrollingFrame.ScrollingDirection = Enum.ScrollingDirection.X
self.tabScrollingFrame.Parent = self.mainFrame
self.tabLayout = Instance.new("UIListLayout")
self.tabLayout.FillDirection = Enum.FillDirection.Horizontal
self.tabLayout.Padding = UDim.new(0, 8)
self.tabLayout.HorizontalAlignment = Enum.HorizontalAlignment.Left
self.tabLayout.VerticalAlignment = Enum.VerticalAlignment.Center
self.tabLayout.Parent = self.tabScrollingFrame
self.tabLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
self.tabScrollingFrame.CanvasSize = UDim2.new(0, self.tabLayout.AbsoluteContentSize.X + 20, 0, 0)
end)
end
function DummyUI:setupAlwaysOnTop()
self.mainFrame.ZIndex = 1000
local function raiseToTop()
local maxZIndex = 0
for _, child in ipairs(self.mainFrame.Parent:GetChildren()) do
if child:IsA("Frame") and child ~= self.mainFrame and child.Visible and child.ZIndex then
maxZIndex = math.max(maxZIndex, child.ZIndex)
end
end
self.mainFrame.ZIndex = math.max(maxZIndex + 1, 1000)
end
self.topBar.InputBegan:Connect(raiseToTop)
end
function DummyUI:setupDraggable()
self.draggable = Draggable.new(self.topBar, self.mainFrame)
end
function DummyUI:AddTab(tabName)
local tabButton = Instance.new("TextButton")
tabButton.Name = tabName .. "Tab"
tabButton.Size = UDim2.new(0, 100, 0, 34)
tabButton.BackgroundColor3 = Color3.fromRGB(45, 45, 55)
tabButton.TextColor3 = Color3.fromRGB(180, 180, 200)
tabButton.Font = Enum.Font.GothamSemibold
tabButton.TextSize = 13
tabButton.Text = tabName
tabButton.AutoButtonColor = false
tabButton.BorderSizePixel = 0
tabButton.Parent = self.tabScrollingFrame
local buttonCorner = Instance.new("UICorner")
buttonCorner.CornerRadius = UDim.new(0, 17)
buttonCorner.Parent = tabButton
local tabContent = Instance.new("ScrollingFrame")
tabContent.Name = tabName .. "Content"
tabContent.Size = UDim2.new(1, -20, 1, -105)
tabContent.Position = UDim2.new(0, 10, 0, 96)
tabContent.BackgroundTransparency = 1
tabContent.BorderSizePixel = 0
tabContent.ScrollBarThickness = 6
tabContent.ScrollBarImageColor3 = Color3.fromRGB(80, 80, 100)
tabContent.CanvasSize = UDim2.new(0, 0, 0, 0)
tabContent.Visible = false
tabContent.Parent = self.mainFrame
local tabLayout = Instance.new("UIListLayout")
tabLayout.Padding = UDim.new(0, 12)
tabLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
tabLayout.Parent = tabContent
tabLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
tabContent.CanvasSize = UDim2.new(0, 0, 0, tabLayout.AbsoluteContentSize.Y + 20)
end)
self.tabs[tabName] = { button = tabButton, content = tabContent, layout = tabLayout }
if not self.currentTab then self:SwitchTab(tabName) end
tabButton.MouseButton1Click:Connect(function() self:SwitchTab(tabName) end)
return tabContent
end
function DummyUI:SwitchTab(tabName)
if not self.tabs[tabName] then return end
self.currentTab = tabName
local activeColor = Color3.fromRGB(100, 200, 255)
local inactiveColor = Color3.fromRGB(45, 45, 55)
local activeTextColor = Color3.fromRGB(255, 255, 255)
local inactiveTextColor = Color3.fromRGB(180, 180, 200)
for name, tab in pairs(self.tabs) do
tab.button.BackgroundColor3 = (name == tabName) and activeColor or inactiveColor
tab.button.TextColor3 = (name == tabName) and activeTextColor or inactiveTextColor
tab.content.Visible = (name == tabName)
end
end
function DummyUI:AddToggle(parent, config)
local card = Instance.new("Frame")
card.Size = UDim2.new(0, 260, 0, 60)
card.BackgroundColor3 = Color3.fromRGB(35, 35, 45)
card.BackgroundTransparency = 0.3
card.BorderSizePixel = 0
card.Parent = parent
local cardCorner = Instance.new("UICorner")
cardCorner.CornerRadius = UDim.new(0, 10)
cardCorner.Parent = card
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -20, 0, 24)
title.Position = UDim2.new(0, 12, 0, 8)
title.BackgroundTransparency = 1
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.Font = Enum.Font.GothamBold
title.TextSize = 14
title.Text = config.text or "Toggle"
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = card
local toggleContainer = Instance.new("Frame")
toggleContainer.Size = UDim2.new(0, 44, 0, 24)
toggleContainer.Position = UDim2.new(1, -56, 0, 18)
toggleContainer.BackgroundColor3 = Color3.fromRGB(80, 80, 100)
toggleContainer.BorderSizePixel = 0
toggleContainer.ClipsDescendants = true
toggleContainer.Parent = card
local toggleCorner = Instance.new("UICorner")
toggleCorner.CornerRadius = UDim.new(0, 12)
toggleCorner.Parent = toggleContainer
local toggleThumb = Instance.new("TextButton")
toggleThumb.Size = UDim2.new(0, 20, 0, 20)
toggleThumb.Position = UDim2.new(0, 2, 0, 2)
toggleThumb.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
toggleThumb.BorderSizePixel = 0
toggleThumb.Text = ""
toggleThumb.AutoButtonColor = false
toggleThumb.Parent = toggleContainer
local thumbCorner = Instance.new("UICorner")
thumbCorner.CornerRadius = UDim.new(0, 10)
thumbCorner.Parent = toggleThumb
local toggle = Toggle.new(toggleContainer, toggleThumb, config.callback)
if config.default then toggle:SetState(config.default) end
table.insert(self.components, toggle)
return toggle
end
function DummyUI:AddSlider(parent, config)
local card = Instance.new("Frame")
card.Size = UDim2.new(0, 260, 0, 70)
card.BackgroundColor3 = Color3.fromRGB(35, 35, 45)
card.BackgroundTransparency = 0.3
card.BorderSizePixel = 0
card.Parent = parent
local cardCorner = Instance.new("UICorner")
cardCorner.CornerRadius = UDim.new(0, 10)
cardCorner.Parent = card
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -20, 0, 24)
title.Position = UDim2.new(0, 12, 0, 8)
title.BackgroundTransparency = 1
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.Font = Enum.Font.GothamBold
title.TextSize = 14
title.Text = config.text or "Slider"
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = card
local valueLabel = Instance.new("TextLabel")
valueLabel.Size = UDim2.new(0, 50, 0, 24)
valueLabel.Position = UDim2.new(1, -62, 0, 8)
valueLabel.BackgroundTransparency = 1
valueLabel.TextColor3 = Color3.fromRGB(100, 200, 255)
valueLabel.Font = Enum.Font.GothamBold
valueLabel.TextSize = 14
valueLabel.Text = tostring(config.default or 0)
valueLabel.TextXAlignment = Enum.TextXAlignment.Right
valueLabel.Parent = card
local sliderBar = Instance.new("Frame")
sliderBar.Size = UDim2.new(0, 220, 0, 4)
sliderBar.Position = UDim2.new(0, 20, 0, 48)
sliderBar.BackgroundColor3 = Color3.fromRGB(60, 60, 80)
sliderBar.BorderSizePixel = 0
sliderBar.Parent = card
local barCorner = Instance.new("UICorner")
barCorner.CornerRadius = UDim.new(0, 2)
barCorner.Parent = sliderBar
local sliderFill = Instance.new("Frame")
local defaultPercent = (config.default or 0) / (config.max or 100)
sliderFill.Size = UDim2.new(defaultPercent, 0, 1, 0)
sliderFill.BackgroundColor3 = Color3.fromRGB(100, 200, 255)
sliderFill.BorderSizePixel = 0
sliderFill.Parent = sliderBar
local fillCorner = Instance.new("UICorner")
fillCorner.CornerRadius = UDim.new(0, 2)
fillCorner.Parent = sliderFill
local sliderHandle = Instance.new("TextButton")
sliderHandle.Size = UDim2.new(0, 14, 0, 14)
sliderHandle.Position = UDim2.new(0, defaultPercent * 220 - 7, 0, -5)
sliderHandle.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
sliderHandle.Text = ""
sliderHandle.AutoButtonColor = false
sliderHandle.BorderSizePixel = 0
sliderHandle.Parent = sliderBar
local handleCorner = Instance.new("UICorner")
handleCorner.CornerRadius = UDim.new(0, 7)
handleCorner.Parent = sliderHandle
local min = config.min or 0
local max = config.max or 100
local slider = Slider.new(sliderBar, sliderHandle, function(normalized)
local value = min + normalized * (max - min)
valueLabel.Text = tostring(math.floor(value + 0.5))
sliderFill.Size = UDim2.new(normalized, 0, 1, 0)
if config.callback then config.callback(value) end
end)
table.insert(self.components, slider)
return slider
end
function DummyUI:AddLabel(parent, text)
local label = Instance.new("TextLabel")
label.Size = UDim2.new(0, 260, 0, 40)
label.BackgroundColor3 = Color3.fromRGB(35, 35, 45)
label.BackgroundTransparency = 0.3
label.TextColor3 = Color3.fromRGB(200, 200, 220)
label.Font = Enum.Font.Gotham
label.TextSize = 12
label.Text = text
label.TextWrapped = true
label.Parent = parent
local labelCorner = Instance.new("UICorner")
labelCorner.CornerRadius = UDim.new(0, 10)
labelCorner.Parent = label
return label
end
function DummyUI:AddKeybind(parent, config)
local card = Instance.new("Frame")
card.Size = UDim2.new(0, 260, 0, 90)
card.BackgroundColor3 = Color3.fromRGB(35, 35, 45)
card.BackgroundTransparency = 0.3
card.BorderSizePixel = 0
card.Parent = parent
local cardCorner = Instance.new("UICorner")
cardCorner.CornerRadius = UDim.new(0, 10)
cardCorner.Parent = card
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -20, 0, 24)
title.Position = UDim2.new(0, 12, 0, 8)
title.BackgroundTransparency = 1
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.Font = Enum.Font.GothamBold
title.TextSize = 14
title.Text = config.text or "Keybind"
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = card
local desc = Instance.new("TextLabel")
desc.Size = UDim2.new(1, -24, 0, 20)
desc.Position = UDim2.new(0, 12, 0, 32)
desc.BackgroundTransparency = 1
desc.TextColor3 = Color3.fromRGB(150, 150, 170)
desc.Font = Enum.Font.Gotham
desc.TextSize = 11
desc.Text = "Press to record new key combination (max 3 keys)"
desc.TextXAlignment = Enum.TextXAlignment.Left
desc.Parent = card
local keybindButton = Instance.new("TextButton")
keybindButton.Size = UDim2.new(0, 200, 0, 36)
keybindButton.Position = UDim2.new(0, 30, 0, 54)
keybindButton.BackgroundColor3 = Color3.fromRGB(45, 45, 55)
keybindButton.TextColor3 = Color3.fromRGB(255, 255, 255)
keybindButton.Font = Enum.Font.GothamBold
keybindButton.TextSize = 13
keybindButton.Text = table.concat(config.default or {"Shift", "P"}, "+")
keybindButton.AutoButtonColor = false
keybindButton.BorderSizePixel = 1
keybindButton.BorderColor3 = Color3.fromRGB(80, 80, 100)
keybindButton.Parent = card
local keybindCorner = Instance.new("UICorner")
keybindCorner.CornerRadius = UDim.new(0, 18)
keybindCorner.Parent = keybindButton
local selectedKeys = {}
local isListening = false
local activeConnection = nil
local function getKeyName(keyCode)
local name = keyCode.Name
if name == "LeftControl" or name == "RightControl" then return "Ctrl"
elseif name == "LeftAlt" or name == "RightAlt" then return "Alt"
elseif name == "LeftShift" or name == "RightShift" then return "Shift"
else return name end
end
local function updateDisplay()
local names = {}
for _, k in ipairs(selectedKeys) do table.insert(names, getKeyName(k)) end
keybindButton.Text = (#names > 0 and table.concat(names, "+")) or "..."
if config.onChange then config.onChange(selectedKeys) end
end
local function startListening()
isListening = true
selectedKeys = {}
keybindButton.Text = "Press keys..."
keybindButton.BackgroundColor3 = Color3.fromRGB(70, 70, 90)
end
local function stopListening()
isListening = false
keybindButton.BackgroundColor3 = Color3.fromRGB(45, 45, 55)
updateDisplay()
end
if config.default then
for _, keyName in ipairs(config.default) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then
table.insert(selectedKeys, ek)
break
end
end
end
updateDisplay()
end
keybindButton.MouseButton1Click:Connect(function()
if isListening then
stopListening()
if activeConnection then
activeConnection:Disconnect()
activeConnection = nil
end
else
startListening()
if activeConnection then activeConnection:Disconnect() end
activeConnection = UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if isListening and input.KeyCode ~= Enum.KeyCode.Unknown then
if #selectedKeys < 3 and not table.find(selectedKeys, input.KeyCode) then
table.insert(selectedKeys, input.KeyCode)
updateDisplay()
end
task.wait(0.2)
if isListening and #selectedKeys > 0 then
stopListening()
if activeConnection then
activeConnection:Disconnect()
activeConnection = nil
end
end
end
end)
end
end)
table.insert(self.components, {Destroy = function() if activeConnection then activeConnection:Disconnect() end end})
return {GetKeys = function() return selectedKeys end}
end
function DummyUI:Destroy()
if self.draggable then self.draggable:Destroy() end
for _, component in ipairs(self.components) do
if component.Destroy then component:Destroy() end
end
if self.mainFrame then self.mainFrame:Destroy() end
end
local ui = DummyUI.new("Freecam Control", UDim2.new(0, 300, 0, 380))
uiMainFrame = ui.mainFrame
floatingButton = Instance.new("TextButton")
floatingButton.Name = "OpenFCUI"
floatingButton.Size = UDim2.new(0, 120, 0, 40)
floatingButton.Position = UDim2.new(0.5, -235, 0.9, -372)
floatingButton.Text = "[OpenFC-UI]"
floatingButton.TextColor3 = Color3.fromRGB(255, 255, 255)
floatingButton.TextSize = 14
floatingButton.Draggable = true
floatingButton.Font = Enum.Font.GothamBold
floatingButton.BackgroundColor3 = Color3.fromRGB(100, 200, 255)
floatingButton.BackgroundTransparency = 0.3
floatingButton.BorderSizePixel = 0
floatingButton.Parent = freecamGui
floatingButton.ZIndex = 100
local floatCorner = Instance.new("UICorner")
floatCorner.CornerRadius = UDim.new(0, 20)
floatCorner.Parent = floatingButton
floatingButton.Visible = false
floatingButton.MouseButton1Click:Connect(function()
if uiMainFrame then uiMainFrame.Visible = true end
floatingButton.Visible = false
end)
local function updateFloatingButtonPosition()
local screenSize = freecamGui.AbsoluteSize
floatingButton.Position = UDim2.new(0.5, -60, 0.9, 0)
end
freecamGui:GetPropertyChangedSignal("AbsoluteSize"):Connect(updateFloatingButtonPosition)
updateFloatingButtonPosition()
local homeTab = ui:AddTab("Home")
local freecamToggle = ui:AddToggle(homeTab, { text = "Freecam Enabled", callback = function(state) if state then StartFreecam() else StopFreecam() end end, default = false })
ui:AddSlider(homeTab, { text = "Movement Speed", min = 0.25, max = 4, default = 1, callback = function(val) mobileNavSpeed = val end })
ui:AddSlider(homeTab, { text = "Mouse Sensitivity", min = 0.2, max = 3, default = 1, callback = function(val) mouseSensitivity = val end })
ui:AddSlider(homeTab, { text = "Touch Look Sensitivity", min = 0.2, max = 3, default = 1, callback = function(val) touchLookSensitivity = val end })
ui:AddSlider(homeTab, { text = "FOV Sensitivity", min = 0.2, max = 3, default = 1, callback = function(val) fovSensitivity = val end })
ui:AddSlider(homeTab, { text = "Movement Smoothing", min = 0.1, max = 5, default = 1.5, callback = function(val) VEL_STIFFNESS = val; velSpring:SetFreq(val) end })
ui:AddSlider(homeTab, { text = "Look Smoothing", min = 0.1, max = 5, default = 1, callback = function(val) PAN_STIFFNESS = val; panSpring:SetFreq(val) end })
ui:AddSlider(homeTab, { text = "FOV Smoothing", min = 0.1, max = 5, default = 4, callback = function(val) FOV_STIFFNESS = val; fovSpring:SetFreq(val) end })
ui:AddSlider(homeTab, { text = "Roll Smoothing", min = 0.1, max = 5, default = 1, callback = function(val) ROLL_STIFFNESS = val; rollSpring:SetFreq(val) end })
ui:AddSlider(homeTab, { text = "Tilt Speed", min = 0.2, max = 3, default = 1, callback = function(val) rollSpeed = val end })
ui:AddLabel(homeTab, "Controls:\nWASD / Thumbstick - Move\nMouse/Right Touch - Look\nQ/E - Up/Down\nZ/C - Tilt (Keyboard)\nTilt Buttons (Bottom Left)\nPlayer Lock Bar (Bottom Center)\nShift - Slow mode")
local keybindTab = ui:AddTab("Keybind")
local customToggleKeys = {"LeftShift", "P"}
local customPlayerLockKeys = {"Slash"}
local customPlayerLockPrevKeys = {"R"}
local customPlayerLockNextKeys = {"T"}
local customDoFKeys = {"BackSlash"}
local customHideGuiKeys = {"G"}
local customHidePlayerGuiKeys = {"X"}
local customLeaderboardKeys = {"L"}
local customTiltResetKeys = {"Z", "C"}
local customTiltLeftKeys = {"Z"}
local customTiltRightKeys = {"C"}
local function rebuildToggleFreecamKeybind()
ContextActionService:UnbindAction("FreecamToggle")
if #customToggleKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customToggleKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamToggle", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown then ToggleFreecam() end
end
return Enum.ContextActionResult.Pass
end, false, TOGGLE_INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildPlayerLockKeybind()
ContextActionService:UnbindAction("FreecamKeyboardPlayerLockToggle")
if #customPlayerLockKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customPlayerLockKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerLockToggle", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown then
playerLockEnabled = not playerLockEnabled
if playerLockEnabled then
playerLockZoom = PLAYER_LOCK_DEFAULT_ZOOM
playerLockHeight = PLAYER_LOCK_DEFAULT_HEIGHT
rootPart = findPlayerLockRootPart(0)
end
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildPlayerLockPrevKeybind()
ContextActionService:UnbindAction("FreecamKeyboardPlayerLockPrev")
if #customPlayerLockPrevKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customPlayerLockPrevKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerLockPrev", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown and playerLockEnabled and #playerList > 0 then
rootPart = findPlayerLockRootPart(-1)
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildPlayerLockNextKeybind()
ContextActionService:UnbindAction("FreecamKeyboardPlayerLockNext")
if #customPlayerLockNextKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customPlayerLockNextKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerLockNext", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown and playerLockEnabled and #playerList > 0 then
rootPart = findPlayerLockRootPart(1)
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildDoFKeybind()
ContextActionService:UnbindAction("FreecamKeyboardDoFToggle")
if #customDoFKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customDoFKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardDoFToggle", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown and FreecamDepthOfField then
FreecamDepthOfField.Enabled = not FreecamDepthOfField.Enabled
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildHideGuiKeybind()
ContextActionService:UnbindAction("FreecamKeyboardCustomGuiToggle")
if #customHideGuiKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customHideGuiKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardCustomGuiToggle", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown and freecamGui and freecamGui.Parent then
freecamGui.Enabled = not freecamGui.Enabled
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildHidePlayerGuiKeybind()
ContextActionService:UnbindAction("FreecamKeyboardPlayerGuiToggle")
if #customHidePlayerGuiKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customHidePlayerGuiKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardPlayerGuiToggle", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown then
screenGuisEnabled = not screenGuisEnabled
local screenGuis = PlayerState.getScreenGuis()
for _, gui in pairs(screenGuis) do
if gui.Parent and gui ~= freecamGui then
gui.Enabled = screenGuisEnabled
end
end
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildLeaderboardKeybind()
ContextActionService:UnbindAction("FreecamKeyboardLeaderboardToggle")
if #customLeaderboardKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customLeaderboardKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardLeaderboardToggle", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown then
leaderboardEnabled = not leaderboardEnabled
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, leaderboardEnabled)
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
local function rebuildTiltResetKeybind()
ContextActionService:UnbindAction("FreecamKeyboardTiltReset")
if #customTiltResetKeys >= 1 then
local macroKeys = {}
for i, keyName in ipairs(customTiltResetKeys) do
for _, ek in pairs(Enum.KeyCode:GetEnumItems()) do
if ek.Name == keyName then macroKeys[i] = ek; break end
end
end
if #macroKeys > 0 then
local lastKey = macroKeys[#macroKeys]
ContextActionService:BindActionAtPriority("FreecamKeyboardTiltReset", function(action, state, input)
if state == Enum.UserInputState.Begin and input.KeyCode == lastKey then
local allDown = true
for i = 1, #macroKeys - 1 do
if not UserInputService:IsKeyDown(macroKeys[i]) then allDown = false; break end
end
if allDown then
cameraRot = Vector3.new(cameraRot.x, cameraRot.y, 0)
rollSpring:Reset(0)
end
end
return Enum.ContextActionResult.Pass
end, false, INPUT_PRIORITY, lastKey)
end
end
end
ui:AddKeybind(keybindTab, { text = "Toggle Freecam", default = customToggleKeys, onChange = function(keys)
customToggleKeys = {}; for _, k in ipairs(keys) do table.insert(customToggleKeys, k.Name) end
if #customToggleKeys == 0 then customToggleKeys = {"LeftShift", "P"} end
rebuildToggleFreecamKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Tilt Left", default = customTiltLeftKeys, onChange = function(keys)
customTiltLeftKeys = {}; for _, k in ipairs(keys) do table.insert(customTiltLeftKeys, k.Name) end
if #customTiltLeftKeys == 0 then customTiltLeftKeys = {"Z"} end
end })
ui:AddKeybind(keybindTab, { text = "Tilt Right", default = customTiltRightKeys, onChange = function(keys)
customTiltRightKeys = {}; for _, k in ipairs(keys) do table.insert(customTiltRightKeys, k.Name) end
if #customTiltRightKeys == 0 then customTiltRightKeys = {"C"} end
end })
ui:AddKeybind(keybindTab, { text = "Player Lock Toggle", default = customPlayerLockKeys, onChange = function(keys)
customPlayerLockKeys = {}; for _, k in ipairs(keys) do table.insert(customPlayerLockKeys, k.Name) end
if #customPlayerLockKeys == 0 then customPlayerLockKeys = {"Slash"} end
rebuildPlayerLockKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Player Lock Previous", default = customPlayerLockPrevKeys, onChange = function(keys)
customPlayerLockPrevKeys = {}; for _, k in ipairs(keys) do table.insert(customPlayerLockPrevKeys, k.Name) end
if #customPlayerLockPrevKeys == 0 then customPlayerLockPrevKeys = {"R"} end
rebuildPlayerLockPrevKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Player Lock Next", default = customPlayerLockNextKeys, onChange = function(keys)
customPlayerLockNextKeys = {}; for _, k in ipairs(keys) do table.insert(customPlayerLockNextKeys, k.Name) end
if #customPlayerLockNextKeys == 0 then customPlayerLockNextKeys = {"T"} end
rebuildPlayerLockNextKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Depth of Field Toggle", default = customDoFKeys, onChange = function(keys)
customDoFKeys = {}; for _, k in ipairs(keys) do table.insert(customDoFKeys, k.Name) end
if #customDoFKeys == 0 then customDoFKeys = {"BackSlash"} end
rebuildDoFKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Hide Freecam UI", default = customHideGuiKeys, onChange = function(keys)
customHideGuiKeys = {}; for _, k in ipairs(keys) do table.insert(customHideGuiKeys, k.Name) end
if #customHideGuiKeys == 0 then customHideGuiKeys = {"G"} end
rebuildHideGuiKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Hide Player GUI", default = customHidePlayerGuiKeys, onChange = function(keys)
customHidePlayerGuiKeys = {}; for _, k in ipairs(keys) do table.insert(customHidePlayerGuiKeys, k.Name) end
if #customHidePlayerGuiKeys == 0 then customHidePlayerGuiKeys = {"X"} end
rebuildHidePlayerGuiKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Toggle Leaderboard", default = customLeaderboardKeys, onChange = function(keys)
customLeaderboardKeys = {}; for _, k in ipairs(keys) do table.insert(customLeaderboardKeys, k.Name) end
if #customLeaderboardKeys == 0 then customLeaderboardKeys = {"L"} end
rebuildLeaderboardKeybind()
end })
ui:AddKeybind(keybindTab, { text = "Tilt Reset", default = customTiltResetKeys, onChange = function(keys)
customTiltResetKeys = {}; for _, k in ipairs(keys) do table.insert(customTiltResetKeys, k.Name) end
if #customTiltResetKeys == 0 then customTiltResetKeys = {"Z", "C"} end
rebuildTiltResetKeybind()
end })
ui:AddLabel(keybindTab, "Click any keybind button to record\na new key combination (max 3 keys)")
rebuildToggleFreecamKeybind()
rebuildPlayerLockKeybind()
rebuildPlayerLockPrevKeybind()
rebuildPlayerLockNextKeybind()
rebuildDoFKeybind()
rebuildHideGuiKeybind()
rebuildHidePlayerGuiKeybind()
rebuildLeaderboardKeybind()
rebuildTiltResetKeybind()
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 FFlagUserFreecamCustomGui then
if not touchGui then
touchGui = CreateTouchControls()
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
function DestroyAllUI()
if touchGui then touchGui:Destroy() touchGui = nil end
if customGui then customGui:Destroy() customGui = nil end
end
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
DestroyAllUI()
screenGuisEnabled = false
leaderboardEnabled = false
end
Input.StopCapture()
pcall(function() RunService:UnbindFromRenderStep("Freecam") end)
PlayerState.Pop()
end
do
local enabled = false
function ToggleFreecam()
if enabled then StopFreecam() else StartFreecam() end
enabled = not enabled
if FFlagUserFreecamGuiDestabilization then script:SetAttribute(FREECAM_ENABLED_ATTRIBUTE_NAME, enabled) end
if freecamToggle and freecamToggle.SetState then
freecamToggle:SetState(enabled)
end
end
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 attributeValue ~= enabled then
if attributeValue then StartFreecam() enabled = true else StopFreecam() enabled = false end
if freecamToggle and freecamToggle.SetState then
freecamToggle:SetState(enabled)
end
end
end)
end
end
return {}Feeecam ui made by official roblox and remaster by pnsdg how to use: 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 DO NOT USE Keybind settngs it's really buggy MOBILE CONTROLS: Left thumbstick (bottom-left) - Move camera forward/back/strafe Right side touch & drag - Look around (rotate) - Works simultaneously with joystick Pinch to zoom on right side - Zoom in/out (pinch out = zoom in, pinch in = zoom out) 🔽 button - Fly down (LEFT side) 🔼 button - Fly up (RIGHT side) Arrow circle is for tilt camera left, right

Universal