Skip to content

Freecam (tm.freecam) ​

Client side only. A free flying camera tethered to a point, for in-world editors and previews. It starts where the current camera is, can only fly within maxRadius of the point it is tethered to, and does not pass through walls.

ControlAction
MouseLook
W A S DMove
E or SpaceUp (Space only with spaceLift ~= false)
Q or Left CtrlDown
Left ShiftBoost
ScrollSpeed (field of view while framing a shot or holding Left Alt)

The caller owns the input. Disable controls every frame (DisableAllControlActions(0)) and call tick.

lua
tm.freecam.start(coords, 8.0)
while tm.freecam.isActive() do
    DisableAllControlActions(0)
    tm.freecam.tick(true)
    Wait(0)
end
tm.freecam.stop()

The freecam owns no thread of its own, so it costs nothing until you run a loop.

Functions ​

CallDescription
start(origin, maxRadius?, opts?)Starts the camera tethered to origin (a position), within maxRadius meters (default 8). Ignored while already active.
stop()Stops it, destroys the camera and clears the streaming focus. Safe when inactive.
tick(canMove, framing?)Advances one frame. canMove enables mouse look and movement this frame. framing makes the scroll wheel zoom (FOV) instead of changing speed. Holding Left Alt (control 19) also zooms. Controls must already be disabled.
isActive()Whether the camera is running.
getCoords()Where the camera last was. Still valid after stop, so a later start can resume from it.
getRotation()The rotation as pitch, roll, yaw.
setAnchor(origin)Retethers a running camera without changing the view, for a moving placement preview.
snapshot()coords, rotation, fov of the camera as the game has it, to store a framed shot. Returns nothing while stopped.
createEditor(opts?)Camera ownership and player freezing for in-world editors, see below.

start options ​

OptionDescription
coordsWhere the camera starts (default: where the current camera is).
rotationStarting rotation (default: the current camera's, or facing origin when coords is given).
fovStarting field of view (default: the current camera's).
collideStop at walls, default true.
streamStream the world in around the camera, for far-off spots, default false.
speedBase fly speed, default 1.5.
spaceLiftSpace flies up, default true. false leaves Space free for the caller, and E is up.

Editors ​

tm.freecam.createEditor(opts?) returns an editor that shares the camera with the player's frozen ped. The caller owns the frame loop. opts takes the start options plus maxRadius (default 30). Editor cameras fly through walls unless you pass collide = true.

MethodDescription
editor.toggle(origin)Starts the camera and freezes the player, or stops both. Returns whether the editor is active.
editor.tick(canMove, origin?)Retethers to origin when given and ticks the camera. If the camera was stopped from outside, it releases the player.
editor.stop()Stops the camera and unfreezes the player to the state it had before.
editor.isActive()Whether this editor owns the running camera.

Starting an editor fires the local event tm_lib:freecam:starting, so a staff camera (or anything else that owns the fly and click controls) can hand them over first. A newer camera started by someone else is never stopped by an old editor.

Cleanup ​

The freecam and every editor stop when the resource stops and when a character unloads (tm_lib:fw:playerUnloaded), so a camera or a frozen ped is never left behind.