Shared and Split Screen Cameras¶
Quick Start covers setup; Player scope explains capacity. This guide describes optional camera integration.
1. Overview¶
GameplayCameraManager is an optional, scene-local module for shared and individual player cameras, with built-in Split Screen layouts for 1-8 local players. It manages camera assignment, rendering state and Camera.rect.
You own camera behavior. The framework does not prescribe follow, orbit, aim, chase, zoom, collision or multiple-target framing. Your camera prefab or provider can contain your own behavior. The Playground and Rocket Rumble cameras are sample implementations, not universal camera controllers.
Configure gameplay players normally first; see Chapter 7 — Gameplay Representation and Spawning. The manager requires a GameplayPlayerSetup that resolves representations. If your game creates its own objects, use that setup's existing Custom Provider mode with an IGameplayPlayerProvider returning those objects. HandleItMyself does not resolve representations for camera management.
No camera module is required for input, sessions, selection or gameplay integration. Cinemachine is not required.
2. Shared vs Split Screen¶
- Split Screen OFF: your Shared Camera renders the full screen; assigned individual cameras stop rendering.
- Split Screen ON: individual cameras render for active resolved participants; the Shared Camera stops rendering. If no individual camera can be resolved, Shared remains a fallback when available.
Changing mode preserves PlayerSession identity, PlayerIndex, InputUser, selected character and gameplay representation. It does not reload scenes or recreate gameplay players. Switching back to Shared requires a Shared Camera reference.
3. Setup Wizard quick start¶
- Configure your gameplay scene's
GameplayPlayerSetupand representation source, then save the scene. - Open Tools > LevelArgento > Couch Co-op Builder > Setup Wizard. Choose the lobby workflow, catalog, capacity and gameplay scene normally.
- On the Cameras step, check Enable Shared / Split Screen Camera Management. It is unchecked by default. Unchecked means no manager is added, no camera fields are required, and existing camera setup is left untouched.
- Use Open Gameplay Scene Additively to load the chosen gameplay scene alongside the lobby. Assign its Gameplay Player Setup; the Wizard suggests it only when exactly one candidate exists. Assign your existing Shared Camera from that scene.
- Choose Camera Prefab, Camera On Gameplay Representation, or Custom Provider, with the source described below. Prefab/provider configuration is required even when the initial mode is Shared, so runtime Split switching has a usable source.
- Choose Default Camera Mode: Shared / Split, the two-player layout and the three-player layout. Four through eight use automatic built-in layouts. Advanced options allow an existing custom layout provider and an AudioListener policy.
- Complete the authored lobby/Canvas bindings. On Review, inspect validation and the plan, then Apply Setup. The Wizard adds one
GameplayCameraManageron the assigned setup object if none exists, or reuses the single existing manager in the gameplay scene. It assigns references and defaults, without creating camera objects or providers. - Save the gameplay scene after Apply, and save the lobby for Existing Canvas. The gameplay scene is marked dirty, not automatically saved. Enter Play Mode, join players and call
SetSplitScreenEnabled(true)from your Settings UI.
Existing Canvas lobby and camera edits form one scene Undo operation. New Lobby output assets cannot be deleted by scene Undo; camera wiring still supports Undo. Project scene-list additions are a separate project-configuration effect. New Lobby refuses to overwrite existing output assets and removes partial outputs if creation fails.
Rerunning reads the single existing manager's configuration when you assign the setup object or open its scene through the Wizard. Review those suggested references before Apply. Reapplying reconciles one manager, without duplicate cameras or providers. Multiple managers produce an actionable validation error rather than a guess about which one to replace. Turning the checkbox off leaves any previously configured manager intact.
4. Manual setup¶
- Add
GameplayCameraManagerto the gameplay scene, normally on theGameplayPlayerSetupobject. - Assign Player Setup, your Shared Camera, and Player Camera Source with its prefab/provider where applicable.
- Set Split Screen Enabled, Two Player Layout, Three Player Layout, and optionally the layout provider/audio policy in the Inspector.
- Author camera behavior and test both modes with real joined gameplay participants.
For code-driven setup, use Configure(GameplayPlayerSetup setup, Camera shared, GameplayCameraSource source, GameObject prefab = null, IGameplayCameraProvider provider = null). It releases the previous camera assignment cycle. Settings toggles should use SetSplitScreenEnabled instead of repeatedly calling Configure.
5. Runtime toggle and layouts¶
These are independent Settings actions; cameraManager is your assigned GameplayCameraManager reference. Include using LevelArgento.CouchCoopBuilder; in scripts using these types:
cameraManager.SetSplitScreenEnabled(true); // Split
cameraManager.SetSplitScreenEnabled(false); // Shared
cameraManager.SetTwoPlayerLayout(TwoPlayerViewportLayout.Vertical);
cameraManager.SetThreePlayerLayout(ThreePlayerViewportLayout.TopTwoBottomOne);
Read state through SplitScreenEnabled, TwoPlayerLayout and ThreePlayerLayout. The Wizard default is serialized scene configuration; your Settings UI can change it at runtime. The module does not persist preferences or generate a mandatory Settings screen.
| Public event | Use |
|---|---|
SplitScreenModeChanged (Action<bool>) |
Reflect Shared/Split changes in your Settings UI. |
ViewportLayoutChanged (Action) |
React after rect/rendering-state changes, including layout and participant updates. |
PlayerCameraAssigned (Action<GameplayPlayerContext, Camera, GameObject>) |
Connect camera behavior or HUD to its current context and representation. |
Subscribe/unsubscribe with your component's normal lifecycle. TryGetPlayerCamera(int playerIndex, out Camera camera) finds an assigned active camera. Call Refresh() after an unavailable custom camera becomes ready to retry assignment.
6. Built-in layouts 1-8¶
Active views pack in ascending existing PlayerIndex order. Packing never renumbers sessions: P1 / P4 / P7 remain P1 / P4 / P7, occupying three visual slots. Unity rect coordinates start at the bottom-left; row names below describe the visual top row first.
| Players | Layout |
|---|---|
| 1 | Full screen |
| 2 | Horizontal (top/bottom) or Vertical (left/right) |
| 3 | Top 2 / Bottom 1; Bottom 2 / Top 1; Left 1 / Right 2; Right 1 / Left 2 |
| 4 | 2 + 2 |
| 5 | 3 + 2 |
| 6 | 3 + 3 |
| 7 | 4 + 3 |
| 8 | 4 + 4 |
Two- and three-player layouts are selectable; four through eight use automatic arrangements. In the automatic 4–8 arrangements, rows share screen height equally and columns fill each row. Rects cover the full screen without decorative gaps. Three-player enum values are TopTwoBottomOne, BottomTwoTopOne, LeftOneRightStack, and RightOneLeftStack. Two-player values are Horizontal and Vertical.
7. Player camera sources¶
Camera Prefab¶
Assign a prefab containing exactly one Camera, on the root or a child. The manager clones the full prefab once per resolved session when Split first needs it. Follow/zoom scripts on the rig are retained. No particular genre, follow script or Cinemachine package is required.
GameplayCameraAssignment is added to the clone root. Its Context and Representation identify the player and target; AssignmentChanged fires when bindings change, including rejoin. Author prefab AudioListeners disabled under the default framework policy to avoid transient duplicate listeners during cloning.
Camera On Gameplay Representation¶
Each resolved representation provides a Camera in its hierarchy. Ownership stays with its owner. The Wizard checks known authored existing objects and selected-character gameplay prefabs for missing Cameras. Dynamic/custom providers are not rejected merely because future cameras cannot be inspected: verify their resolved representations in Play Mode. A representation Camera cannot also be the Shared Camera.
Custom Provider¶
Assign your gameplay-scene MonoBehaviour implementing IGameplayCameraProvider. Its existing method is:
bool TryResolveCamera(GameplayPlayerContext context, GameObject representation,
out Camera camera, out string failureMessage);
Return a live scene Camera for that participant, not a prefab asset or a Camera assigned to another participant. The provider owns camera lifetime, behavior and pooling. The Wizard assigns your component; it does not invent an implementation. Multi-camera rigs/advanced stacks need your own setup through this source.
8. Camera ownership¶
The manager never deletes or reparents your Shared Camera, replaces follow scripts, or edits camera FOV, projection, clipping planes, renderer settings or behavior. At runtime it controls assigned cameras' enabled state and rects; the default audio policy also manages assigned-hierarchy listeners. Prior customer enabled/rect/listener states are restored on release.
Framework-created prefab clones belong to the manager. Customer representation/provider cameras stay customer-owned and are never destroyed by the manager. Disabling/destroying the manager releases its clones and restores customer state. A pooled provider should recycle cameras through its own representation lifecycle; the manager does not own that pool.
9. Drop Out / Rejoin and permanent Leave¶
Intentional gameplay Drop Out releases that participant's representation and removes its active viewport; remaining views repack without renumbering PlayerIndex. Rejoin restores the participant. Framework-owned camera clones remain disabled/reserved for the session and are reused with the new representation binding.
Representation cameras follow their representation's lifetime. Custom providers manage their returned cameras. Permanent Leave performs normal session cleanup and destroys framework-owned clones for that session; it is distinct from reversible Drop Out.
10. DeviceLost¶
Temporary device loss leaves the participant represented and its camera normally assigned. The manager follows representation lifecycle, not raw device events or inactivity. Your game may pause or show reconnection UI according to its existing session policy. DeviceLost does not silently become Leave or Drop Out.
11. AudioListener¶
Default ManageAssignedCameraListeners enables one listener among assigned player rigs: the first active rig with a listener, or Shared as fallback. Shared mode uses the shared listener. Prior listener states are restored on release.
Only listeners in assigned player rigs/representation hierarchies and the shared-camera hierarchy are managed. Other scene listeners remain yours. The Wizard creates no extra listeners and changes no prefab assets. Select Developer Managed (DeveloperManaged) if your game owns listener switching; SetAudioPolicy(GameplayCameraAudioPolicy policy) also changes policy at runtime. Neither policy prevents duplicate listeners you independently enable elsewhere.
12. UI / HUD¶
- Screen Space Overlay: global full-screen UI, appropriate for Pause, Settings and Winner. It is not cropped into player viewports.
- Screen Space Camera: an individual HUD can target its assigned Camera through
Canvas.worldCamera. - World Space: normal Unity behavior through relevant cameras.
Subscribe to PlayerCameraAssigned to connect your authored HUD to the camera using the provided context and representation. Rebind when assignments change. The manager does not automatically clone customer HUDs. Packed visual positions are not new player identities.
13. URP and Cinemachine¶
Normal URP Base Cameras support Camera.rect. Overlay stacks, renderers, post-processing and renderer features remain customer-controlled. Prefab source expects exactly one Camera; use a custom provider for multi-camera stacks and verify them on your target Unity/URP version.
Cinemachine is not required. There is no Cinemachine package dependency or built-in integration package. Developers may use Cinemachine in their own prefabs/providers; its target binding and advanced URP/stack configuration remain theirs.
14. Custom layout provider¶
In Advanced Camera Options or the Inspector, assign an existing scene component implementing ICameraViewportLayoutProvider. Empty uses built-in layouts. At runtime use SetViewportLayoutProvider(ICameraViewportLayoutProvider provider); null returns to the built-in provider.
The interface fills normalized rects in ascending active PlayerIndex order:
bool TryGetViewports(int viewCount, TwoPlayerViewportLayout twoPlayer,
ThreePlayerViewportLayout threePlayer, Rect[] viewports);
The manager validates finite, positive, in-bounds, non-overlapping full-screen tiling and falls back to built-in layouts if custom output is invalid. The supported range is 1-8. The Wizard checks the component/interface reference; it does not execute customer layout code during setup.
15. Performance¶
One through eight layouts are supported. More cameras increase rendering cost; performance depends on resolution, scene complexity, shadows, post-processing, renderer features and hardware. Eight cameras do not guarantee high-setting performance on every device. Profile your own content/build and tune effects and resolution. No universal game performance is promised.
16. Samples¶
See the Samples index for entry points.
| Demonstration | Purpose |
|---|---|
| Rocket Rumble 3D | Real game integration, fixed Shared Camera, individual 3D follow cameras, runtime Camera Settings and Drop Out/Rejoin; up to four players. |
| Split Screen Playground 3D | Independent 1-8 join/entry flow, perspective follow cameras and 5/6/7/8 layouts. |
| Split Screen Playground 2D | Independent 1-8 join/entry flow, orthographic cameras, simple platformer movement and Shared/Split switching. |
The Playground guide links both entry scenes and explains the independent 1–8-player join flow. Sample follow/framing belongs to the game; the core has no dependency on those scripts.
17. Troubleshooting¶
| Problem | Check |
|---|---|
| Camera fields missing in Wizard | Enable Shared / Split Screen Camera Management on the Cameras step. |
| Cannot assign gameplay references | Open the selected saved gameplay scene additively and assign its Gameplay Player Setup. Lobby objects and prefab assets are not gameplay-scene references. |
| Shared mode has no view | Assign Shared Camera; switching to Shared needs it even if initial mode was Split. |
| Split has no individual cameras | Resolve representations first and configure a camera source. HandleItMyself does not resolve objects. |
| Camera Prefab rejected | Assign an asset with exactly one Camera, including inactive children. Missing/multiple Cameras or scene objects are unusable for this source. |
| Representation lacks a Camera | Add it, choose prefab source, or use a custom provider. Test dynamically created representations after resolution. |
| Custom provider missing/invalid | Assign a live gameplay-scene component implementing IGameplayCameraProvider or ICameraViewportLayoutProvider, as applicable. |
| Multiple managers on rerun | Reconcile them explicitly; the Wizard does not delete one or guess which to configure. |
| Duplicate AudioListener warning | Disable unrelated scene listeners, author prefab listeners disabled, and verify the selected policy. |
| HUD fills screen | Overlay is global; bind an individual Screen Space Camera Canvas to its assigned camera. |
| P numbers seem out of order after Drop Out | Views repack; PlayerIndex stays stable. P1/P4/P7 still identify those sessions. |
| Camera does not follow | Supply your behavior and bind targets through GameplayCameraAssignment or PlayerCameraAssigned. |
ValidateConfiguration(out string failure) reports the first basic runtime configuration problem. Detailed resolution diagnostics are reported once per problem; Refresh() can retry a provider after its camera becomes available. Fix legitimate diagnostics rather than repeatedly clearing them. No proximity split/merge, animated/diagonal splits, HUD cloning, minimap or spectator system is provided.