Unity Cinemachine Extension Scripts

Thomas Steffen
3 min readSep 18, 2023

--

Recently I’ve been experimenting with adjusting the cinemachine script. I’ve done various extensions in the past and I thought it would be helpful to start sharing these moving forward.

This script is an extension for Cinemachine in Unity, written in C#. It’s designed to be used with Cinemachine Virtual Cameras and allows you to lock the camera’s position along the X, Y, and Z axes independently. I wanted the ability to follow the player on specific axis, locking the other axis to a set position. I’ll break down the script and explain each part in detail.

using UnityEngine;
using Cinemachine;

/// <summary>
/// An add-on module for Cinemachine Virtual Camera that locks the camera's Z co-ordinate
/// </summary>
[ExecuteInEditMode]
/* allows the script to run in Edit Mode, which means it will execute even
when the game is not playing. This can be useful for testing and
configuring the script in the editor.*/
[SaveDuringPlay]
/* specifies that changes made to the script's properties during play mode
should be saved.*/
[AddComponentMenu("")] // Hide in menu
/* removes the script from the "Add Component" menu in the Unity Editor.
It means you won't be able to add this script as a component directly
from the menu; instead, you would typically add it to
a Cinemachine Virtual Camera through the Unity Inspector.*/



public class Cinemachine_LockCamAxis : CinemachineExtension
//defines the class Cinemachine_LockCamAxis, which extends CinemachineExtension
{
[Tooltip("Lock the camera's Z position to this value")]
[SerializeField] private float m_XPosition = 0;
[SerializeField] private float m_YPosition = 0;
[SerializeField] private float m_ZPosition = -10;
/*These variables allow you to specify the desired positions for
the camera along the X, Y, and Z axes, respectively.*/

[SerializeField] private bool lockXaxis;
[SerializeField] private bool lockYaxis;
[SerializeField] private bool lockZaxis;
/*These boolean variables determine whether you want to lock the
camera's position along the X, Y, and Z axes, respectively.*/

protected override void PostPipelineStageCallback(
CinemachineVirtualCameraBase vcam,
CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
/*This is a method override for PostPipelineStageCallback.
It's a callback method called by Cinemachine after processing each stage
of the camera pipeline. The method receives several parameters:

vcam: The Cinemachine Virtual Camera that this extension is attached to.
stage: The current stage of the camera processing pipeline.
state: reference to CameraState / camera's current state.
deltaTime: The time since the last frame update.*/

{
if (lockXaxis)
{
if (stage == CinemachineCore.Stage.Body)
{
var pos = state.RawPosition;
pos.x = m_XPosition;
state.RawPosition = pos;
}
}

if (lockYaxis)
{
if (stage == CinemachineCore.Stage.Body)
{
var pos = state.RawPosition;
pos.y = m_YPosition;
state.RawPosition = pos;
}
}

if (lockZaxis)
{
if (stage == CinemachineCore.Stage.Body)
{
var pos = state.RawPosition;
pos.z = m_ZPosition;
state.RawPosition = pos;
}
}
/* Inside this method, the script checks if any of the axis lock flags
(lockXaxis, lockYaxis, lockZaxis) are set to true. If they are,
and the current processing stage is CinemachineCore.Stage.Body,
it modifies the camera's RawPosition accordingly to lock the camera's
position along the specified axis.

For example, if lockXaxis is true, it sets the camera's X position
to m_XPosition. This allows you to lock the camera's position
along any combination of the X, Y, and Z axes as needed.*/
}
}

Just to give you some examples, this could be useful in platformer’s to prevent the camera from changing depth or to lock the camera from moving vertically. I applied this to my 2D Space Shooter to allow some dampened follow only along the x-axis, with the y and z being locked.

This script extends Cinemachine’s functionality to allow you to lock the position of a Cinemachine Virtual Camera along the X, Y, and Z axes independently. You can configure which axes to lock and set the desired locked positions through the script’s serialized fields in the Unity Inspector.

--

--

Thomas Steffen

I am Virtual Reality Developer, UI Systems, and general programmer with a passion for Unity software development.