Hi all
New to Unity and fairly new to coding generally. I’ve been following Sasquatch B’s tutorial on metroidvania camera controls (
) and have an issue I’m struggling to resolve.
I’ve built the camera system, which creates a Cinemachine Virtual Camera following an object which in turn follows the player (for smoother movement). My Camera works great, but will NOT stay within the bounds of a 2D confiner. I’ve tried both Cinemachine Confiner and Cinemachine Confiner 2D, tried Box and Polygon colliders etc. - no joy.
I suspect that the issue is that the code I use to move the Camera (i.e. follow the object following the player) is overriding the confiner bounds. Any idea how to solve this issue?
For reference, this is my CameraManager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class CameraManager : MonoBehaviour
{
public static CameraManager instance;
[SerializeField] private CinemachineVirtualCamera[] _allVirtualCameras;
[Header("Controls for lerping the Y Damping during player jump/fall")]
[SerializeField] private float _fallPanAmount = 0.25f;
[SerializeField] private float _fallYPanTime = 0.35f;
public float _fallSpeedYDampingChangeThreshold = -15f;
public bool IsLerpingYDamping { get; private set; }
public bool LerpedFromPlayerFalling { get; set; }
private Coroutine _lerpYPanCoroutine;
private Coroutine _panCameraCoroutine; // Coroutine to run in our CameraTrigger script to auto pan the camera.
private CinemachineVirtualCamera _currentCamera;
private CinemachineFramingTransposer _framingTransposer;
private float _normYPanAmount;
private Vector3 _startingTrackedObjectOffset;
private void Awake()
{
if (instance == null)
{
instance = this;
}
for (int i = 0; i < _allVirtualCameras.Length; i++)
{
if (_allVirtualCameras[i].enabled)
{
// Set current active camera
_currentCamera = _allVirtualCameras[i];
// Set the framing transposer
_framingTransposer = _currentCamera.GetCinemachineComponent<CinemachineFramingTransposer>();
}
}
// Set the YDamping amount based on the inspector value
_normYPanAmount = _framingTransposer.m_YDamping;
// Set the starting position of the tracked object offset
_startingTrackedObjectOffset = _framingTransposer.m_TrackedObjectOffset;
}
// Pan the Camera
public void PanCameraOnContact(float panDistance, float panTime, PanDirection panDirection, bool panToStartingPos)
{
_panCameraCoroutine = StartCoroutine(PanCamera(panDistance, panTime, panDirection, panToStartingPos));
}
private IEnumerator PanCamera(float panDistance, float panTime, PanDirection panDirection, bool panToStartingPos)
{
Vector3 endPos = Vector3.zero;
Vector3 startingPos = Vector3.zero;
// Handle pan from trigger
if (!panToStartingPos)
{
// Set the direction and distance
switch (panDirection)
{
case PanDirection.Up:
endPos = Vector3.up;
break;
case PanDirection.Down:
endPos = Vector3.down;
break;
case PanDirection.Left:
endPos = Vector3.left;
break;
case PanDirection.Right:
endPos = Vector3.right;
break;
default:
break;
}
endPos *= panDistance;
startingPos = _startingTrackedObjectOffset;
endPos += startingPos;
}
// Handle the pan back to the starting position
else
{
startingPos = _framingTransposer.m_TrackedObjectOffset;
endPos = _startingTrackedObjectOffset;
}
// Handle the actual panning of the camera
float elapsedTime = 0f;
while (elapsedTime < panTime)
{
elapsedTime += Time.deltaTime;
Vector3 panLerp = Vector3.Lerp(startingPos, endPos, (elapsedTime / panTime));
_framingTransposer.m_TrackedObjectOffset = panLerp;
yield return null;
}
}
public void LerpYDamping(bool isPlayerFalling)
{
if (_lerpYPanCoroutine != null)
{
StopCoroutine(_lerpYPanCoroutine);
}
_lerpYPanCoroutine = StartCoroutine(LerpYAction(isPlayerFalling));
}
public IEnumerator LerpYAction(bool isPlayerFalling)
{
IsLerpingYDamping = true;
// Grab the starting damping
float startDampAmount = _framingTransposer.m_YDamping;
float endDampAmount = 0f;
// Determine end damping amount
if (isPlayerFalling)
{
endDampAmount = _fallPanAmount;
LerpedFromPlayerFalling = true;
}
else
{
endDampAmount = _normYPanAmount;
}
// Lerp the pan amount
float elapsedTime = 0f;
while (elapsedTime < _fallYPanTime)
{
elapsedTime += Time.deltaTime;
float lerpedPanAmount = Mathf.Lerp(startDampAmount, endDampAmount, (elapsedTime / _fallYPanTime));
_framingTransposer.m_YDamping = lerpedPanAmount;
yield return null;
}
_framingTransposer.m_YDamping = endDampAmount;
IsLerpingYDamping = false;
}
}