Understanding Time.deltaTime in Unity

When developing games in Unity, you’ll often come across a powerful and essential tool called Time.deltaTime. If you inspect any code written for a Unity game you will see this used often. If you’re new to Unity, this might seem like just another piece of jargon. However, understanding Time.deltaTime is crucial for creating smooth and consistent gameplay experiences, especially in games where motion and physics play a big role.

In this blog post, we’ll explore what Time.deltaTime is, why it’s important, and how to use it effectively. We’ll also look at what happens when you don’t use Time.deltaTime in your scripts.


What is Time.deltaTime?

Time.deltaTime represents the amount of time (in seconds) that has elapsed since the last frame was rendered. In other words, it tells you how long the previous frame took to complete.

So if you have a variable for the movement speed for your player, you are effectively translating the movement speed per frame, into movement speed per second.

Games usually run at varying frame rates due to differences in the player’s hardware or the computer workload, Time.deltaTime helps you account for these variations. By using it in your scripts, you can ensure that game behavior, such as movement or animation, remains consistent regardless of frame rate fluctuations.


Why is Time.deltaTime Important?

Games typically aim to run at a smooth 60 frames per second (FPS) or higher. However, depending on the complexity of your game or the power of the player’s hardware, the frame rate might drop below this target. Without accounting for these fluctuations, your game could behave unpredictably. For example:

  • At 60 FPS, each frame lasts approximately 0.0167 seconds (1 second / 60 frames).
  • At 30 FPS, each frame lasts approximately 0.0333 seconds (1 second / 30 frames).

If you’re moving an object by a fixed amount per frame, the object will move slower on systems running at higher frame rates and faster on systems with lower frame rates. Time.deltaTime solves this problem by allowing you to scale movements and actions based on the actual time elapsed between frames.


Using Time.deltaTime in Movement

Let’s look at a simple example: moving an object forward. Here’s how the code might look without using Time.deltaTime:

using UnityEngine;

public class MoveObject : MonoBehaviour
{
    [SerilazeField] private float speed = 5f;

    private void Update()
    {
        transform.Translate(Vector3.forward * speed);
    }
}

What Happens Without Time.deltaTime?

In this script, the object moves forward by speed units every frame. At 60 FPS, the object moves 300 units per second (5 units * 60 frames). At 30 FPS, it moves only 150 units per second (5 units * 30 frames). This inconsistency creates a noticeable difference in gameplay.

Fixing the Problem with Time.deltaTime

Here’s how you should implement the movement:

using UnityEngine;

public class MoveObject : MonoBehaviour
{
    [SerializeField] private float speed = 5f;

    private void Update()
    {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}

Now, the movement is frame rate independent. The object moves forward by speed units per second, regardless of how many frames are rendered during that second.


How Does Time.deltaTime Work?

Time.deltaTime adjusts the value you multiply by based on the time it takes to render each frame:

  1. At 60 FPS, Time.deltaTime is approximately 0.0167 seconds.
  2. At 30 FPS, Time.deltaTime is approximately 0.0333 seconds.

By multiplying speed by Time.deltaTime, you ensure that the movement happens at a consistent rate. For example:

  • At 60 FPS: 5 (speed) * 0.0167 (deltaTime) = 0.0835 units per frame.
  • At 30 FPS: 5 (speed) * 0.0333 (deltaTime) = 0.1665 units per frame.

In both cases, the object moves 5 units per second.


Other Use Cases for Time.deltaTime

1. Rotations

Time.deltaTime is also helpful for smooth rotations. For example:

private void Update()
{
    transform.Rotate(Vector3.up, 90f * Time.deltaTime);
}

This script rotates the object around the Y-axis at 90 degrees per second, regardless of frame rate.

2. Physics Simulations

When applying forces or velocities in physics calculations, Time.deltaTime ensures consistency. For instance:

private void Update()
{
    Vector3 velocity = new Vector3(0, -9.8f, 0);
    transform.position += velocity * Time.deltaTime;
}

This script simulates gravity, applying a downward velocity of 9.8 units per second.

3. Animations

Custom animations can use Time.deltaTime to interpolate values over time. For example:

private void Update()
{
    float scale = Mathf.Lerp(transform.localScale.x, 2f, Time.deltaTime);
    transform.localScale = new Vector3(scale, scale, scale);
}

What Happens If You Don’t Use Time.deltaTime?

Not using Time.deltaTime can lead to:

  1. Inconsistent Gameplay: Actions like movement, rotations, and animations will vary based on the player’s hardware and frame rate.
  2. Unpredictable Physics: Without Time.deltaTime, forces and velocities won’t account for frame time, causing erratic behavior.
  3. Poor User Experience: Players with lower frame rates may find the game sluggish, while those with higher frame rates might experience overly fast actions.

Common Mistakes When Using Time.deltaTime

1. Multiplying Multiple Times

Avoid applying Time.deltaTime more than once in a single calculation. For example:

speed = speed * Time.deltaTime; // Incorrect
transform.Translate(Vector3.forward * speed * Time.deltaTime); // Incorrect

2. Using Time.deltaTime Outside Update or FixedUpdate

Time.deltaTime is best used in Update or FixedUpdate, as these methods are called every frame or fixed time step, respectively. Using it elsewhere may yield unexpected results. That said, placing it in a function that is called from Update is fine. For example :

private void Update()
{
   HandleMovement()
}

private void HandleMovement() 
{
  // This is fine if only called from Update
  transform.Translate(Vector3.forward * speed * Time.deltaTime);
}

FixedUpdate vs. Update

Unity provides two main methods for updating your game logic:

  1. Update: Called every frame. Use Time.deltaTime here for frame-dependent calculations, such as input handling or non-physics-based movement.
  2. FixedUpdate: Called at a fixed interval. Use Time.fixedDeltaTime here for physics-based calculations, as Unity’s physics engine updates at a consistent rate.

Example:

void FixedUpdate()
{
    Vector3 velocity = new Vector3(0, -9.8f, 0);
    transform.position += velocity * Time.fixedDeltaTime;
}

Conclusion

Time.deltaTime is a simple but essential tool in Unity that ensures consistent and smooth gameplay across different frame rates. By integrating it into your scripts, you can:

  • Normalize movement, rotations, and animations.
  • Maintain predictable physics simulations.
  • Enhance the overall player experience.

Whether you’re building a simple platformer or a complex 3D shooter, Time.deltaTime is your ally for frame rate independence. Mastering its use will make you a more effective and versatile game developer.

Happy coding!