Skip to content

Game.Debug.CameraDebugUI

Assembly: Assembly-CSharp (game code assembly)
Namespace: Game.Debug

Type: public static class

Base: System.Object (static utility class)

Summary:
CameraDebugUI builds the in-game debug UI for camera-related systems. It exposes a "Camera" debug tab (via the [DebugTab] attribute) that enumerates all Unity game cameras, presents per-camera information, and exposes a set of controls and readouts for the active viewer (from CameraUpdateSystem), Cinemachine virtual cameras, and some CameraController settings (edge-scrolling and clip distance). The class is a static provider — the debug framework calls its BuildCameraDebugUI method and displays the returned DebugUI widgets.


Fields

  • None
    {{ This class does not declare any instance or static fields. All state is queried from game systems (Camera, CameraUpdateSystem, CinemachineCore, CameraController) at runtime and returned as DebugUI widgets. }}

Properties

  • None
    {{ No properties are defined; the class only exposes a single static method that the debug system uses to construct the debug UI. }}

Constructors

  • None (static class)
    {{ Being a static class, CameraDebugUI has no constructors or static initializer in the source. Its functionality is provided via a decorated static method that the debug framework discovers and invokes. }}

Methods

  • private static List<DebugUI.Widget> BuildCameraDebugUI(World world)
    {{ Purpose:
  • This is the primary method used by the debug framework to generate the "Camera" tab UI. It is decorated with [DebugTab("Camera", 0)] so the debug system will call it and display the returned widgets.

Behavior / What it builds: - Retrieves the CameraUpdateSystem from the provided ECS World: world.GetExistingSystemManaged(). - Creates a top-level DebugUI.Container titled "Game Cameras". - Iterates over Camera.allCameras and, for each camera with cameraType == CameraType.Game, adds a Foldout showing: - Whether it is Camera.main (Is Main?) - Whether it is the active viewer's camera (Is ActiveViewer?) - World Position (camera.transform.position) - Focus distance (note: current code returns transform.position for "Focus distance" as well — likely a copy/paste mistake in original source) - Adds an "Active Viewer" Foldout that reads many runtime properties from cameraUpdateSystem.activeViewer, including: - World position (formatted to two decimals) - Visibility distance - Focus distance - Booleans for shadowsAdjustStartDistance and shadowsAdjustFarDistance exposed as BoolField widgets (with setters that write back to activeViewer) - Push culling near plane multiplier/value exposed as FloatField widgets with min/max/incStep and setters - Viewer distance readouts (closest/farthest/average/ground/sea level) - Adds a "Cinemachine" Foldout that: - Iterates CinemachineCore.Instance.BrainCount and VirtualCameraCount and lists virtual cameras - Marks each virtual camera as "Active" if any Brain has that vcam as ActiveVirtualCamera; otherwise "Inactive" - Finally, returns a list of widgets including: - The "Game Cameras" container - A BoolField for "Edge-scrolling" that reads/writes CameraController.edgeScrolling via CameraController.TryGet - A FloatField for "Clip offset" that maps to CameraController.clipDistance. The UI clamps/max-maps values so a displayed max value implies float.MaxValue internally.

Notes and caveats: - The method uses many null-conditional operators (?.) and TryGet patterns to avoid exceptions if systems or singletons are not present. - The "Focus distance" value for each Camera currently returns transform.position.ToString(), which appears incorrect; it should likely read a distance or focus property. - Some widgets include setters that directly mutate runtime systems (activeViewer fields, CameraController.clipDistance), so use with care. - The method is private and intended for the debug system to discover via the DebugTab attribute. }}

Usage Example

// The BuildCameraDebugUI method is discovered via the [DebugTab("Camera", 0)] attribute.
// You normally don't call it directly; the debug framework will call it and render the widgets.

// Example: programmatically toggling edge-scrolling (same field the debug UI exposes)
if (CameraController.TryGet(out CameraController cameraController))
{
    // Toggle edge-scrolling off
    cameraController.edgeScrolling = false;

    // Set clip distance to 500 units
    cameraController.clipDistance = 500f;
}

// Example: change an active viewer boolean (mirrors the BoolField setter in the debug UI)
var world = World.DefaultGameObjectInjectionWorld;
var cameraUpdateSystem = world.GetExistingSystemManaged<CameraUpdateSystem>();
if (cameraUpdateSystem?.activeViewer != null)
{
    cameraUpdateSystem.activeViewer.shadowsAdjustStartDistance = true;
}

{{ Additional tips: - If you want to extend the camera debug tab, add another static method decorated with [DebugTab(...)] or modify this method to include extra DebugUI widgets (DebugUI.Value, DebugUI.BoolField, DebugUI.FloatField, DebugUI.Foldout, etc.). - Be careful when exposing setters in debug UI — they mutate live game systems. - For investigating Cinemachine cameras, use CinemachineCore.Instance APIs as shown here. }}