untangle-puzzlegame/Library/PackageCache/com.unity.inputsystem@e2c83221d2dc/Documentation~/timing-mixed-scenarios.md
2025-04-17 17:33:08 -04:00

3.6 KiB
Raw Permalink Blame History

Mixed timing scenarios with fixed and dynamic input

There are some situations where you might set the Update Mode process in Dynamic Update even when using input code in FixedUpdate, to minimize input latency, as described in the previous section.

In this situation, for discrete events you must ensure that you use WasPressedThisFrame or WasReleasedThisFrame in Update, and pass through a variable to your FixedUpdate code to indicate the event happened. There may still be some latency between the frame in which the event occurred, and the next FixedUpdate call.

For example:

using UnityEngine;
using UnityEngine.InputSystem;

public class ExampleScript : MonoBehaviour
{
    InputAction jumpAction;
    bool jumpPressed;

    private void Start()
    {
        jumpAction = InputSystem.actions.FindAction("Jump");
    }

    private void Update()
    {
        // read discrete jump pressed event here:
        if (jumpAction.WasPressedThisFrame())
        {
            // set this variable to true, for use in FixedUpdate
            jumpPressed = true;
        }
    }

    void FixedUpdate()
    {
        if (jumpPressed)
        {
            // apply jump physics here

            // set the variable to false so that the jump pressed physics are only applied once
            jumpPressed = false;
        }
    }
}

Minimum latency in mixed timing scenarios

A technique to give the user the feel of absolute minimum latency while still using FixedUpdate is to respond as fast as possible in Update giving some visual feedback, but also respond to that same input in FixedUpdate for your physics system code. For example, you could display the start of a "jump" animation immediately in Update, while applying physics to correspond with the "jump" animation in the next available FixedUpdate which might come slightly later.

In this scenario, set your Update Mode Process events in Dynamic Update which gives you the fastest response in your Update call. However for the reasons mentioned in the previous section, this might mean you miss discrete events if you use methods like WasPressedThisFrame in your FixedUpdate call. To avoid this problem, use a variable to pass through the pressed/released state of the discrete event from the event handler to your FixedUpdate call, and then clear it once your FixedUpdate code has acted on it. For example:

using UnityEngine;
using UnityEngine.InputSystem;

public class ExampleScript : MonoBehaviour
{
    InputAction jumpAction;
    bool jumpPressed;

    private void Start()
    {
        jumpAction = InputSystem.actions.FindAction("Jump");
    }

    private void Update()
    {
        // at high FPS, its fastest to read actions here:

        // read discrete jump pressed event here:
        if (jumpAction.WasPressedThisFrame())
        {
            // start jump animation here

            // set this variable to true, for use in FixedUpdate
            jumpPressed = true;

        }
    }

    void FixedUpdate()
    {
        if (jumpPressed)
        {
            // apply jump physics here

            // set the variable to false so that the jump pressed physics are only applied once
            jumpPressed = false;
        }
    }
}