Physical Security Camera System
This system creates physical Live CCTV camera feeds using ViewportFrames.
| CCTV.rbxl (102.6 KB) | — | Creator Store |
It supports:
- Multiple cameras
- Multiple display screens
- Camera grouping via the
CameraGroupattribute StreamingEnabledsupport- Automatic discovery of tagged instances
For example, you could create a prison with:
CameraGroup = "CellBlockA"CameraGroup = "CellBlockB"
Displays assigned to each group will automatically show the appropriate camera feeds.
Quick Setup
1. Install
Place the SecurityCamera package inside ServerScriptService.
2. Tag Cameras
Tag every camera part with:
SecurityCamera.Camera
3. Tag Displays
Tag every monitor/display part with:
SecurityCamera.Display
4. (Optional) Configure Renderable Objects
You can limit what appears inside CCTV feeds by either:
- Tagging instances with
SecurityCamera.Renderable
or placing renderable objects inside
Workspace.CCTVRenderable
5. (Optional) Configure Camera & Display Attributes
Attributes override the global defaults for individual cameras or displays.
6. Start the Service
local Workspace = game:GetService("Workspace")
local SecurityCameraService = require(script:WaitForChild("SecurityCameraService"))
local cameraService = SecurityCameraService.new({
RenderSourceFolder = Workspace:FindFirstChild("CCTVRenderable"),
PixelsPerStud = 90,
Face = Enum.NormalId.Front,
MaxSelectedCameras = 4,
MaxActiveScreensPerPlayer = 2,
MaxActiveFeedsPerPlayer = 4,
ActivationRange = 80,
RenderOnlyConfiguredSources = true,
MirrorCharactersForStreaming = true,
CharacterMirrorUpdateRate = 10,
UpdateRate = 10,
Debug = false,
AutoDiscover = true,
})
cameraService:Start()
API Documentation
Tags
SecurityCamera.Camera
Assign this tag to any BasePart that should function as a CCTV camera.
The part’s CFrame determines the camera’s position and viewing direction.
SecurityCamera.Display
Assign this tag to any BasePart that should display CCTV feeds.
When a player is close enough, the system automatically creates a client-side SurfaceGui on the specified face.
SecurityCamera.Renderable
Optional
Use this tag on parts, models, or folders that should appear inside CCTV feeds.
When RenderOnlyConfiguredSources = true, feeds render in the following order:
- Tagged
SecurityCamera.Renderableinstances Workspace.CCTVRenderable- Player characters
If RenderOnlyConfiguredSources = false, eligible Workspace content is rendered automatically.
Camera Attributes
These attributes are applied to parts tagged with SecurityCamera.Camera.
DisplayName: string
Display name shown above the feed.
DisplayName = Lobby Camera
If omitted, an ID such as CAM_001 is generated automatically.
FieldOfView: number
Camera field of view.
FieldOfView = 70
Default: 70
Range: 1–120
CameraGroup: string
Groups cameras and displays together.
CameraGroup = Lobby
Displays with the same group automatically receive those camera feeds.
Face: string
Surface of the display that receives the SurfaceGui.
Face = Front
PixelsPerStud: number
Viewport resolution density.
PixelsPerStud = 90
MaxSelectedCameras: number
Maximum number of feeds shown simultaneously.
MaxSelectedCameras = 4
Constructor
SecurityCameraService.new(props)
Rendering
RenderSourceFolder: Instance?
Fallback folder or model used when no tagged renderables exist.
Typically:
Workspace:FindFirstChild("CCTVRenderable")
RenderOnlyConfiguredSources: boolean?
Default:
true
When enabled, feeds render only:
SecurityCamera.Renderable
Workspace.CCTVRenderable
When disabled, feeds clone all eligible Workspace content except:
Terrain
Camera instances
Scripts
LocalScripts
Player character models
PixelsPerStud: number?
Default:
80
Face: Enum.NormalId?
Default:
Enum.NormalId.Front
Display Limits
MaxSelectedCameras
Default:
4
MaxActiveScreensPerPlayer
Maximum nearby displays rendered by each player.
Default:
2
MaxActiveFeedsPerPlayer
Maximum active feeds rendered per player.
Default:
MaxSelectedCameras or 4
ActivationRange
Distance required before a display activates.
Default:
80
Streaming Support
MirrorCharactersForStreaming
Default:
true
When enabled, server-side character mirrors are replicated so CCTV feeds continue displaying players when StreamingEnabled unloads their Workspace character.
CharacterMirrorUpdateRate
Mirror update frequency.
Default:
UpdateRate or 10
UpdateRate
Feed refresh rate.
Default:
10
Tags
CameraTag
Default:
SecurityCamera.Camera
DisplayTag
Default:
SecurityCamera.Display
RenderableTag
Default:
SecurityCamera.Renderable
Discovery
AutoDiscover
Default:
true
When disabled, manually refresh tagged instances:
cameraService:RefreshTaggedInstances()
Debug
Default:
false
Enables debug output.
Service Methods
Start
cameraService:Start()
Starts the system.
This will:
- Discover tagged cameras and displays
- Replicate configuration
- Start character mirrors
- Deploy the client package
- Listen for newly tagged instances
Destroy
cameraService:Destroy()
Stops the system.
This:
- Disconnects listeners
- Removes replicated configuration
- Removes character mirrors
- Removes deployed client packages
- Clears camera and display registries
RefreshTaggedInstances
cameraService:RefreshTaggedInstances()
Manually rescans tagged cameras and displays.
Useful when:
AutoDiscover = false
AddCamera
cameraService:AddCamera(id, cameraPart, displayName, fieldOfView)
Example:
cameraService:AddCamera(
"VaultCam",
workspace.VaultCameraPart,
"Vault Camera",
70
)
AddScreen
cameraService:AddScreen(id, screenPart, cameraIds, displayName)
Automatic camera assignment:
cameraService:AddScreen(
"LobbyScreen",
workspace.LobbyMonitor,
nil,
"Lobby Monitor"
)
Specific cameras:
cameraService:AddScreen(
"VaultScreen",
workspace.VaultMonitor,
{"VaultCam", "HallwayCam"},
"Vault Monitor"
)
RemoveCamera
cameraService:RemoveCamera("VaultCam")
RemoveScreen
cameraService:RemoveScreen("VaultScreen")
Multiplayer
Each player renders CCTV feeds locally.
This means:
- Camera selection is per-player.
- Displays activate independently for each player.
- Distant displays consume no rendering cost.
- Feed rendering is limited by
MaxActiveScreensPerPlayer. - Individual displays are limited by
MaxActiveFeedsPerPlayerandMaxSelectedCameras.
StreamingEnabled
When using StreamingEnabled, distant player characters may not exist on the client.
Keep:
MirrorCharactersForStreaming = true
The server creates mirrors inside:
ReplicatedStorage.SecurityCameraCharacterMirrors
Feeds automatically use:
- the real streamed character when available
- the replicated mirror otherwise
Mirrors remove:
Scripts
LocalScripts
Sounds
to prevent duplicated character sounds.
Recommended Settings
General
MaxSelectedCameras = 4
MaxActiveScreensPerPlayer = 2
MaxActiveFeedsPerPlayer = 4
ActivationRange = 80
RenderOnlyConfiguredSources = true
MirrorCharactersForStreaming = true
CharacterMirrorUpdateRate = 10
UpdateRate = 10
PixelsPerStud = 90
Performance-Focused
MaxSelectedCameras = 2
MaxActiveScreensPerPlayer = 1
MaxActiveFeedsPerPlayer = 2
CharacterMirrorUpdateRate = 6
UpdateRate = 6
RenderOnlyConfiguredSources = true


