MIG.LegacyInputApi

UnityEngine.Input still called while the backend is New Input System only

Warning Migration Report only — manual fix

UnityEngine.InputInput.GetKey, Input.GetAxis, Input.mousePosition — only works while the old input backend is enabled. Under Active Input Handling: Input System Package (New) the old API throws, but it still compiles, so there is no build error to catch it. What you get instead, at the moment that line first runs:

InvalidOperationException: You are trying to read input using the UnityEngine.Input class,
but you have switched active Input handling to Input System package in Player Settings.

Which is a clear message — if that code path runs while you’re looking. It’s the call sites that only execute on a gamepad, in a rarely-visited menu, or inside a package you didn’t write that ship broken.

What the scan looks at

The project’s Active Input Handling setting, and — only when it’s set to new system only — calls to the legacy UnityEngine.Input API in runtime scripts, reported per file and line.

The related project-level finding is MIG.InputBackendBoth: Both backends enabled at once. That’s reported at Info, because “Both” is a legitimate and common migration state — it just means you’re paying for both systems and haven’t finished the move.

Why it’s easy to miss

Nothing surfaces in the places people check before shipping: the compiler is happy, the editor may behave differently from a player build depending on when the setting changed, and third-party packages in your project may call the old API without you knowing. The exception is per-call-site and lazy — it fires the first time that specific line runs, so coverage of the bug equals coverage of your playtesting. On a device, with no console open, the symptom is just “controls dead”, which points nowhere near the setting that caused it.

How to fix it by hand

Per call site, the mapping is conceptual rather than mechanical:

// Old
if (Input.GetKeyDown(KeyCode.Space)) Jump();
float h = Input.GetAxis("Horizontal");

// New Input System — actions are assets, bound in an .inputactions file
if (jumpAction.WasPressedThisFrame()) Jump();
float h = moveAction.ReadValue<Vector2>().x;

The steps that matter:

  1. Create an Input Actions asset, define your actions and bindings there rather than in code.
  2. Replace polling with either the generated C# class, PlayerInput callbacks, or direct action reads.
  3. For a quick unblock, Keyboard.current/Mouse.current from UnityEngine.InputSystem give you a device-level API that maps closely to the old calls — usable as a stepping stone, not a destination.
  4. Audit third-party packages, which are a common source of leftover legacy calls you can’t edit.
  5. If you need to ship before the migration is done, set Active Input Handling to Both temporarily. It costs a little overhead and buys a working build.

What PerfLint does about it

Report-only, and explicitly not AI-fixable — a deliberate line. Input migration is not a rename: the new system replaces polling with actions and bindings, so a fragment-level substitution would produce code that compiles and doesn’t work. The finding locates every legacy call so you can scope the real migration, and reports the backend setting so you know which mode you’re actually in.

Check your own project. The scan is free, runs entirely on your machine, and reports this rule with the exact assets that trip it — nothing is uploaded.

Install the free scanner See a sample report


Last reviewed · All rules