Skip to content

Instantly share code, notes, and snippets.

@Ambratolm
Created December 14, 2024 08:47
Show Gist options
  • Save Ambratolm/86fd1f87c94241df33dc2157e5cea352 to your computer and use it in GitHub Desktop.
Save Ambratolm/86fd1f87c94241df33dc2157e5cea352 to your computer and use it in GitHub Desktop.
Cinemachine extension that locks the camera position along the X and Y axes.
using Sirenix.OdinInspector;
using Unity.Cinemachine;
using UnityEngine;
using static Unity.Cinemachine.CinemachineCore;
namespace Assets
{
/// <summary>
/// Cinemachine extension that locks the camera position along the X and Y axes.
/// </summary>
[RequireComponent(typeof(CinemachineCamera)), ExecuteInEditMode, SaveDuringPlay, AddComponentMenu("")]
public class CinemachineLocker2D : CinemachineExtension
{
[SerializeField, LabelText("Lock X")]
[Tooltip("Determines whether to lock the X-axis position.")]
private bool xLocked;
public bool XLocked { get => xLocked; set => xLocked = value; }
[SerializeField, LabelText("Lock Y")]
[Tooltip("Determines whether to lock the Y-axis position.")]
private bool yLocked;
public bool YLocked { get => yLocked; set => yLocked = value; }
[SerializeField]
[Tooltip("Position to lock the camera to.")]
private Vector2 _position;
public Vector2 Position { get => _position; set => _position = value; }
//----------------------------------------------------------------------------------------------------
protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam,
Stage stage, ref CameraState state, float deltaTime)
{
if ((!xLocked && !yLocked) || (stage != Stage.Body)) return;
Vector3 lockPosition = state.RawPosition;
if (xLocked) lockPosition.x = _position.x;
if (yLocked) lockPosition.y = _position.y;
state.RawPosition = lockPosition;
}
//----------------------------------------------------------------------------------------------------
/// <summary>
/// Locks the camera along the X-axis to the given X position.
/// </summary>
/// <param name="x">X position to lock the camera to.</param>
public void LockX(float? x = null)
{
xLocked = true;
if (x != null) _position.x = x.Value;
}
/// <summary>
/// Locks the camera along the Y-axis to the given Y position.
/// </summary>
/// <param name="y">Y position to lock the camera to.</param>
public void LockY(float? y = null)
{
yLocked = true;
if (y != null) _position.y = y.Value;
}
/// <summary>
/// Locks the camera along all axes to the given position.
/// </summary>
/// <param name="position">Position to lock the camera to.</param>
public void Lock(Vector2? position = null)
{
xLocked = yLocked = true;
if (position != null) _position = position.Value;
}
/// <summary>
/// Unlocks the camera along the X-axis and forces it to assume the given X position.
/// </summary>
/// <param name="x">Position to force the camera to.</param>
public void UnlockX(float? x = null)
{
xLocked = false;
if (x != null) ForcePosition(x: x.Value);
}
/// <summary>
/// Unlocks the camera along the Y-axis and forces it to assume the given Y position.
/// </summary>
/// <param name="y">Position to force the camera to.</param>
public void UnlockY(float? y = null)
{
yLocked = false;
if (y != null) ForcePosition(y: y.Value);
}
/// <summary>
/// Unlocks the camera along all axes and forces it to assume the given position.
/// </summary>
/// <param name="position">Position to force the camera to.</param>
public void Unlock(Vector2? position = null)
{
xLocked = yLocked = false;
if (position != null) ForcePosition(position.Value);
}
//----------------------------------------------------------------------------------------------------
/// <summary>
/// Forces the position of the virtual camera to the specified coordinates.
/// </summary>
/// <param name="x">The x-coordinate. If null, the x-coordinate remains unchanged.</param>
/// <param name="y">The y-coordinate. If null, the y-coordinate remains unchanged.</param>
public void ForcePosition(float? x = null, float? y = null)
{
if (x == null && y == null) return;
Vector3 position = ComponentOwner.transform.position;
if (x != null) position.x = x.Value;
if (y != null) position.y = y.Value;
ForcePosition(position);
}
/// <summary>
/// Forces the position of the virtual camera to the specified 2D position.
/// </summary>
/// <param name="position">The 2D position to force the virtual camera to.</param>
public void ForcePosition(Vector2 position)
{
Vector3 position3D = position;
position3D.z = ComponentOwner.transform.position.z;
ForcePosition(position3D);
}
/// <summary>
/// Forces the position of the virtual camera to the specified 3D position.
/// </summary>
/// <param name="position">The 3D position to force the virtual camera to.</param>
public void ForcePosition(Vector3 position)
=> ComponentOwner.ForceCameraPosition(position, ComponentOwner.transform.rotation);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment