I am trying to make my camera smoothly zoom in and out whenever I use a mouse scroll wheel, but for some reason it zooms instantly and not smoothly.
This is how I update the zoom:
[SerializeField, Range(10, 100)] float scrollSpeed = 10f;
[SerializeField] Vector2 zoomAmount = Vector2.zero;
private float ScrollWheel
{
get { return Input.GetAxis("Mouse ScrollWheel"); }
}
private new Camera camera = null;
void Update()
{
if (camera == null) return;
UpdateZoom();
}
void UpdateZoom()
{
pos = camera.transform.position;
pos = Vector3.Lerp(pos, new Vector3(pos.x, pos.y - scrollSpeed * 10 * ScrollWheel, pos.z), Time.deltaTime * 2);
pos.y = Mathf.Clamp(pos.y, zoomAmount.x, zoomAmount.y);
camera.transform.position = pos;
}
I think you're a little confused about Lerp
(I was confused in the same way too when I started using it). When you pass in a 0 for the time argument (the third argument), it will return your "starting" vector. When you pass a value of 1 or more for the time argument, it will return your "ending" vector. However, if you're passing Time.deltaTime * 2
, then you'll be returning approximately the same interpolated vector every frame. Lerp
doesn't "track" how far it's already interpolated, so by passing in the same time value every frame, Lerp
will never actually return your ending vector. So rather than passing Time.deltaTime * 2
, you'd need to do something like this
float interpolatedTime = 0;
void Update()
{
var myVector = Vector3.Lerp(vector1, vector2, this.interpolatedTime);
this.interpolatedTime += Time.deltaTime;
}
How about something like this for your camera:
float zoomTime;
float zoomTarget;
float lastScrollWheelDirection;
void Update()
{
// If this camera is currently zooming in and the player started zooming
// out (or vice versa), reset the amount that is remaining to be zoomed
if ((this.lastScrollWheelDirection > 0 && this.ScrollWheel < 0) ||
(this.lastScrollWheelDirection < 0 && this.ScrollWheel > 0))
{
this.zoomTarget = 0;
}
if (this.ScrollWheel != 0)
{
this.lastScrollWheelDirection = this.ScrollWheel;
}
// zoomTarget is the total distance that is remaining to be zoomed.
// Each frame that the scroll wheel is moved, we'll add a little more
// to the distance that we want to zoom
zoomTarget += this.ScrollWheel * this.scrollSpeed;
// zoomTime is used to do linear interpolation to create a smooth zoom.
// Each time the player moves the mouse wheel, we reset zoomTime so that
// we restart our linear interpolation
if (this.ScrollWheel != 0)
{
this.zoomTime = 0;
}
if (this.zoomTarget != 0)
{
this.zoomTime += Time.deltaTime;
// Calculate how much our camera will be moved this frame using linear
// interpolation. You can adjust how fast the camera zooms by
// changing the divisor for zoomTime
var translation = Vector3.Lerp(
new Vector3(0, 0, 0),
new Vector3(0, this.zoomTarget, 0),
zoomTime / 4f); // see comment above
// Zoom the camera by the amount that we calculated for this frame
this.transform.position -= translation;
// Decrease the amount that's remaining to be zoomed by the amount
// that we zoomed this frame
this.zoomTarget -= translation.y;
}
}