Skip to content
Agung Smaraputra
All Articles

Ever Wanted to Stop Time (or Slow It Down) in Your Unity Game? Here's How!

Implementing time manipulation mechanics in Unity using Time.timeScale, unscaled time, and custom time systems for pause menus and slow-motion effects.

January 11, 2025UnityMedium
Read on Medium (opens in new tab)
Ever Wanted to Stop Time (or Slow It Down) in Your Unity Game? Here's How!

Introduction

Imagine creating epic "Matrix-style" slow-mo effects or freezing the action entirely for dramatic moments. Controlling time in Unity is not just cool, it's incredibly simple! Here are two different ways to master time control.

Stopping Time Instantly

Unity's Time.timeScale lets you freeze all time-based processes (movement, physics, animations). Perfect for pause menus or dramatic story pauses! Below is a code snippet of how to stop and resume time instantly.

using UnityEngine;

public class TimeController : MonoBehaviour
{
    private bool isTimeStopped = false;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) // Press Space to toggle time
        {
            if (isTimeStopped)
                ResumeTime();
            else
                StopTime();
        }
    }

    void StopTime()
    {
        Time.timeScale = 0; // Instantly freeze time
        isTimeStopped = true;
        Debug.Log("Time stopped!");
    }

    void ResumeTime()
    {
        Time.timeScale = 1; // Instantly resume time
        isTimeStopped = false;
        Debug.Log("Time resumed!");
    }
}

Gradually Slowing Time

Want smoother, cinematic effects? Gradually reduce Time.timeScale to create dramatic slow-mo sequences before freezing the action entirely! Below is a code snippet of how to gradually slow and resume time.

using UnityEngine;
using System.Collections;

public class TimeController : MonoBehaviour
{
    private Coroutine timeCoroutine;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) // Press Space to toggle slow-mo
        {
            if (timeCoroutine != null)
                StopCoroutine(timeCoroutine);

            if (Mathf.Approximately(Time.timeScale, 1f))
                timeCoroutine = StartCoroutine(ChangeTimeScale(1f, 0f, 1f)); // Slow time over 1 second
            else
                timeCoroutine = StartCoroutine(ChangeTimeScale(Time.timeScale, 1f, 1f)); // Resume time over 1 second
        }
    }

    IEnumerator ChangeTimeScale(float start, float end, float duration)
    {
        float elapsed = 0f;

        while (elapsed < duration)
        {
            Time.timeScale = Mathf.Lerp(start, end, elapsed / duration);
            elapsed += Time.unscaledDeltaTime; // Use unscaledDeltaTime to remain consistent even when time is slowed
            yield return null;
        }

        Time.timeScale = end;
        Debug.Log($"Time scale set to {end}.");
    }
}

Pro Tips

  • Sync your audio! Adjust AudioSource.pitch or use AudioListener.pause for a more immersive experience.
  • For dramatic action, set targetTimeScale = 0.1f instead of 0 to keep the game in slow-mo rather than fully stopping it.
  • Combine both methods for ultimate flexibility in your game design!