Version: 2020.3
ScriptableObject
Important Classes - Mathf

Important Classes - Time and Framerate Management

The Time Class

Unity’s Time class provides a number of important basic properties which allow you to work with time-related values in your project.

The descriptions for each member of Time script reference page are self explanatory, and that is the best place to learn about them.

Listed here is a small selection of examples to provide an idea of the common and typical uses:

Time.time returns the amount of time since your project started playing.

Time.deltaTime returns the amount of time that elapsed since the last frame completed.

Time.timeScale represents the rate at which time elapses. You can read this value, or set it to control how fast time passes, allowing you to create slow-motion effects.

For the full list of time-related properties, see the Time script reference page.

The Update function allows you to monitor inputs and other events regularly from a script and take appropriate action. For example, you might move a character when the “forward” key is pressed. An important thing to remember when handling time-based actions like this is that the game’s framerate is not constant and neither is the length of time between Update function calls.

As an example of this, consider the task of moving an object forward gradually, one frame at a time. It might seem at first that you could just shift the object by a fixed distance each frame:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerFrame;
    
    void Update() {
        transform.Translate(0, 0, distancePerFrame); // this is incorrect
    }
}

However, given that the frame time is not constant, the object will appear to move at an irregular speed. If the frame time is 10 milliseconds then the object will step forward by distancePerFrame one hundred times per second. But if the frame time increases to 25 milliseconds (due to CPU load, say) then it will only step forward forty times a second and therefore cover less distance. The solution is to scale the size of the movement by the frame time which you can read from the Time.deltaTime property:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerSecond;
    
    void Update() {
        transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
    }
}

Note that the movement is now given as distancePerSecond rather than distancePerFrame. As the framerate changes, the size of the movement step will change accordingly and so the object’s speed will be constant.

Fixed Timestep (fixedDeltaTime)

Unlike the main frame update, Unity’s physics system does work to a fixed timestepA customizable framerate-independent interval that dictates when physics calculations and FixedUpdate() events are performed. More info
See in Glossary
, which is important for the accuracy and consistency of the simulation. At the start of the physics update, Unity performs as many physics updates as necessary to catch up with the current time.

If your game or app is running at a higher framerate than the fixed timestep value, it means each frame is less than the duration of a single fixed timesetp, so Unity will either perform one or zero fixed physics updates per frame. For example, if your fixed timestep value is 0.02, there should be 50 fixed updates per second. If your game or app then runs at approximately 60 frames per secondThe frequency at which consecutive frames are displayed in a running game. More info
See in Glossary
, there will occasionally be a frame where no fixed update occurs - in approximately one in ten frames.

If your game or app is running at a lower framerate than the fixed timestep value, it means each frame duration is longer than a single fixed timesetp. To account for this, Unity will perform one or more fixed updates each frame, so that the physics simulation “catches up” with the amount of time elapsed since the last frame. For example, if your fixed timestep value is 0.01, there should be 100 fixed updates per second. If your game or app then runs at approximately 25 frames per second, Unity will perform approximately four fixed updates every frame to keep the physics simulation time up-to-date with the current frame time.

You can change the duration of the fixed timestep in the Time window, and you can read it from a script using the Time.fixedDeltaTime property. Note that a lower value for the timestep will result in more frequent physics updates and more precise simulation but at the cost of greater CPU load. You probably won’t need to change the default fixed timestep unless you are placing high demands on the physics engineA system that simulates aspects of physical systems so that objects can accelerate correctly and be affected by collisions, gravity and other forces. More info
See in Glossary
that require extra high precision.

Unity’s Time Logic

The following flowchart illustrates the logic that Unity uses to count time in a single frame, and how the time, deltaTime, fixedDeltaTime, and maximumDeltaTime properties relate to each other.

Maximum Allowed Timestep (maximumDeltaTime)

When a very slow frame occurs, The Maximum Allowed Timestep (in the Time window) limits the value of deltaTime in the following frame to avoid undesirable side-effects from very large deltaTime values. This value is also accessible via scripting as Time.maximumDeltaTime.

For example, an application running at 60Hz with a maximumDeltaTime value of 0.333 that encounters a single very slow frame (2 seconds) would exhibit a behavior similar to that shown in the following table:

Frame unscaledTime time deltaTime smoothDeltaTime
1 0.000 3.000 0.014 0.014
2 0.014 3.015 0.014 0.014
3 0.028 3.028 0.014 0.014
4 (a) 0.042 3.043 0.014 0.014
5 2.062 (b) 3.376 (c) 0.333 (d) 0.078
6 2.082 3.396 0.020 0.066
7 2.096 3.410 0.014 0.056
8 2.110 3.424 0.014 0.048

The data above illustrates the effect of the maximum allowed timestep value (the maximumDeltaTime). It shows eight frames, numbered one to eight. During frame four in this example (a), there is a slow-down which causes the frame to take two seconds to complete, rather than around 25 milliseconds like the others. The effects of this are reflected in the values on the following frame. The pause is visible as increment of around 2 in the unscaledTime value (b), however the Time.time value only increments by 0.333 (c), because that is the value of maximum allowed timestep when this example was running. The deltaTime value for this frame is also clamped to the maximum allowed timestep (d).

The maximum allowed timestep value also affects the physics timekeeping. The fixed timestep keeps the physical simulation accurate in real time but it can cause problems in cases where the game makes heavy use of physics and the gameplay frame rate has also become low, for example due to a large number of objects in motion. The main frame update processing has to be “squeezed” in between the regular physics updates, and if there is a lot of processing to do then several physics updates might need to take place during a single frame to catch the physics simulation up with the current time. Since the frame time, positions of objects and other properties are frozen at the start of the frame, the graphics can get out of sync with the more frequently updated physics.

Limited CPU power means there is a limit to what the physics system can process, so Unity has an option to let you effectively slow down physics time to let the frame processing catch up if it falls behind. The maximum allowed timestep puts a limit on the amount of time Unity will spend processing physics and FixedUpdate calls during a given frame update.

If a frame update takes longer than Maximum Allowed Timestep to process, the physics engine will “stop time” and let the frame processing catch up. Once the frame update has finished, the physics resumes as though no time has passed since it was stopped. The result of this is that rigidbodiesA component that allows a GameObject to be affected by simulated gravity and other forces. More info
See in Glossary
will not move perfectly in real time as they usually do but will be slowed slightly. However, the physics “clock” will still track them as though they were moving normally. The slowing of physics time is usually not noticeable and is often an acceptable trade-off against gameplay performance.

Time Scale

For special effects, such as “bullet-time”, it is sometimes useful to slow the passage of game time so that animations and script responses happen at a reduced rate. Furthermore, you may sometimes want to freeze game time completely, as when the game is paused. Unity has a Time Scale property that controls how fast game time proceeds relative to real time. If the scale is set to 1.0 then game time matches real time. A value of 2.0 makes time pass twice as quickly in Unity (ie, the action will be speeded-up) while a value of 0.5 will slow gameplay down to half speed. A value of zero will make time “stop” completely. Note that the time scale doesn’t actually slow execution but simply changes the time step reported to the Update and FixedUpdate functions via Time.deltaTime and Time.fixedDeltaTime. The Update function is likely to be called more often than usual when game time is slowed down but the deltaTime step reported each frame will simply be reduced. Other script functions are not affected by the time scale so you can, for example, display a GUI with normal interaction when the game is paused.

The Time window has a property to let you set the time scale globally but it is generally more useful to set the value from a script using the Time.timeScale property:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    void Pause() {
        Time.timeScale = 0;
    }
    
    void Resume() {
        Time.timeScale = 1;
    }
}

Capture Framerate

A very special case of time management is where you want to record gameplay as a video. Since the task of saving screen images takes considerable time, the usual framerate of the game will be drastically reduced if you attempt to do this during normal gameplay. This will result in a video that doesn’t reflect the true performance of the game.

Fortunately, Unity provides a Capture Framerate property that lets you get around this problem. When the property’s value is set to anything other than zero, game time will be slowed and the frame updates will be issued at precise regular intervals. The interval between frames is equal to 1 / Time.captureFramerate, so if the value is set to 5.0 then updates occur every fifth of a second. With the demands on framerate effectively reduced, you have time in the Update function to save screenshots or take other actions:

//C# script example
using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    // Capture frames as a screenshot sequence. Images are
    // stored as PNG files in a folder - these can be combined into
    // a movie using image utility software (eg, QuickTime Pro).
    // The folder to contain our screenshots.
    // If the folder exists we will append numbers to create an empty folder.
    string folder = "ScreenshotFolder";
    int frameRate = 25;
        
    void Start () {
        // Set the playback framerate (real time will not relate to game time after this).
        Time.captureFramerate = frameRate;
        
        // Create the folder
        System.IO.Directory.CreateDirectory(folder);
    }
    
    void Update () {
        // Append filename to folder name (format is '0005 shot.png"')
        string name = string.Format("{0}/{1:D04} shot.png", folder, Time.frameCount );
        
        // Capture the screenshot to the specified file.
        Application.CaptureScreenshot(name);
    }
}

Although the video recorded using this technique typically looks very good, the game can be hard to play when slowed-down drastically. You may need to experiment with the value of Time.captureFramerate to allow ample recording time without unduly complicating the task of the test player.

ScriptableObject
Important Classes - Mathf