Skip to main content

freecam

smooth, professional camera control system.

overview​

freecam detaches the camera from your character and lets you fly freely. it includes:

  • spring-based smooth movement
  • adjustable speed
  • fov control
  • multi-input support (keyboard, mouse, gamepad)
  • automatic focus distance

how it works​

camera detachment​

when enabled, freecam:

  1. saves your current camera state
  2. sets camera type to Custom
  3. disables mouse icon
  4. locks mouse behavior to Default
  5. hides core guis (backpack, chat, health, playerlist)
  6. binds movement inputs

movement system​

uses spring physics for smooth, natural movement:

VEL_STIFFNESS = 1.5   -- movement smoothing
PAN_STIFFNESS = 1.0 -- rotation smoothing
FOV_STIFFNESS = 4.0 -- fov transition smoothing

the spring system creates acceleration/deceleration curves instead of instant movement.

input processing​

every frame:

  1. reads input from keyboard, mouse, gamepad
  2. calculates target velocity and rotation
  3. applies spring physics
  4. updates camera cframe and fov
  5. calculates focus distance

speed system​

  • range: 0.01x to 4x
  • default: 1x
  • adjustment: ±0.75 per arrow press
  • sprint multiplier: 0.25x (when shift held)

fov system​

  • range: 1° to 120°
  • default: 70°
  • zoom factor: automatically adjusts pan sensitivity based on fov

lower fov = slower perceived rotation higher fov = faster perceived rotation

focus distance​

calculates where the camera is "looking" by:

  1. casting 9 rays from viewport corners and center
  2. finding closest intersection point
  3. setting camera focus to that distance

this ensures proper depth sorting and rendering.

controls​

see the keybinds page for complete control reference.

technical details​

constants​

NAV_GAIN = Vector3.new(1, 1, 1) * 64
PAN_GAIN = Vector2.new(0.75, 1) * 8
FOV_GAIN = 300
PITCH_LIMIT = rad(90)
  • NAV_GAIN: movement speed multiplier
  • PAN_GAIN: rotation speed multiplier
  • FOV_GAIN: fov change speed
  • PITCH_LIMIT: prevents camera flipping

spring implementation​

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

this creates smooth, physics-based transitions.

input handling​

freecam binds inputs at high priority to override default camera controls:

ContextActionService:BindActionAtPriority(
"FreecamKeyboard",
Keypress,
false,
INPUT_PRIORITY,
-- keycodes here
)

advanced usage​

customizing feel​

edit these values in features/freecam.lua:

-- stiffer movement (more responsive)
VEL_STIFFNESS = 3.0

-- looser movement (more floaty)
VEL_STIFFNESS = 0.5

-- faster base speed
NAV_GAIN = Vector3.new(1, 1, 1) * 128

-- higher fov limit
-- change line: cameraFov = clamp(cameraFov + fov*FOV_GAIN*(dt/zoomFactor), 1, 150)

cinematic techniques​

slow reveals:

  • speed: 0.1x - 0.3x
  • hold shift for extra control
  • use low fov (30-50°) for compression

fast travel:

  • speed: 3x - 4x
  • high fov (90-120°) for sense of speed
  • plan path beforehand

orbit shots:

  • medium speed (1x - 1.5x)
  • mouse for smooth rotation
  • maintain consistent distance from subject

limitations​

freecam cannot currently:

  • record camera paths
  • save positions
  • interpolate between points
  • control depth of field
  • adjust motion blur

these features are planned for future releases.

source code​

location: features/freecam.lua

the freecam module is ~500 lines and includes:

  • spring physics system
  • input handling for 3 input types
  • camera state management
  • focus distance calculation

troubleshooting​

camera feels laggy​

  • increase game fps
  • reduce stiffness values
  • check for conflicting scripts

controls not responding​

  • ensure inputs aren't being processed by game
  • check executor injected properly
  • verify no other freecam scripts running

fov stuck​

  • press z twice to reset
  • check mouse wheel working
  • try gamepad buttons instead