Camera Director, Requests and Volumes
The Camera Director (plCameraDirectorComponent) decides which view a player sees. Put it on the same object as the scene's Main View Camera component. Each frame it picks the highest-priority view request, blends to it from wherever the camera is, runs the modifier stack and writes the result to its object and camera: transform, field of view, near plane and, optionally, focus distance.
Requests and priorities
Views are shown through requests. A request names a view, a priority, an optional duration and an optional blend. The director keeps a list of open requests and shows the one with the highest priority. When two requests have the same priority, the newest one wins.
| Source | Priority | Lasts |
|---|---|---|
| Player view | 10 | Always. It is an implicit request that is never released. |
| Camera Volume | 20 by default (the volume's Priority) | While the player is inside the volume. |
Script (ActivateView) | Chosen by the caller | Until released, or for the given duration. |
Message (plMsgCameraRequestView) | 50 unless set | Until released, or for the given duration. |
A request below 10 never shows, because the player view outranks it. A request at exactly 10 beats the player view, because it is newer. Requests whose view is deleted or deactivated are dropped automatically.
The player view
The player view is found in this order:
- the view set with
SetPlayerViewByName(orSetPlayerViewin C++), - the view on the
DefaultViewobject, - a view on the director's own object,
- a view on one of the director object's direct children.
If none is found and there is no other request, the director does nothing that frame.
Timed requests
A request with a duration above zero ends by itself after that time, as if it had been released. A duration of zero lasts until the request is released by id or by view.
Blending
Whenever the top request changes, the director starts a blend from the camera's current output pose to the new view. Because the blend starts from the current output, a blend that is interrupted by another request continues from wherever the camera is, without a jump. Position and focus distance blend linearly, rotation along the shortest arc, and field of view linearly. The very first view after play starts cuts in.
The blend time is taken from the first of these that is set:
- the blend time passed when the previously shown request was released (for example a volume's
BlendOut), - the request's own blend time (0 or more, where a negative value means "not set"),
- the new view's
BlendTime, if above 0, with the view'sBlendCurve, - the director's
BlendTimeandBlendCurve.
A blend time of 0 or the Cut curve switches instantly.
Sequence cuts
The director steps aside while a sequence shows its own camera. When another camera becomes Main View after play started (a sequencer cut), the director sets its own camera's usage hint to None and writes nothing to its object or camera. When that camera is no longer Main View, the director takes Main View back and blends from the cut's last pose into whichever view is due, using its own BlendTime and BlendCurve. Requests and volumes keep being tracked during the cut. Cameras that were already Main View when play started are treated as part of the scene setup and do not make the director step aside.
Properties
| Property | Default | Description |
|---|---|---|
Player | 0 | Which local player this director serves (0–3). Only matters with several directors. Stats are published per player. |
DefaultView | empty | Object with the player's own view. Empty uses a view on the director's object or its children. |
BlendTime | 0.6 s | Blend used when neither the request nor the view sets one, and when returning from a sequence cut. |
BlendCurve | Ease In Out | Cut, Linear, Ease In, Ease Out or Ease In Out. |
WriteFocus | on | Writes focus distances from views and the Focus modifier to the camera. When a focus distance is written, the camera's focus mode is set to Manual. |
Modifiers | empty | Modifiers applied to every view, after the active view's own modifiers in each stage. |
The director needs a Camera component on its own object to write field of view, near plane and focus. Without one it only moves its object. A view whose FieldOfView is 0 shows the camera's own field of view, read the first time the director updates after play starts.
Script API
These functions are reflected script functions on the Camera Director, so visual scripts and other script languages can call them. Object names are paths or names searched relative to the director's object.
| Function | Description |
|---|---|
ActivateView(ViewObject, Priority, Duration, BlendTime) | Requests the view on ViewObject at Priority. Duration is in seconds, and 0 lasts until released. BlendTime is in seconds: a negative value uses the view's or the director's blend, and 0 cuts. Uses the director's BlendCurve. Returns the request id, or 0 (with a warning in the log) when no view is found. |
ReleaseViewByName(ViewObject, BlendTime) | Releases every request for the view on ViewObject. If one of them was being shown, BlendTime is used for the change that follows, and a negative value uses the normal blend rules. |
ReleaseRequestById(RequestId) | Releases one request, using the normal blend rules for the change that follows. |
SetPlayerViewByName(ViewObject) | Replaces the player's own view (priority 10). |
AddTrauma(Trauma) | Adds trauma (0–1) to every Shake modifier in the active view's and the director's stacks. |
AddRecoil(PitchDegrees, YawDegrees) | Kicks every Recoil modifier. Positive pitch kicks the aim up. |
SetModifierEnabled(Name, Enabled) | Enables or disables the first modifier with that Name, searching the active view's Modifiers list first and then the director's. |
SetModifierWeight(Name, Weight) | Sets the weight (0–1) of the first modifier with that Name, searching the active view's list first and then the director's. |
LookAtObject(Object) | Frames the Camera Point Of Interest on Object through every Look At modifier, without the key press. Logs a warning when the object has no point of interest. |
SetZoomed(Zoomed) | Holds every Zoom modifier zoomed in, or releases them. |
SetLean(Lean) | Leans every Lean modifier: -1 fully left, 1 fully right, 0 upright. |
IsBlending() | Whether the camera is blending between two views right now. |
SetModifierEnabled and SetModifierWeight find the first match in the active view's list, then in the director's. A modifier on a view that is not active is not found. Give each modifier you want to address a unique Name.
C++ code has the same operations plus RequestView, ReleaseRequest, ReleaseView, SetPlayerView, GetActiveView, GetPlayerView, GetOutputPose and GetBestPointOfInterest. plCameraWorldModule finds the director for a player (FindDirector) and sends an impulse to every director (PlayImpulse).
Messages
| Message | Send to | Fields |
|---|---|---|
plMsgCameraRequestView | The director's object | m_hViewObject (object with the view), Priority (50), Duration (0: until released), BlendTime (negative: default), BlendCurve, Source (Script). The director writes the new request id into m_uiRequestId. |
plMsgCameraReleaseView | The director's object | RequestId releases that request when set, otherwise every request for m_hViewObject is released. BlendTime (negative: default). |
plMsgCameraImpulse | The director's object, or every director through plCameraWorldModule::PlayImpulse | Type (Shake, Recoil, Landing), Strength (0.5, which is trauma for Shake and fall speed in m/s for Landing), Position and Radius (Shake falloff, 0 = none), Pitch and Yaw (Recoil). Delivered to the enabled modifiers of the active view and the director. |
plMsgCameraPointOfInterestChanged | Sent by the Look At modifier as an event message to the view's subject (the player) and up its hierarchy | m_hPointOfInterest (invalid when nothing is in range), DisplayName. See Look At. |
Source on a request is one of Player, Volume, Script or Sequence. It only shows in the debug overlay.
Camera Volumes
A Camera Volume (plCameraVolumeComponent) is a box or sphere that shows a view while the player is inside it. Every director tests its player view's subject point against every active volume each frame. Without a player view, it tests the director's own position. Entering requests the volume's view at the volume's priority with BlendIn, and leaving releases it with BlendOut. The shape follows the volume object's position, rotation and scale.
| Property | Default | Description |
|---|---|---|
View | empty | Object with the view to show. |
Shape | Box | Box or Sphere. |
HalfExtents | (2, 2, 2) | Half size of the box, in the object's space. |
Radius | 2 | Radius of the sphere. |
Priority | 20 | Priority of the request made on entering. |
BlendIn | 0.6 s | Blend to the volume's view on entering. |
BlendOut | 0.6 s | Blend away from the volume's view on leaving, if it was being shown. |
BlendCurve | Ease In Out | Curve for the blend in. |
The editor draws the box or sphere in gold and offers manipulators for its size.
Switching to a fixed camera in a courtyard
- Place an object where the courtyard camera should be and add a Fixed View. Set its
Targetto the player, or leave it empty for a fixed angle. - Create an object covering the courtyard and add a Camera Volume. Set
HalfExtentsto the courtyard's size andViewto the Fixed View's object. - Keep
Priorityat 20 so it beats the player view, or raise it if volumes overlap. - Play and walk in. The camera blends to the fixed view over
BlendInand back overBlendOutwhen you leave.
Playing a timed shot from script
- Place a view for the shot, for example a Rail View with a spline along a bridge, and name its object
BridgeShot. - From a script with access to the Camera Director, call
ActivateView("BridgeShot", 100, 5, 1): priority 100, five seconds, one-second blend in. - The request ends by itself after five seconds and the camera blends back to the player view with the normal blend rules. To end it early, call
ReleaseRequestByIdwith the returned id, orReleaseViewByName("BridgeShot", 0.5)for a half-second blend back.
Debugging
Cameras.Debug
| Value | Shows |
|---|---|
0 | Nothing (default). |
1 | A text overlay in the top left of the game view for each director, showing the player index, every request with its view name, source, priority and (for the active one, marked >) the blend progress, every modifier of the active view and the director with its type, owner, whether it is disabled (x) and its current contribution, and the output field of view, yaw, pitch and aspect ratio. |
2 | Everything from 1, plus the active view's rig (arm, sweep, frustums) and the framing guides: the rule-of-thirds grid, the dead and soft zones around the anchor and a cross at the subject. |
Stats
Each director publishes a stats group, where N is its Player index:
| Stat | Value |
|---|---|
Cameras/PlayerN/View | Name of the active view's object. |
Cameras/PlayerN/Blend | Blend progress, 0 to 1. 1 means no blend is running. |
Cameras/PlayerN/FieldOfView | Output field of view in degrees, before the player's offset. |
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Nothing happens after adding a director | No player view was found (see the order above) and no other request is open. Set DefaultView. |
| A view placed in the world moves its own object | The world has no active director, so views run in standalone mode. |
| The camera moves but the field of view and focus never change | The director's object has no Camera component. |
ActivateView returns 0 | The object name did not resolve, or the object has no view. The log shows a warning with the name. |
| A scripted view never shows | Its priority is below 10, or a higher-priority request (for example a volume) is open. Check Cameras.Debug 1. |
| A volume does not trigger | The player view's subject point is not inside it (for a third-person view that is halfway between the target offsets), or View is not set. |
SetModifierWeight has no effect | Its Name does not match, or it is on a view that is not active right now. |
| The camera freezes during a cutscene | A sequence camera is Main View. The director has stepped aside on purpose and takes over again when the cut ends. |
See also: Gameplay Cameras · Camera Views · The Modifier Stack · Framing, Look At and Focus