I’m using Vector3.Lerp to set up my Cinemachine camera to create a zoom effect when the player collects a powerup. When the player collects a powerup it calls ZoomCameraOn(), the camera zooms out, and after a certain amount of time (when the powerup timer expires), the camera zooms back to its normal position.
This way, if the user collects a powerup while the camera is zooming in to its normal position, the camera will seamlessly start zooming out from its current position.
If I only collect a power-up once to trigger the camera movement, it works fine. It’s only when you interrupt the zooming process by collecting another power-up that the problems start.
If you collect a powerup while the camera is zooming back to its normal position, the camera zooms out fine, but when it’s time for the camera to zoom back in after the timer expires, it plays the zoom effect twice.
-
The first time it zooms in, the camera’s starting point is from where it was when the zoom out was triggered after a powerup was collected.
-
The second time, the camera zooms in as it should. It’s starting point is from the end point from where the camera finishes zooming out.
Here’s the code:
public CinemachineVirtualCamera cinemachineVirtualCamera;
public CinemachineTransposer cinemachineTransposer;
public Vector3 startPosition_ZoomOn;
public Vector3 startPosition_ZoomOff;
public bool cameraZoom;
public float timer;
void Awake()
{
cinemachineTransposer = cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>();
}
void Update()
{
if (cameraZoom && timer > 0)
{
timer -= 2f * Time.deltaTime;
}
if (timer <= 0)
{
timer = 10f;
ZoomCameraOff();
}
}
public void ZoomCameraOn()
{
startPosition_ZoomOn = cinemachineTransposer.m_FollowOffset;
Vector3 endPosition = new Vector3(0, 4, -9);
StartCoroutine(ZoomCameraOn_LerpPosition(endPosition, 3));
cameraZoom = true;
timer = 10f;
}
IEnumerator ZoomCameraOn_LerpPosition(Vector3 targetPosition, float duration)
{
float time = 0;
while (time < duration)
{
if (cameraZoom == true)
{
cinemachineTransposer.m_FollowOffset = Vector3.Lerp(startPosition_ZoomOn, targetPosition, time / duration);
time += Time.deltaTime;
}
yield return null;
}
cinemachineTransposer.m_FollowOffset = targetPosition;
}
public void ZoomCameraOff()
{
startPosition_ZoomOff = new Vector3(0, 4, -9);
Vector3 endPosition = new Vector3(0, 3, -7);
StartCoroutine(ZoomCameraOff_LerpPosition(endPosition, 2));
cameraZoom = false;
}
IEnumerator ZoomCameraOff_LerpPosition(Vector3 targetPosition, float duration)
{
float time = 0;
while (time < duration)
{
if (cameraZoom == false)
{
cinemachineTransposer.m_FollowOffset = Vector3.Lerp(startPosition_ZoomOff, targetPosition, time / duration);
time += Time.deltaTime;
}
yield return null;
}
cinemachineTransposer.m_FollowOffset = targetPosition;
}
I don’t know what’s causing this. I tried stopping the zoom in coroutine when the zoom out is triggered, thinking it needed to finish the first zoom-in before doing another, but that didn’t work.
I’d be grateful for any help as I’ve hit a brick wall trying to solve this problem.