Skip to content

Game.CinematicCameraController

Assembly:
Game (inferred)
Namespace: Game

Type: class

Base: MonoBehaviour, IGameCameraController

Summary: CinematicCameraController is a free/cinematic camera controller used in Cities: Skylines 2. It drives a CinemachineVirtualCamera by moving a hidden anchor Transform that the vCam follows. The controller reads input from a CameraInput component, enforces terrain constraints via CinemachineRestrictToTerrain, supports movement/zoom/rotation speeds that scale with camera height, updates the game's AudioManager listener, and registers itself with the CameraUpdateSystem. The controller creates an anchor GameObject at Awake and starts disabled by default after initialization.


Fields

  • private float m_MinMoveSpeed Description: Minimum planar movement speed (units/sec) used when camera is near the terrain.

  • private float m_MaxMoveSpeed Description: Maximum planar movement speed used when camera is high above the terrain.

  • private float m_MinZoomSpeed Description: Minimum zoom (vertical) speed applied when camera is near the terrain.

  • private float m_MaxZoomSpeed Description: Maximum zoom speed applied at higher altitudes.

  • private float m_RotateSpeed Description: Sensitivity multiplier for camera rotation input.

  • private float m_MaxHeight Description: Maximum height above terrain the camera is allowed to reach.

  • private float m_MaxMovementSpeedHeight Description: Height threshold at which movement/zoom speeds reach their maximum values.

  • private Transform m_Anchor Description: Hidden GameObject Transform that the Cinemachine virtual camera follows. All motion/rotation is applied to this anchor.

  • private CinemachineVirtualCamera m_VCam Description: Reference to the Cinemachine virtual camera component on the same GameObject. Its Follow target is set to m_Anchor.

  • private CinemachineRestrictToTerrain m_RestrictToTerrain Description: Component used to clamp camera position to map/terrain bounds and to perform collision checks with scene objects.

  • private CameraInput m_CameraInput Description: Component that provides aggregated camera input (move/rotate/zoom). Initialized in Awake if present.

  • private CameraUpdateSystem m_CameraUpdateSystem Description: ECS-managed system (CameraUpdateSystem) this controller registers with so UpdateCamera gets called from the appropriate update loop.

Properties

  • public ICinemachineCamera virtualCamera => m_VCam Description: Exposes the underlying Cinemachine camera as an ICinemachineCamera.

  • public float zoom { get; set } Description: Gets/sets the camera's zoom as the anchor's world Y position (height). Setting adjusts m_Anchor.position.y.

  • public Vector3 pivot { get; set } Description: Gets/sets the anchor world position.

  • public Vector3 position { get; set } Description: Alias for pivot. Getting/setting forwards to pivot.

  • public Vector3 rotation { get; set } Description: Gets/sets anchor rotation in Euler angles. Setting converts the given Euler angles into a Quaternion stored on the anchor.

  • public bool controllerEnabled { get; set } Description: Enables/disables the controller GameObject. Getter returns isActiveAndEnabled; setter calls gameObject.SetActive(value).

  • public bool collisionsEnabled { get; set } Description: Gets/sets the CinemachineRestrictToTerrain.enableObjectCollisions flag which toggles object collision checking.

  • public ref LensSettings lens => ref m_VCam.m_Lens Description: Returns a ref to the Cinemachine lens settings (exposes FieldOfView, Dutch, etc) of the virtual camera.

  • public Action eventCameraMove { get; set; } Description: Event-like Action invoked when any camera input is detected (inputDetected -> eventCameraMove?.Invoke()).

  • public float fov { get; set; } Description: Gets/sets the virtual camera's FieldOfView via the lens.

  • public float dutch { get; set; } Description: Gets/sets the lens's Dutch (roll) value.

  • public bool inputEnabled { get; set; } = true Description: When false, controller ignores CameraInput and will not move. Defaults to true.

Constructors

  • public CinematicCameraController() Description: Standard Unity MonoBehaviour constructor (no custom constructor logic). Initialization is performed in Awake (async).

Methods

  • private async void Awake() : System.Void Description: Async initialization. Waits for GameManager.instance.WaitForReadyState(), creates the m_Anchor GameObject, gets and configures the CinemachineVirtualCamera and CinemachineRestrictToTerrain components, initializes CameraInput (if present), retrieves/assigns CameraUpdateSystem.cinematicCameraController, then disables this controller GameObject (gameObject.SetActive(false)) so it starts inactive until explicitly enabled.

Notes: - Because Awake is async, the controller's initialization waits for the game to be ready before setting up components and registering with systems. - The anchor is named "CinematicCameraControllerAnchor".

  • public void TryMatchPosition(IGameCameraController other) : System.Void Description: Copies the provided IGameCameraController's position and rotation into this controller (position = other.position; rotation = other.rotation;). Useful when switching cameras to preserve view.

  • public void UpdateCamera() : System.Void Description: Per-frame update entry called by CameraUpdateSystem. Refreshes CameraInput, invokes eventCameraMove if any input exists, and if inputEnabled is true calls UpdateController to move/rotate/zoom the anchor. Also updates the AudioManager audio listener with this camera's transform.

  • private void UpdateController(CameraInput input) : System.Void Description: Core motion logic:

  • Refreshes m_RestrictToTerrain and clamps a candidate position to terrain/map bounds.
  • Computes a height-based t factor to interpolate between min and max movement/zoom speeds.
  • Applies planar move (move.x, move.y), vertical zoom (input.zoom), and rotation input (input.rotate) to compute a new anchor position and rotation.
  • Clamps the Y to not exceed terrainHeight + m_MaxHeight.
  • Uses CinemachineRestrictToTerrain.CheckForCollision to detect collisions when enableObjectCollisions is enabled; if a collision occurs the returned collision-corrected position is used.
  • Assigns the computed position and quaternion to m_Anchor.

Important math points: - Movement is applied in the anchor's Y rotation basis (using Quaternion.AngleAxis(eulerAngles.y, Vector3.up)). - Rotation X is clamped to a valid pitch range via Mathf.Clamp on (eulerAngles.x + 90f) % 360f - vector2.y, then subtracting 90f to restore anchor orientation. - Vertical zoom changes the anchor Y by -num (note negative to move camera up/down based on input sign).

  • private void OnDestroy() : System.Void Description: Cleanup. Destroys the created anchor GameObject if present and unregisters from the CameraUpdateSystem by setting cinematicCameraController to null.

Usage Example

// Find the controller in the scene (example usage)
var cinematic = FindObjectOfType<Game.CinematicCameraController>();
if (cinematic != null)
{
    // Enable the controller
    cinematic.controllerEnabled = true;

    // Set initial zoom height
    cinematic.zoom = 200f;

    // Disable input temporarily (e.g. during a cutscene)
    cinematic.inputEnabled = false;

    // Subscribe to camera-move notifications
    cinematic.eventCameraMove += () => Debug.Log("Cinematic camera moved");

    // Toggle collisions with objects
    cinematic.collisionsEnabled = true;

    // Copy view from another game camera
    // cinematic.TryMatchPosition(otherCameraController);
}

Additional notes: - This controller requires CinemachineVirtualCamera and CinemachineRestrictToTerrain components on the same GameObject. CameraInput is optional but recommended for player control. - Because Awake is async and the object is disabled at the end of initialization, other code should enable controller.controllerEnabled = true when ready to use. - The camera's lens settings are exposed by the ref property lens, and fov/dutch can be changed directly via the corresponding properties.