Game.CinemachineDollyCartLookExtension
Assembly:
Assembly-CSharp (Assembly-CSharp.dll)
Namespace:
Game
Type:
Class
Base:
Cinemachine.CinemachineExtension
Summary:
A Cinemachine extension that adjusts the camera's aim while a CinemachineDollyCart is moving along a CinemachinePathBase. It lets you specify per-path-index look-angle overrides (Vector3 Euler angles) and interpolates between them as the dolly cart moves. Handles both looped and non-looped paths and ignores z rotation from both path orientation and override so the camera roll is not applied. Useful in Cities: Skylines 2 mods to fine-tune camera look directions along scripted dolly paths.
Fields
public struct DollyLookAngleOverride
This nested struct represents a single per-index override entry. It contains a boolean to enable the override and a Vector3 containing the override Euler angles (degrees). When m_OverrideLookAngle is true, the override is applied relative to the path's orientation (with z normalized out).
Fields:public bool m_OverrideLookAngle
— whether this entry should override the path look angle.-
public Vector3 m_Angle
— the Euler angle override to apply (degrees).
{{ The struct is used to populate the m_Angles array: each element corresponds to an integer path index (or corner) and can be blended between adjacent entries as the dolly moves. }} -
public DollyLookAngleOverride[] m_Angles
Array of per-index look-angle overrides. Each element corresponds to a location/index along the path. The class uses this array to compute orientation offsets and to interpolate between indices as the dolly moves.
{{ Ensure the array has an entry for each path index you intend to override. For looped paths the GetMaxPos method treats the maximum differently (see Methods). If the array is empty, no overrides are applied. }}
Properties
- This type has no public properties.
{{ Configuration is done via the public m_Angles field and the CinemachineDollyCart component on the same GameObject. }}
Constructors
public CinemachineDollyCartLookExtension()
{{ Default Unity component constructor. This class is intended to be used as a component attached to the same GameObject as a CinemachineDollyCart; no special construction is required beyond Unity's component lifecycle. }}
Methods
-
public float GetMaxPos(bool looped)
Returns the effective maximum position value used by StandardizePos and indexing logic. For an m_Angles length N, the method calculates N-1 as the last index. If looped is true the method returns one more than the last index (allowing wrap-around interpolation). If the array is too small, it returns 0.
{{ Use this to determine the usable range of cart positions for indexing/interpolation. }} -
public virtual float StandardizePos(float pos, bool looped)
Normalizes/clamps a floating position into the valid range for the array. If looped is true, the position wraps modulo the maximum; otherwise it is clamped to [0, max].
{{ This ensures interpolation uses valid indices and supports negative positions (wraps them for looped paths). }} -
private float GetBoundingIndices(float pos, bool looped, out int indexA, out int indexB)
Converts a position into two integer indices (indexA and indexB) that bound the position for interpolation, and returns the standardized position. Handles edge cases for arrays with fewer than 2 entries and corrects indexing for looped/non-looped behavior.
{{ The returned standardized pos is suitable for computing the interpolation fraction between indexA and indexB. For single-entry arrays both indices will be 0. }} -
protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
Main runtime hook. When the pipeline stage is Aim, and if the attached CinemachineDollyCart uses PathUnits, this method: - Determines bounding indices for the cart's current position along the path.
- Computes per-index angle offsets (Quaternion) from m_Angles.
- Spherically interpolates between the two offsets if needed.
-
Adds the computed offset to the path's orientation (z components zeroed) and sets state.RawOrientation so the camera aims accordingly.
{{ Requires that a CinemachineDollyCart component is present on the same GameObject. If m_Angles is empty or the cart is not using PathUnits, the extension does nothing. The z axis (roll) is explicitly ignored for both path orientation and override angles. }} -
private Quaternion GetAngleOffset(CinemachinePathBase path, int t)
Computes the orientation offset Quaternion for a given index t. If the corresponding m_Angles[t].m_OverrideLookAngle is true, it subtracts the path's orientation (z zeroed) from the override Euler angles and returns that rotation; otherwise returns identity.
{{ This produces a rotation that, when added to the path orientation, yields the final look orientation for that index. }}
Usage Example
// Attach this component to the same GameObject that has a CinemachineDollyCart.
// Configure the m_Angles array (e.g., in Awake, Start or via the inspector).
using Cinemachine;
using UnityEngine;
using Game;
public class SetupDollyLook : MonoBehaviour
{
void Start()
{
var ext = gameObject.GetComponent<CinemachineDollyCartLookExtension>();
var cart = gameObject.GetComponent<CinemachineDollyCart>();
if (ext == null || cart == null || cart.m_Path == null)
return;
// Example: create one override per integer index along the path
int count = Mathf.Max(1, cart.m_Path.MinPos + cart.m_Path.MaxPos); // or determine desired count
// For simplicity, set an override for the first 3 indices:
ext.m_Angles = new CinemachineDollyCartLookExtension.DollyLookAngleOverride[3];
ext.m_Angles[0].m_OverrideLookAngle = true;
ext.m_Angles[0].m_Angle = new Vector3(10f, 0f, 0f); // tilt down 10 degrees
ext.m_Angles[1].m_OverrideLookAngle = true;
ext.m_Angles[1].m_Angle = new Vector3(0f, 15f, 0f); // look right 15 degrees
ext.m_Angles[2].m_OverrideLookAngle = false; // no override, use path orientation
}
}
{{ Notes: - Attach the extension to the same GameObject as a CinemachineDollyCart (the extension fetches that component at runtime). - The extension only acts when the DollyCart uses CinemachinePathBase.PositionUnits.PathUnits. - The Z (roll) component of both path orientation and overrides is ignored to avoid rolling the camera. - Make sure the m_Angles array length and indexing match how you want to address path positions. For looped paths, GetMaxPos treats the range differently to allow wrap-around interpolation. - This is intended for use in Unity-based modding (Cities: Skylines 2) where Cinemachine is present. }}