Quick answer: The Input Actions editor needs an explicit Save Asset click (or Auto Save enabled) — File > Save All does not include it. After save, ensure Generate C# Class is checked so the wrapper regenerates. PlayerInput components only pick up bindings when the asset is reloaded; exit and re-enter Play mode if needed.

Here is how to fix Unity New Input System where you edit a .inputactions asset, change a binding, but the game continues using the old binding. The asset window seems to accept the change, the inspector shows it, yet input behaves as if nothing happened. Two distinct stages have to complete: saving the asset, and refreshing whatever holds a reference to it.

The Symptom

You add a new action or rebind an existing one in the Input Actions editor window. Press Play. The new binding does nothing; the old one still works. The asset file modification timestamp on disk is unchanged. Or, if you use a generated C# wrapper, the new action does not show up in autocomplete.

What Causes This

Save Asset not pressed. Edits in the Input Actions editor window stay in memory until you click Save Asset (or enable Auto Save). Standard Ctrl-S in the rest of Unity does not trigger this.

Generate C# Class not enabled. Without it, code-side wrappers are stale. References resolve to old method signatures.

PlayerInput holds old reference. A PlayerInput component caches a reference to the action map at start. Hot edits do not propagate.

Asset re-import skipped. If you copied a .inputactions file in via the file system without restarting Unity, the editor may not pick up the new bindings until reimport.

The Fix

Step 1: Save the asset. In the Input Actions editor window, click Save Asset (top-right). Or check Auto Save next to it so future edits save automatically.

Step 2: Enable Generate C# Class. Select the .inputactions asset in the Project window. In the inspector, check Generate C# Class. Set the file name (e.g., PlayerControls) and namespace, then click Apply. A C# file is generated alongside the asset.

// Generated wrapper usage
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    private PlayerControls controls;

    void Awake()
    {
        controls = new PlayerControls();
        controls.Player.Jump.performed += ctx => OnJump();
    }

    void OnEnable()  { controls.Player.Enable(); }
    void OnDisable() { controls.Player.Disable(); }

    void OnJump() { Debug.Log("Jumped"); }
}

Step 3: Refresh PlayerInput at runtime if needed.

playerInput.actions.Disable();
playerInput.actions.Enable();

This forces a re-resolution of bindings. Useful when you allow runtime rebinding and want the new binding to take effect immediately.

Step 4: Re-import the asset. If you copied the .inputactions file in externally, right-click in the Project window and choose Reimport. The editor reads the new content and regenerates the C# wrapper.

Step 5: Use Auto Save while iterating. Top-right of the Input Actions window, enable Auto Save. Every edit is committed to disk immediately. Tradeoff is no “cancel” option; if you do not want this, save manually.

Runtime Rebinding Persistence

If you let players rebind keys at runtime, persist the bindings via SaveBindingOverridesAsJson and reload via LoadBindingOverridesFromJson:

// Save
string json = playerInput.actions.SaveBindingOverridesAsJson();
PlayerPrefs.SetString("bindings", json);

// Load on next session
var json = PlayerPrefs.GetString("bindings", "");
if (!string.IsNullOrEmpty(json))
    playerInput.actions.LoadBindingOverridesFromJson(json);

“Save Asset is its own button. Generate C# Class regenerates on save. PlayerInput re-resolves on Disable/Enable. Three handles for one workflow.”

Related Issues

For control scheme switching, see Input System Control Scheme Switching. For inputs not arriving at all, see New Input System Actions Not Updating.

Click Save Asset. Generate C# Class. Disable/Enable to refresh. Bindings update.