Weird Zoom In Issue

I’m having a weird zooming in issue with my vcam controller script. I’m using a Virtual Camera.

Normal zooming in (near to far distance zoom) works fine.

Zooming in with camera tilting is making the camera very jerky while it is rotating. Why is this happening?

This is my code:

using UnityEngine;
using Cinemachine;

public class VCamController : MonoBehaviour
{
    // Important stuff here.
    public CinemachineVirtualCamera vcam;

    // Variables used in calculations to make the script logic work.
    //private float defaultZoom = 20f;
    private float zoom = 20f;
    private float zoomChangeAmount = 50f;

    private float tilt = 70f;
    private float tiltChangeAmount = 100f;
    public bool camTilt = false;

    private void Update()
    {
        ScrollZoom();
    }

    void ScrollZoom()
    {
        if (Input.mouseScrollDelta.y > 0)
        {
            zoom -= zoomChangeAmount * Time.deltaTime;
            zoom = Mathf.Clamp(zoom, 10f, 30f);
            vcam.GetCinemachineComponent<CinemachineFramingTransposer>().m_CameraDistance = zoom;

            if (camTilt == true)
            {
                tilt -= tiltChangeAmount * Time.deltaTime;
                tilt = Mathf.Clamp(tilt, 40f, 80f);
                vcam.transform.rotation = Quaternion.Euler(tilt, vcam.transform.rotation.y, vcam.transform.rotation.z);
            }
        }
        if (Input.mouseScrollDelta.y < 0)
        {
            zoom += zoomChangeAmount * Time.deltaTime;
            zoom = Mathf.Clamp(zoom, 10f, 30f);
            vcam.GetCinemachineComponent<CinemachineFramingTransposer>().m_CameraDistance = zoom;

            if (camTilt == true)
            {
                tilt += tiltChangeAmount * Time.deltaTime;
                tilt = Mathf.Clamp(tilt, 40f, 80f);
                vcam.transform.rotation = Quaternion.Euler(tilt, vcam.transform.rotation.y, vcam.transform.rotation.z);
            }
        }
    }
}

Fair warning: I’m the Product Manager, not tech support nor one of the engineers (most folks are still on holiday). I think I’ve got a decent answer for you, but take it with an appropriate grain of salt.

I think the issue here is that you’re trying to do in code what Cinemachine already does for you for free. I’ve set up an analogous scene.

You’ll notice that I’m using two virtual cameras instead of one. (CM upper represents my zoomed out, looking down position, CM lower represents my lower, looking forward position. I’m using a Cinemachine Mixing Camera to blend between them. With that done, the only code I need is something to adjust the weights of the two cameras.

using UnityEngine;
using Cinemachine;
public class MixingCamController : MonoBehaviour
{
    // Important stuff here.
    public CinemachineMixingCamera mixCam;
    // Variables used in calculations to make the script logic work.
    [Range(0,1f)]
    private float zoom = .5f;
    public float zoomChangeAmount = 1f;
    private void Update()
    {
        ScrollZoom();
    }
    void ScrollZoom()
    {
        if (Input.mouseScrollDelta.y > 0)
        {
            zoom -= zoomChangeAmount * Time.deltaTime;
        }
        if (Input.mouseScrollDelta.y < 0)
        {
            zoom += zoomChangeAmount * Time.deltaTime;
        }

        mixCam.SetWeight(0, zoom);
        mixCam.SetWeight(1, 1f - zoom);
    }
}

Note that Virtual Cameras are just that: virtual. Think of them like bookmarks. Adding an extra vcam is negligible in terms of performance impact and greatly simplifies this problem.

Hope that helps.

1 Like