InControl: Pausing and Time Scale

Many games implement pausing by setting Time.timeScale to zero, which can pose a problem in certain cases. When Time.timeScale is zero, MonoBehaviour.FixedUpdate will not be called.

InControl is usually updated during MonoBehaviour.Update, so this is not a problem. Typically, you could implement pausing as simply as:

using System;
using UnityEngine;
using InControl;


public class PauseManager : MonoBehaviour
{
    bool isPaused = false;

    void Update()
    {
        if (InputManager.ActiveDevice.MenuWasPressed)
        {
            isPaused = !isPaused;
            Time.timeScale = isPaused ? 0.0f : 1.0f;
        }
    }
}

However, some games choose to do some or all of their input logic in MonoBehaviour.FixedUpdate and, in some cases, may choose to call InputManager.Update in MonoBehaviour.FixedUpdate.

As a brief aside, Unity updates its input just before MonoBehaviour.Update, so updating InControl more frequently will not yield much gain unless you’re using something like XInput, in which case updating more frequently with a higher FixedUpdate rate can yield higher input fidelity. The built-in InControlManager component has a setting to do so, if you wish.

If you do plan to update InControl inside FixedUpdate, be aware that when you pause the application with Time.timeScale set to zero, FixedUpdate will not be called, and thus InControl will not poll for input. You will need to call InputManager.Update in MonoBehaviour.Update, but only while paused or other input behavior will be affected (particularly, WasPressed, which is set only for the duration of a single update tick).

If you are using the InControlManager component to manage InControl, this will be handled for you.

Regardless of whether you are updating InControl on Update or FixedUpdate, you will need to do the unpause check in MonoBehaviour.Update.

It is highly recommended that you use the InControlManager component as it will be automatically updated to handle any other quirks and issues that may arise in the future, including other hooks into the application lifecycle which are likely to become necessary.

If you find that it does not meet some requirement or use case, please drop me a note as to why so the component can be updated to cover it if possible.

Below is a simplified overview of how you could handle the specific situation if, and only if, you are updating input on FixedUpdate. I’ve also marked the parts handled for you if you do use the InControlManager component.

using System;
using UnityEngine;
using InControl;


public class MyGameInputManager : MonoBehaviour
{
    bool isPaused = false;


    void OnEnable()
    {
        InputManager.Setup(); // Omit if using InControlManager
    }


    void Update()
    {
        if (isPaused)
        {
            InputManager.Update(); // Omit if using InControlManager

            if (InputManager.ActiveDevice.MenuWasPressed)
            {
                isPaused = false;
                Time.timeScale = 1.0f;
            }
        }
    }


    void FixedUpdate()
    {
        InputManager.Update(); // Omit if using InControlManager

        if (!isPaused && InputManager.ActiveDevice.MenuWasPressed)
        {
            isPaused = true;
            Time.timeScale = 0.0f;
        }
    }
}