I want to zoom the main camera by changing the field of view, and I want it to happen smoothly.
Problem
I am getting the zoom in, but it is too fast. I have change variables and played with number but still is either too fast or it does not happen.
Code
public class ZoomInOut : MonoBehaviour {
//public variables parameter for Unity inspector input
public float initialFOV;
public float zoomInFOV;
public float smooth;
//private variables for script mod
private float sphereRotation;
private float lerpTimer;
// Use this for initialization
void Start ()
{
Camera.main.fieldOfView = initialFOV;
}
// Update is called once per frame
void Update ()
{
ChangeFOV();
}
void ChangeFOV()
{
lerpTimer = Time.deltaTime * smooth;
Camera.main.fieldOfView = Mathf.Lerp(initialFOV, zoomInFOV, lerpTimer);
}
}
Instead of using mathf.lerp I changed to if statements. I started checking what was the current FOV after rotation stopped. When it started to Zoom-In I checked the FOV until it was the same or smaller than my Zoom-In value, at which point I set it equal to my Zoom-In input. I change the value of the FOV using an incremental.
Code
public class ZoomInOut : MonoBehaviour
{
//public variables paremeters for Unity inpector inputs
public float initialFOV;
public float zoomInFOV;
public float smooth;
//private variables for script mod
private float sphereRotation;
private float currentFOV;
// Use this for initialization
void Start()
{
//set initial FOV at start
Camera.main.fieldOfView = initialFOV;
}
// Update is called once per frame
void Update()
{
//get component from sphere script to know if rations is happening
sphereRotation = GameObject.Find("Sphere").GetComponent<Rotation>().rotationSpeed;
//store current field of view value in variable
currentFOV = Camera.main.fieldOfView;
//check if roration stopped and call function to change FOV
if (sphereRotation <= 0)
{
ChangeFOV();
}
}
//function to zoom in the FOV
void ChangeFOV()
{
//check that current FOV is different than Zoomed
if (currentFOV != zoomInFOV)
{
//check if current FOV is grater than the Zoomed in FOV input and increment the FOV smoothly
if (currentFOV > zoomInFOV)
{
Camera.main.fieldOfView += (-smooth * Time.deltaTime);
}
else
{
//then current FOV gets to the same or smaller value than the Zoomed in input
//set FOV as the Zoomed in input
if (currentFOV <= zoomInFOV)
{
Camera.main.fieldOfView = zoomInFOV;
}
}
}
}
}
This was my solution to my problem. Please feel free to criticize and comment on it. I tried the math.lerp but I was not able to get the smooth transition I wanted. If you have a better way, you can post a working example.
Here is a solution using Lerp with a few examples how to smooth it out. Just slap this script on a camera and it should work.
All that matters is in the 4 lines within the first if statement in the ChangeFOV() method. The magic is how you calculate t, the actual interpolation. I have 4 examples there: Smoothstep and SmootherStep smoothing in and out, quadratic and cubic just easing in (could be inverted to ease out).
using System;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class FoviLerp : MonoBehaviour {
public float FovStart = 60;
public float FovEnd = 30;
public float TransitionTime = 3;
private float _currentFov;
private float _lerpTime;
private Camera _camera;
void Start ()
{
//could also use Camera.main if apropriate
_camera = this.GetComponent<Camera>();
}
void Update () {
ChangeFOV();
}
void ChangeFOV()
{
if (Math.Abs(_currentFov - FovEnd) > float.Epsilon)
{
_lerpTime += Time.deltaTime;
var t = _lerpTime / TransitionTime;
//Different ways of interpolation if you comment them all it is just a linear lerp
t = Mathf.SmoothStep(0, 1, t); //Mathf.SmoothStep() can be used just like Lerp, here it is used to calc t so it works with the other examples.
//t = SmootherStep(t);
//t = t * t;
//t = t * t * t;
_currentFov = Mathf.Lerp(FovStart, FovEnd, t);
}
else if (Math.Abs(_currentFov - FovEnd) < float.Epsilon)
{
//Just going back where we came from. For demonstrative purpos only ...
_lerpTime = 0;
Debug.Log("Switch");
var tmp = FovStart;
FovStart = FovEnd;
FovEnd = tmp;
}
_camera.fieldOfView = _currentFov;
}
private float SmootherStep(float t)
{
return t * t * t * (t * (6f * t - 15f) + 10f);
}
}