简体   繁体   中英

Zoom camera FOV overtime

I'm wondering how to smoothly zoom in and smoothly zoom out on button press in Unity3d using c#. I've got zooming part down already, but not sure how to make a transition of zooming in and out smooth. As an example, I'd like it to zoom in as smooth as it is in ARMA or DayZ game.

Here's my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class zoomIN : MonoBehaviour {

    public Camera cam;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

        if (Input.GetMouseButton (1)) {
            cam.fieldOfView = 20;
        }

        if (Input.GetMouseButtonUp (1)) {
            cam.fieldOfView = 60;
        }

    }
}

I'd appreciate any help! Thanks and Merry Xmas!

Use coroutine to do this. You can use it to enable the speed or duration of the zooming. Perform a Mathf.Lerp between cam.fieldOfView and the destination( 20 or 60 ) depending on if the key is pressed or released.

Note: You must change Input.GetMouseButton to Input.GetMouseButtonDown otherwise your first if statement will be running every frame while the right mouse button is held down. I think you want to be true once only.

public Camera cam;
Coroutine zoomCoroutine;

// Update is called once per frame
void Update()
{
    if (Input.GetMouseButtonDown(1))
    {
        //Stop old coroutine
        if (zoomCoroutine != null)
            StopCoroutine(zoomCoroutine);

        //Start new coroutine and zoom within 1 second
        zoomCoroutine = StartCoroutine(lerpFieldOfView(cam, 20, 1f));
    }

    if (Input.GetMouseButtonUp(1))
    {
        //Stop old coroutine
        if (zoomCoroutine != null)
            StopCoroutine(zoomCoroutine);

        //Start new coroutine and zoom within 1 second
        zoomCoroutine = StartCoroutine(lerpFieldOfView(cam, 60, 1f));
    }

}


IEnumerator lerpFieldOfView(Camera targetCamera, float toFOV, float duration)
{
    float counter = 0;

    float fromFOV = targetCamera.fieldOfView;

    while (counter < duration)
    {
        counter += Time.deltaTime;

        float fOVTime = counter / duration;
        Debug.Log(fOVTime);

        //Change FOV
        targetCamera.fieldOfView = Mathf.Lerp(fromFOV, toFOV, fOVTime);
        //Wait for a frame
        yield return null;
    }
}

A simple way to get your smooth zoom animation is by performing the zoom operation over multiple frames. So instead of changing the fieldOfView from 20 to 60 right away, increase the fieldOfView with 5 every frame until you reach your target of 60. (To lengthen the animation you can of course take a smaller number than 5.) So based on the mouse input you can keep a state _zoomedIn and based on that state and on the current fieldOfView you can determine whether you still need to add or substract to the value. Which gives you something like the following code: (not tested)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class zoomIN : MonoBehaviour {

    public Camera cam;
    private bool _zoomedIn = false;
    private int _zoomedInTarget = 60;
    private int _zoomedOutTarget = 20;

    // Update is called once per frame
    void Update () {

        if (Input.GetMouseButtonDown (1))
            _zoomedIn = true;

        if (Input.GetMouseButtonUp (1)) {
            _zoomedIn = false;
        }

        if (_zoomedIn) {
            if (cam.fieldOfView < _zoomedInTarget)
                cam.fieldOfView += 5;
        } else {
            if (cam.fieldOfView > _zoomedOutTarget)
                cam.fieldOfView -= 5;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM