Customizing the Camera

Roblox offers several built-in options for basic configuration of an experience's camera settings. You can also apply more customized systems by scripting various Camera properties.

Basic Settings

You can configure common camera settings directly within Studio's StarterPlayer object. These settings include zoom distance and various camera, occlusion, and movement modes.

To access the camera properties in StarterPlayer:

  1. In the Explorer window, select the StarterPlayer object.

    Starter Player in Explorer
  2. In the Properties window, scroll down to locate the Camera section. You can configure these properties directly or through a script.

    Camera Properties Window

Zoom Distance

Together, CameraMaxZoomDistance and CameraMinZoomDistance set the span in which users can zoom the camera in respect to their user character. Setting a very high maximum, such as 500, allows users to zoom the camera far out in space. If you want to lock the camera to a specific distance away from the user, you can set both of these properties to the same value.

Camera Range Diagram

Camera Mode

The CameraMode property sets the overall behavior of the camera between two options:

Setting Description
Classic The classic Roblox camera which allows users to zoom in and out (unless zoom is locked) and rotate the camera around the player.
LockFirstPerson Locks the camera to first-person mode. When in this mode, all parts/elements of the user's character are invisible to them, except for equipped Tools.

Occlusion Mode

The DevCameraOcclusionMode property controls camera behavior when the user cannot see their character:

Setting Description
Zoom If the user's character moves behind an object with BasePart.Transparency lower than 0.25, the camera zooms in very close to the character so that it can be seen. Once the character moves back into a viewable position, the camera zooms back out.
Invisicam If the character moves behind an object (opaque or transparent), the camera remains in position but the object becomes semi-transparent so that the character can be seen. Once the character moves back into a viewable position, the object returns to its normal opacity.

Movement Mode

The DevComputerCameraMovementMode (computer) and DevTouchCameraMovementMode (phone/tablet) determine how the user can move the camera around.

Setting Description
Classic The camera remains at its zoom distance between the user's view and their character, tracking the character as it moves around the world. You can also pitch the camera up/down and rotate it in an orbit around the character.
Follow Similar to "Classic" but the camera rotates to face the user's character if it's moving in any direction that isn't parallel to the direction the camera is facing.
Orbital The camera remains at its zoom distance and tracks the character as it moves around the world. You can rotate it in an orbit around the character, but you can't pitched it up/down.
UserChoice Allows users to choose their desired camera movement mode from the in-experience Settings menu. Note that Orbital is not an option through the user menu.

Mouse Lock

When StarterPlayer.EnableMouseLockOption is enabled, Roblox users can enable the Shift Lock Switch in their settings. When Shift Lock Switch is enabled, the user can press Shift to toggle between the following mouse camera behaviors:

  • The user can freely look around by only moving the mouse.
  • The user must hold down the right mouse button while moving the mouse to look around.

When StarterPlayer.EnableMouseLockOption is disabled in an experience, users cannot set their Shift Lock Switch client setting.

Camera Scripting Properties

Beyond basic camera customization, you can manipulate the camera to create specific user/character view systems, lock the camera to a world position, create unique camera effects, and more.

The following are some of the primary properties that that you can modify in a script to control the Roblox Camera:

Property Description
Camera.CFrame The CFrame of the camera. This property is frequently used to position and move the camera in game.
Camera.Focus The point in 3D space where the camera is looking. When pointing the camera in a specific direction, you should update this property because certain visuals are more detailed depending on how close they are to the focus point.
Camera.FieldOfView The extent of the observable 3D space that can be seen on screen, measured between 1120 degrees in the vertical direction (default is 70).

Camera Scripting Examples

You can access the camera's properties to create unique camera behavior, such as an over-the-shoulder view, a scoping effect, or an orbiting view.

Because each user's camera is local to their device, custom camera code should exist in a LocalScript within StarterPlayerScripts or StarterPack. Placing any of the following scripts elsewhere doesn't allow the code to properly take control of the user's camera.

Over-the-Shoulder

The following example is a basic over-the-shoulder camera commonly found in third-person shooter games. This camera stays locked behind the character's back and users use the mouse to turn (not directional input). Use the following script example to implement this camera setting:


1local Players = game:GetService("Players")
2local ContextActionService = game:GetService("ContextActionService")
3local UserInputService = game:GetService("UserInputService")
4local RunService = game:GetService("RunService")
5
6local camera = workspace.CurrentCamera
7local cameraOffset = Vector3.new(2, 2, 8)
8local player = Players.LocalPlayer
9
10player.CharacterAdded:Connect(function(character)
11
12 local humanoid = character:WaitForChild("Humanoid")
13 local rootPart = character:WaitForChild("HumanoidRootPart")
14 humanoid.AutoRotate = false
15
16 local cameraAngleX = 0
17 local cameraAngleY = 0
18
19 local function playerInput(actionName, inputState, inputObject)
20 -- Calculate camera/player rotation on input change
21 if inputState == Enum.UserInputState.Change then
22 cameraAngleX = cameraAngleX - inputObject.Delta.X
23 -- Reduce vertical mouse/touch sensitivity and clamp vertical axis
24 cameraAngleY = math.clamp(cameraAngleY-inputObject.Delta.Y*0.4, -75, 75)
25 -- Rotate root part CFrame by X delta
26 rootPart.CFrame = rootPart.CFrame * CFrame.Angles(0, math.rad(-inputObject.Delta.X), 0)
27 end
28 end
29 ContextActionService:BindAction("PlayerInput", playerInput, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.Touch)
30
31 RunService.RenderStepped:Connect(function()
32 if camera.CameraType ~= Enum.CameraType.Scriptable then
33 camera.CameraType = Enum.CameraType.Scriptable
34 end
35 local startCFrame = CFrame.new((rootPart.CFrame.Position)) * CFrame.Angles(0, math.rad(cameraAngleX), 0) * CFrame.Angles(math.rad(cameraAngleY), 0, 0)
36 local cameraCFrame = startCFrame:ToWorldSpace(CFrame.new(cameraOffset.X, cameraOffset.Y, cameraOffset.Z))
37 local cameraFocus = startCFrame:ToWorldSpace(CFrame.new(cameraOffset.X, cameraOffset.Y, -10000))
38 camera.CFrame = CFrame.new(cameraCFrame.Position, cameraFocus.Position)
39 end)
40end)
41
42local function focusControl(actionName, inputState, inputObject)
43 -- Lock and hide mouse icon on input began
44 if inputState == Enum.UserInputState.Begin then
45 UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
46 UserInputService.MouseIconEnabled = false
47 ContextActionService:UnbindAction("FocusControl", focusControl, false, Enum.UserInputType.MouseButton1, Enum.UserInputType.Touch, Enum.UserInputType.Focus)
48 end
49end
50ContextActionService:BindAction("FocusControl", focusControl, false, Enum.UserInputType.MouseButton1, Enum.UserInputType.Touch, Enum.UserInputType.Focus)
51

Scope In/Out

A simple scope in/out camera system can be implemented using the following script. This example uses the middle mouse button to zoom in and out, and the ability of ContextActionService to create a virtual zoom button on mobile devices.

Use the following example script to implement a scoping effecting when the user presses their middle mouse button:


1local Players = game:GetService("Players")
2local ContextActionService = game:GetService("ContextActionService")
3local UserInputService = game:GetService("UserInputService")
4local TweenService = game:GetService("TweenService")
5
6local camera = workspace.CurrentCamera
7local player = Players.LocalPlayer
8
9local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
10local initialFieldOfView = camera.FieldOfView
11local initialCameraPosition = camera.CFrame
12local isZoomed = false
13local inTween = false
14local target
15
16player.CharacterAdded:Connect(function(character)
17
18 local humanoid = character:WaitForChild("Humanoid")
19 local rootPart = character:WaitForChild("HumanoidRootPart")
20 local initialWalkSpeed = humanoid.WalkSpeed
21 local initialJumpPower = humanoid.JumpPower
22
23 local cameraAngleX = 0
24 local cameraAngleY = 0
25
26 local function moveInput(actionName, inputState, inputObject)
27 if not isZoomed then return end
28 if inputState == Enum.UserInputState.Change then
29 cameraAngleX = math.clamp(cameraAngleX-inputObject.Delta.X*0.4, -90, 90)
30 cameraAngleY = math.clamp(cameraAngleY-inputObject.Delta.Y*0.4, -75, 75)
31 local camPosition = rootPart.CFrame:ToWorldSpace(CFrame.new(0, 2, -2))
32 local camRotation = camPosition * CFrame.Angles(0, math.rad(cameraAngleX), 0) * CFrame.Angles(math.rad(cameraAngleY), 0, 0)
33 target = camRotation:ToWorldSpace(CFrame.new(0, 0, -20))
34 camera.CFrame = CFrame.new(camRotation.Position, target.Position)
35 camera.Focus = CFrame.new(target.Position)
36 end
37 end
38
39 local function scopeInOut(actionName, inputState, inputObject)
40 if inTween == true then return end
41 if (inputObject.UserInputType == Enum.UserInputType.MouseButton3 and (inputState == Enum.UserInputState.Begin or inputState == Enum.UserInputState.End))
42 or (inputObject.UserInputType == Enum.UserInputType.Touch and inputState == Enum.UserInputState.End) then
43 inTween = true
44 -- Zoom in
45 if isZoomed == false then
46 initialCameraPosition = camera.CFrame
47 camera.CameraType = Enum.CameraType.Scriptable
48 UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
49 UserInputService.MouseIconEnabled = false
50 -- Rotate root part CFrame according to camera direction
51 local faceToward = camera.CFrame:Lerp(rootPart.CFrame, 1.1)
52 rootPart.CFrame = CFrame.new(rootPart.CFrame.Position, Vector3.new(faceToward.Position.X, rootPart.Position.Y, faceToward.Position.Z))
53 target = rootPart.CFrame:ToWorldSpace(CFrame.new(0, 2, -20))
54 cameraAngleX, cameraAngleY = 0, 0
55 humanoid.WalkSpeed = 0
56 humanoid.JumpPower = 0
57 wait(0.05)
58 local camPosition = rootPart.CFrame:ToWorldSpace(CFrame.new(0, 2, -2))
59 camera.CFrame = CFrame.new(camera.CFrame.Position, target.Position)
60 local tween = TweenService:Create(camera, tweenInfo, {CFrame=camPosition, FieldOfView=12})
61 tween.Completed:Connect(function()
62 ContextActionService:BindAction("MoveInput", moveInput, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.Touch)
63 ContextActionService:SetTitle("ScopeInOut", "–")
64 camera.Focus = CFrame.new(target.Position)
65 isZoomed = true
66 inTween = false
67 end)
68 tween:Play()
69 -- Zoom out
70 elseif isZoomed == true then
71 ContextActionService:UnbindAction("MoveInput", moveInput, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.Touch)
72 UserInputService.MouseBehavior = Enum.MouseBehavior.Default
73 UserInputService.MouseIconEnabled = true
74 local tween = TweenService:Create(camera, tweenInfo, {CFrame=initialCameraPosition, FieldOfView=initialFieldOfView})
75 tween.Completed:Connect(function()
76 ContextActionService:SetTitle("ScopeInOut", "+")
77 camera.CameraType = Enum.CameraType.Custom
78 humanoid.WalkSpeed = initialWalkSpeed
79 humanoid.JumpPower = initialJumpPower
80 isZoomed = false
81 inTween = false
82 end)
83 tween:Play()
84 end
85 end
86 end
87 ContextActionService:BindAction("ScopeInOut", scopeInOut, true, Enum.UserInputType.MouseButton3)
88 ContextActionService:SetPosition("ScopeInOut", UDim2.new(0.65, 0, 0.1, 0))
89 ContextActionService:SetTitle("ScopeInOut", "+")
90end)
91

Rotate Around Object

To rotate the camera fully or partially around a part, experiment with the following script which features adjustable camera offset, rotation time, repetition count, easing styles, and more.

Use the following example script to set up a camera rotation:


1local TweenService = game:GetService("TweenService")
2local RunService = game:GetService("RunService")
3
4local target = workspace:FindFirstChild("Part") -- The object to rotate around
5local camera = workspace.CurrentCamera
6camera.CameraType = Enum.CameraType.Scriptable
7local rotationAngle = Instance.new("NumberValue")
8local tweenComplete = false
9
10local cameraOffset = Vector3.new(0, 10, 12)
11local rotationTime = 15 -- Time in seconds
12local rotationDegrees = 360
13local rotationRepeatCount = -1 -- Use -1 for infinite repeats
14local lookAtTarget = true -- Whether the camera tilts to point directly at the target
15
16local function updateCamera()
17 if not target then return end
18 camera.Focus = target.CFrame
19 local rotatedCFrame = CFrame.Angles(0, math.rad(rotationAngle.Value), 0)
20 rotatedCFrame = CFrame.new(target.Position) * rotatedCFrame
21 camera.CFrame = rotatedCFrame:ToWorldSpace(CFrame.new(cameraOffset))
22 if lookAtTarget == true then
23 camera.CFrame = CFrame.new(camera.CFrame.Position, target.Position)
24 end
25end
26
27-- Set up and start rotation tween
28local tweenInfo = TweenInfo.new(rotationTime, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, rotationRepeatCount)
29local tween = TweenService:Create(rotationAngle, tweenInfo, {Value=rotationDegrees})
30tween.Completed:Connect(function()
31 tweenComplete = true
32end)
33tween:Play()
34
35-- Update camera position while tween runs
36RunService.RenderStepped:Connect(function()
37 if tweenComplete == false then
38 updateCamera()
39 end
40end)
41