Skip to content

Game.CameraController

Assembly: Assembly-CSharp
Namespace: Game

Type: class

Base: MonoBehaviour, IGameCameraController

Summary: CameraController manages the in-game gameplay camera for Cities: Skylines 2. It handles camera position, rotation, zoom, edge-scrolling input, map-tile tool transition view, collision adjustments, terrain/water height sampling, and audio listener updates. The controller integrates with the input system (ProxyActionMap/ProxyAction), Cinemachine (CinemachineVirtualCamera), and ECS systems (CameraUpdateSystem, CameraCollisionSystem, TerrainSystem, WaterSystem). It supports smooth transitions and configurable zoom ranges and smoothing values.


Fields

  • private float3 m_Pivot
    Controls the world-space pivot point the camera orbits around. Serialized so it can be set in the inspector.

  • private float2 m_Angle
    Camera angle (x = yaw, y = pitch) stored as float2. Serialized.

  • private float m_Zoom
    Current zoom distance. Serialized.

  • private Bounds1 m_ZoomRange = new Bounds1(10f, 10000f)
    Allowed zoom range for normal gameplay view. Serialized.

  • private Bounds1 m_MapTileToolZoomRange = new Bounds1(10f, 20000f)
    Alternate zoom range used when the map tile tool view is active. Serialized.

  • private bool m_MapTileToolViewEnabled
    Flag used to enable/disable specialized map tile tool view handling. Serialized.

  • private float m_MapTileToolFOV
    Field of view used in map tile tool view. Serialized.

  • private float m_MapTileToolFarclip
    Far clip plane used in map tile tool view. Serialized.

  • private float3 m_MapTileToolPivot
    Pivot position for the map tile tool view. Serialized.

  • private float2 m_MapTileToolAngle
    Angle used for the map tile tool view. Serialized.

  • private float m_MapTileToolZoom
    Zoom used for the map tile tool view. Serialized.

  • private float m_MapTileToolTransitionTime
    Time for transitions between gameplay view and map tile view. Serialized.

  • private float m_MoveSmoothing = 1E-06f
    Smoothing factor used when adjusting pivot height to terrain/water heights. Serialized.

  • private float m_CollisionSmoothing = 0.001f
    Smoothing factor used by the collision system adjustments. Serialized.

  • private ProxyActionMap m_CameraMap
    Reference to the input action map for camera controls.

  • private ProxyAction m_MoveAction
    Input action used for camera movement.

  • private ProxyAction m_MoveFastAction
    Input action used for fast movement (modifier).

  • private ProxyAction m_RotateAction
    Input action used for rotating the camera.

  • private ProxyAction m_ZoomAction
    Input action used for zoom input.

  • private CinemachineVirtualCamera m_VCam
    The Cinemachine virtual camera component attached to the same GameObject.

  • private float m_InitialFarClip
    Cached initial far clip plane from the Cinemachine lens.

  • private float m_InitialFov
    Cached initial field of view from the Cinemachine lens.

  • private float m_LastGameViewZoom
    Stores last gameplay zoom when switching to map tile view.

  • private float2 m_LastGameViewAngle
    Stores last gameplay angle when switching to map tile view.

  • private float3 m_LastGameViewPivot
    Stores last gameplay pivot when switching to map tile view.

  • private float m_LastMapViewZoom
    Stores last map view zoom when switching back.

  • private float2 m_LastMapViewAngle
    Stores last map view angle when switching back.

  • private float3 m_LastMapViewPivot
    Stores last map view pivot when switching back.

  • private float m_MapViewTimer
    Timer used for map tile view transitions.

  • private AudioManager m_AudioManager
    Cached reference to an AudioManager (optional; AudioManager.instance used in updates).

  • private CameraUpdateSystem m_CameraSystem
    Reference to the ECS CameraUpdateSystem; used for active camera properties (near/fov/aspect).

  • private CameraCollisionSystem m_CollisionSystem
    Reference to the ECS CameraCollisionSystem; used to test and resolve camera collisions.

Properties

  • public IEnumerable<ProxyAction> inputActions
    Enumerable of active input ProxyAction instances used by this controller (Move, Move Fast, Rotate, Zoom). Useful if you need to register/unregister UI/input hooks.

  • public Action<bool> EventCameraMovingChanged { get; set; }
    Event invoked when camera moving state changes. The bool parameter indicates whether the camera is currently moving.

  • public bool moving { get; private set; }
    Indicates whether the controller currently considers the camera to be moving.

  • public ref LensSettings lens => ref m_VCam.m_Lens
    Reference to the Cinemachine lens settings for the virtual camera (exposes FarClipPlane, FieldOfView, etc).

  • public ICinemachineCamera virtualCamera => m_VCam
    Exposes the underlying Cinemachine virtual camera as ICinemachineCamera.

  • public Vector3 rotation
    Gets/sets camera rotation as a Unity Vector3 (z always 0). Maps to internal m_Angle ordering.

  • public TerrainSystem terrainSystem
    Gets a reference to the World.DefaultGameObjectInjectionWorld TerrainSystem if available; returns null otherwise.

  • public WaterSystem waterSystem
    Gets a reference to the World.DefaultGameObjectInjectionWorld WaterSystem if available; returns null otherwise.

  • public Vector3 pivot
    Gets/sets the camera pivot point (exposes m_Pivot).

  • public Vector3 position
    Getter returns transform.position. Setter is intentionally empty in this implementation (position is driven internally).

  • public float2 angle
    Gets/sets the internal angle vector (m_Angle).

  • public float zoom
    Gets/sets the internal zoom (m_Zoom).

  • public bool controllerEnabled
    Gets whether GameObject is active and enabled; sets active state of the GameObject.

  • public bool inputEnabled { get; set; } = true
    Whether camera input is accepted; simple auto-property initialized to true.

  • public Bounds1 zoomRange
    Returns m_MapTileToolZoomRange while the map tile view is active, otherwise returns m_ZoomRange.

  • public float3 cameraPosition { get; private set; }
    Current camera world-space local position used by the transform (after collision/terrain adjustments).

  • public float velocity { get; private set; }
    Scalar velocity (computed from squared distance change over Time.deltaTime).

  • public bool edgeScrolling { get; set; }
    Whether edge-scrolling is enabled. Read/written by Awake using SharedSettings.

  • public float edgeScrollingSensitivity { get; set; }
    Sensitivity for edge-scrolling.

  • public float clipDistance { get; set; }
    Unused in many places but available for external systems to set a clip/visibility distance.

Constructors

  • public CameraController()
    Default MonoBehaviour constructor; initialization happens in Awake. (No explicit parameterized constructors provided.)

Methods

  • public void TryMatchPosition(IGameCameraController other)
    Attempts to match camera position/rotation/zoom to another camera controller by computing pivot and zoom based on terrain height and the other camera's rotation/position. Uses terrain sampling and clamps zoom to zoomRange.

  • private async void Awake()
    Async Unity Awake that waits for GameManager.instance.WaitForReadyState() before initializing. Sets up edge-scrolling defaults, caches CinemachineVirtualCamera and its lens parameters, finds input action map/actions, and gets/sets CameraUpdateSystem and CameraCollisionSystem references. Called automatically by Unity on scene load.

Important: waits for GameManager readiness and relies on InputManager, SharedSettings, World.DefaultGameObjectInjectionWorld, and ECS systems.

  • public void UpdateCamera()
    Main per-frame camera update entrypoint (intended to be called by CameraUpdateSystem). Handles input reading, edge-scrolling, zoom/angle updates, pivot movement, terrain/water height clamping, collision checking (via CameraCollisionSystem), transform updates, velocity calculation, moving state change event, and audio listener update.

Notes: - Uses ProxyAction.ReadValue to read move/rotate/zoom inputs. - Applies smoothing and clamps to Zoom/Angle. - Integrates with terrainSystem and waterSystem for height sampling and bounds clamping. - Calls AudioManager.instance?.UpdateAudioListener with updated transform.

  • private float3 GetCameraPos(float3 cameraOffset)
    Returns m_Pivot + cameraOffset with an added vertical offset of zoomRange.min*0.5f. Used to compute camera local position from an offset direction/zoom.

  • private bool HandleMapViewCamera()
    Handles transitioning to/from the map tile tool view. Interpolates pivot, angle, zoom, Cinemachine lens FOV and FarClipPlane based on m_MapViewTimer and m_MapTileToolTransitionTime. Uses terrain/water sampling and returns true if a map view was handled (i.e., no further UpdateCamera work needed).

  • public static float2 LerpAngle(float2 from, float2 to, float t)
    Utility that interpolates angles while correctly wrapping the yaw component across the 360-degree boundary. The pitch (y) is linearly interpolated.

  • private bool TryGetTerrainHeight(Vector3 pos, out float terrainHeight)
    Attempts to sample terrain or water height at a world position using TerrainSystem and WaterSystem. Returns true if a valid height was obtained; otherwise returns false and sets terrainHeight to 0.

  • public static bool TryGet(out CameraController cameraController)
    Static helper that finds the GameObject tagged "GameplayCamera" and returns its CameraController component if present. Returns true and sets out param on success.

Usage Example

// Example: get the active gameplay camera and adjust its zoom/pivot
if (CameraController.TryGet(out CameraController cam))
{
    // enable/disable controller input
    cam.inputEnabled = true;

    // set pivot to a world position and zoom in
    cam.pivot = new Unity.Mathematics.float3(1000f, 0f, 1000f);
    cam.zoom = math.clamp(cam.zoom * 0.5f, cam.zoomRange.min, cam.zoomRange.max);

    // manually trigger a single update (normally CameraUpdateSystem calls UpdateCamera each frame)
    cam.UpdateCamera();
}

{{ Additional notes: - This controller is intended to run on the main Unity thread and depends on several game subsystems: InputManager, GameManager, SharedSettings/GameplaySettings, MapTilesUISystem, TerrainSystem, WaterSystem, CameraUpdateSystem, CameraCollisionSystem, and AudioManager. - For modding, be careful altering serialized fields at runtime; Cinemachine lens changes (FOV/FarClipPlane) are applied directly to the attached CinemachineVirtualCamera. - Map tile tool transitions are handled internally; toggling MapTilesUISystem.mapTileViewActive will automatically drive map view transitions. - If you need to override camera movement or implement a custom controller, consider implementing IGameCameraController and setting CameraUpdateSystem.gamePlayController accordingly. }}