Unity: Make the Camera Follow a Player (or any GameObject) Smoothly and Fluidly
Having the Camera follow the player character is a common requirement for many types of games, so I thought I’d share a helpful trick to ensure the camera follows the player smoothly and fluidly.
The basic premise of having a camera follow the player is to update the camera’s position each frame to match that of the player’s. However, this can lead to unpleasant jerks in camera positioning when the player moves very quickly (teleportation, for instance), or if the game’s frame-rate dips.
The approach I prefer is to move the camera gradually towards the player’s position using Mathf.Lerp.
What’s a Lerp?
The Lerp function takes two values, as well as an interpolation value between 0.0 and 1.0. As the documentation explains, when the interpolation value is 0.0, the first value is returned and when it’s 1.0 the second value is returned. However, if the interpolation value is somewhere between 0.0 and 1.0, an appropriate value between the two values is returned.
Consider the following examples:
Mathf.Lerp(10, 20, 0.5f); // Returns: 15.0f Mathf.Lerp(10, 20, 0.25f); // Returns 12.5f Mathf.Lerp(10, 20, 0.8f); // Returns 18.0f
If you’re curious, the formula looks like:
valueA + ((valueB - valueA) * interpolationValue)
So, How do we Lerp?
Lerp allows us to close the distance between two values, in our case the camera and player positions, gradually. It also means that the further the two points are from one another, the higher the value returned by Lerp will be, meaning we can move the camera more quickly the further away it is.
This gives us a really pleasant aesthetic with an elastic and fluid motion to close the gap between the two positions, and allows the player object to move slightly out of the center of the camera, with the camera moving to catch up with the player. Not only does present a much smoother motion, but it gives the player an additional sense of movement and control over their character.
Take a look at the sample below which demonstrates using Lerp on the y-axis:
While this example only demonstrates the y-axis, you could just as easily Lerp on the x-axis (or both simultaneously) as you’ll see below, depending on the type of game you’re making. You can also increase or decrease the speed at which the camera follows the player by adjusting the interpolation value - again, we’ll see this down below.
Let’s Code.
Alright so now that we know the general idea, let’s take a look at how this works in practice. We’ll create a standalone Follow script which, while intended for the camera and player in this case, can actually be applied to any GameObject to have it follow another.
using UnityEngine; using System.Collections; public class Follow : MonoBehaviour { public GameObject objectToFollow; public float speed = 2.0f; void Update () { float interpolation = speed * Time.deltaTime; Vector3 position = this.transform.position; position.y = Mathf.Lerp(this.transform.position.y, objectToFollow.transform.position.y, interpolation); position.x = Mathf.Lerp(this.transform.position.x, objectToFollow.transform.position.x, interpolation); this.transform.position = position; } }
How it works is by using the attached GameObject’s position (in our case it’s the Camera), and the position of the objectToFollow (the player), as well as a speed value. The value of speed* isn’t used directly tough, we instead multiply it by Time.deltaTime to create a smooth, frame-rate independent player following system.
Each frame, we update the current GameObject’s transform.position with the new x and y values returned by Mathf.Lerp.
With the Follow script written this way, we can add it to the Camera or any other GameObject, adjust the speed accordingly, and instantly create a smooth and fluid effect of following any GameObject in the Scene!