Skip to main content

CameraOwnership

The camera handoff contract, reached through Flow.Camera.

A Camera track requests control of workspace.CurrentCamera when its first section enters and yields it when its last section exits, including when the playback is stopped early or errors. While Flow holds control the camera is Scriptable; the previous CameraType comes back when it lets go.

A game with its own camera system defers to Flow while it holds the camera and resumes afterwards:

local Flow = require(ReplicatedStorage.Flow)

Flow.Camera.OwnerChanged:Connect(function(newOwner)
	MyCameraSystem:SetEnabled(newOwner == nil)
end)
MyCameraSystem:SetEnabled(not Flow.Camera.IsOwnedByFlow())

Owners stack. When two sequences hold the camera, the most recent one controls it, and control returns to the earlier one when it releases.

Properties​

OwnerChanged​

CameraOwnership.OwnerChanged: Signal<(
newOwner: any?,
newLabel: string?,
previousOwner: any?
)>

Fires whenever the controlling owner changes. newOwner is nil when Flow has let go of the camera. Owners are opaque; the label is the playing sequence's name.

Functions​

RequestControl​

CameraOwnership.RequestControl(
owner: any,
label: string?
) → boolean

Requests camera control for owner. The most recent requester controls the camera, and control returns to the previous requester when it releases. Requesting again while already an owner does nothing.

ReleaseControl​

CameraOwnership.ReleaseControl(owner: any) → ()

Gives up owner's claim on the camera. Does nothing if it holds none.

SetSuspended​

CameraOwnership.SetSuspended(suspended: boolean) → ()

Hands the camera back to whatever normally drives it without releasing ownership. A paused editor preview suspends control so the camera can be posed for the next keyframe. Sequence writes still apply while suspended; they just no longer lock out other controllers.

IsSuspended​

CameraOwnership.IsSuspended() → boolean

GetOwner​

CameraOwnership.GetOwner() → (
any?,--

The controlling owner, or nil when Flow does not hold the camera

string?--

The owner's label

)

IsOwnedByFlow​

CameraOwnership.IsOwnedByFlow() → boolean

Returns true while any sequence holds the camera, suspended or not.

Show raw api
{
    "functions": [
        {
            "name": "RequestControl",
            "desc": "Requests camera control for `owner`. The most recent requester controls the camera, and control returns to\nthe previous requester when it releases. Requesting again while already an owner does nothing.",
            "params": [
                {
                    "name": "owner",
                    "desc": "",
                    "lua_type": "any"
                },
                {
                    "name": "label",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 100,
                "path": "runtime/CameraOwnership.luau"
            }
        },
        {
            "name": "ReleaseControl",
            "desc": "Gives up `owner`'s claim on the camera. Does nothing if it holds none.",
            "params": [
                {
                    "name": "owner",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 119,
                "path": "runtime/CameraOwnership.luau"
            }
        },
        {
            "name": "SetSuspended",
            "desc": "Hands the camera back to whatever normally drives it without releasing ownership. A paused editor preview\nsuspends control so the camera can be posed for the next keyframe. Sequence writes still apply while\nsuspended; they just no longer lock out other controllers.",
            "params": [
                {
                    "name": "suspended",
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 147,
                "path": "runtime/CameraOwnership.luau"
            }
        },
        {
            "name": "IsSuspended",
            "desc": "",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 158,
                "path": "runtime/CameraOwnership.luau"
            }
        },
        {
            "name": "GetOwner",
            "desc": "",
            "params": [],
            "returns": [
                {
                    "desc": "The controlling owner, or nil when Flow does not hold the camera",
                    "lua_type": "any?"
                },
                {
                    "desc": "The owner's label",
                    "lua_type": "string?"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 167,
                "path": "runtime/CameraOwnership.luau"
            }
        },
        {
            "name": "IsOwnedByFlow",
            "desc": "Returns true while any sequence holds the camera, suspended or not.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean\n"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 179,
                "path": "runtime/CameraOwnership.luau"
            }
        }
    ],
    "properties": [
        {
            "name": "OwnerChanged",
            "desc": "Fires whenever the controlling owner changes. `newOwner` is nil when Flow has let go of the camera. Owners\nare opaque; the label is the playing sequence's name.",
            "lua_type": "Signal<(newOwner: any?, newLabel: string?, previousOwner: any?)>",
            "source": {
                "line": 58,
                "path": "runtime/CameraOwnership.luau"
            }
        }
    ],
    "types": [],
    "name": "CameraOwnership",
    "desc": "The camera handoff contract, reached through [Flow.Camera].\n\nA Camera track requests control of `workspace.CurrentCamera` when its first section enters and yields it\nwhen its last section exits, including when the playback is stopped early or errors. While Flow holds\ncontrol the camera is `Scriptable`; the previous `CameraType` comes back when it lets go.\n\nA game with its own camera system defers to Flow while it holds the camera and resumes afterwards:\n\n```lua\nlocal Flow = require(ReplicatedStorage.Flow)\n\nFlow.Camera.OwnerChanged:Connect(function(newOwner)\n\tMyCameraSystem:SetEnabled(newOwner == nil)\nend)\nMyCameraSystem:SetEnabled(not Flow.Camera.IsOwnedByFlow())\n```\n\nOwners stack. When two sequences hold the camera, the most recent one controls it, and control returns to\nthe earlier one when it releases.",
    "source": {
        "line": 42,
        "path": "runtime/CameraOwnership.luau"
    }
}