オプション画面の「ジャンプ: Space [変更]」というあのボタン——キーコンフィグは、今どきのPCゲームではあって当たり前の機能です。そして「プレイヤーがキーを差し替えられる」ことこそ、New Input System を選ぶ最大の理由のひとつ。ところがいざ作ろうとすると、「押されたキーをどう待ち受ける?」「変更をどう保存する?」と手が止まりがちです。
この記事では、New Input Systemの PerformInteractiveRebinding() を使ったリバインド実装を、仕組み(Bindingの上書き)→ 基本実装 → UI連携 → 保存・復元の順で解説します。
この記事でわかること
- リバインドの正体は「Bindingの上書き(override)」であること
PerformInteractiveRebinding()による「次の入力を待って差し替える」実装- 変更したキーの表示・変更待ち状態などUIとの連携
SaveBindingOverridesAsJsonによる保存と起動時の復元
仕組み:リバインド=Bindingの上書き
New Input Systemでは、「ジャンプ」というアクションと「Spaceキー」という Binding(割り当て) が分離されています。リバインドとは、このBindingを書き換えること——正確には、元の定義はそのままに、上書き(override)を被せることです。

元の定義(Input Action Assetに保存されたSpace)は消えません。上書きシールを貼るようにoverridePathが優先されるだけなので、シールを剥がせばいつでもデフォルトに戻せます。この構造が、後述の「リセット機能」や「保存のしやすさ」に直結しています。
基本実装:PerformInteractiveRebinding
「変更ボタンを押す → 次に押されたキーを待つ → そのキーで上書きする」という一連の流れを、PerformInteractiveRebinding()が丸ごと引き受けてくれます。

using UnityEngine;
using UnityEngine.InputSystem;
public class RebindController : MonoBehaviour
{
[SerializeField] private InputActionReference jumpAction; // ジャンプのアクション
private InputActionRebindingExtensions.RebindingOperation rebindOperation;
public void StartRebind()
{
// 1. リバインド中に反応しないよう、対象アクションを無効化
jumpAction.action.Disable();
// 2. 「次の入力」を待ち受けて上書きする操作を開始
rebindOperation = jumpAction.action.PerformInteractiveRebinding()
.WithControlsExcluding("Mouse") // マウス操作は候補から除外
.WithCancelingThrough("<Keyboard>/escape") // Escapeでキャンセル
.OnComplete(operation => FinishRebind()) // 確定時
.OnCancel(operation => FinishRebind()) // キャンセル時
.Start();
}
private void FinishRebind()
{
// 3. 後片付け(Disposeを忘れるとメモリリークの原因に)
rebindOperation.Dispose();
jumpAction.action.Enable();
}
}
押さえるべきポイントは3つです。
- 開始前に
Disable(): 有効なまま始めると、リバインド中の入力にアクション自体が反応してしまいます WithCancelingThrough: 「やっぱりやめた」用のキャンセルキーを必ず用意します- 完了・キャンセルどちらでも
Dispose(): リバインド操作は使い捨てのオブジェクトです。後片付けとEnableを共通の後処理にまとめると漏れません
注意: アクションに複数のBindingがある場合(例:ジャンプに「Space」と「ゲームパッドの南ボタン」の2つ)、無指定の
PerformInteractiveRebinding()では 意図しない側のBindingを書き換えてしまう ことがあります。実戦ではPerformInteractiveRebinding(bindingIndex)のように どのBindingを変更するかを必ず指定 しましょう。WASDのようなコンポジットBindingでは必須です(おまけ参照)。
UIと連携する
実際の設定画面では、「現在のキー表示」と「変更待ち状態の表示」が必要です。現在の割り当てはGetBindingDisplayString()で人間向けの表記(「Space」「Left Button」など)が取れます。
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class RebindButtonUI : MonoBehaviour
{
[SerializeField] private InputActionReference jumpAction;
[SerializeField] private TextMeshProUGUI keyLabel; // ボタン上のキー名表示
private bool isRebinding; // 二重開始を防ぐフラグ
private void Start()
{
RefreshLabel();
}
public void RefreshLabel()
{
// 現在の割り当てを「Space」のような表示用文字列で取得
keyLabel.text = jumpAction.action.GetBindingDisplayString();
}
public void OnClickRebind()
{
// ボタン連打で2つ同時にリバインドを始めない
if (isRebinding) return;
isRebinding = true;
keyLabel.text = "..."; // 変更待ち状態の表示
jumpAction.action.Disable();
jumpAction.action.PerformInteractiveRebinding()
.WithControlsExcluding("Mouse")
.WithCancelingThrough("<Keyboard>/escape")
.OnComplete(op => { op.Dispose(); jumpAction.action.Enable(); isRebinding = false; RefreshLabel(); })
.OnCancel(op => { op.Dispose(); jumpAction.action.Enable(); isRebinding = false; RefreshLabel(); })
.Start();
}
}
ボタンのOnClickにOnClickRebindを繋げば、「クリック → 表示が ... に変わる → キーを押すと新しいキー名になる」という定番の挙動が完成します。
保存と復元
上書きはあくまで実行中のメモリ上の状態なので、ゲームを終了すると消えます。保存にはSaveBindingOverridesAsJson()を使います。上書き情報だけがJSON文字列になるので、PlayerPrefs にそのまま入れられます。
using UnityEngine;
using UnityEngine.InputSystem;
public class RebindSaveLoad : MonoBehaviour
{
[SerializeField] private InputActionAsset actions; // Input Action Asset全体
private const string SaveKey = "rebinds";
// 設定画面を閉じるときなどに呼ぶ
public void SaveRebinds()
{
string json = actions.SaveBindingOverridesAsJson();
PlayerPrefs.SetString(SaveKey, json);
}
// ゲーム起動時に呼ぶ
private void Awake()
{
string json = PlayerPrefs.GetString(SaveKey, string.Empty);
if (!string.IsNullOrEmpty(json))
{
actions.LoadBindingOverridesFromJson(json);
}
}
// 「デフォルトに戻す」ボタン用
public void ResetRebinds()
{
actions.RemoveAllBindingOverrides();
PlayerPrefs.DeleteKey(SaveKey);
}
}
「上書きだけを保存する」設計のおかげで、保存・復元・リセットがそれぞれ数行で済みます。冒頭の「上書きシール」のイメージそのままです。
なお、アップデートでアクションやBindingの構成を変えたあとに古い保存データを読み込むと、期待と違う割り当てになることがあります。凝った移行処理を作り込むより、 「デフォルトに戻す」ボタンを設定画面に置いておく のが、いちばんシンプルで確実な保険になります。
おまけ:先に知っておくと良いこと
基本のリバインドが動いたら、次はこのあたりが課題になってきます。
- WASD(コンポジット)のリバインド: 移動のようなWASD4方向の割り当ては「コンポジットBinding」で、上下左右それぞれの部分Bindingを個別にリバインドします。
PerformInteractiveRebinding(bindingIndex)のように対象インデックスの指定が必要です。 - 重複割り当てのチェック: 「ジャンプも攻撃もEキー」を許すかはゲーム次第です。許さない場合は
OnComplete時に他アクションのBindingと比較し、重複していたら上書きを取り消す処理を足します。 - ゲームパッドとの共存: キーボード用とゲームパッド用のBindingは別々に存在します。リバインド候補を絞りたいときは
WithControlsExcludingや、対象スキームの指定を活用しましょう。New Input Systemの基礎から確認したい場合は 入門記事 へ。
まとめ
キーコンフィグは、New Input Systemなら「仕組みに乗るだけ」で実装できます。
- リバインドの正体は Bindingの上書き(override)。元の定義は残るので、いつでもデフォルトに戻せる。
PerformInteractiveRebinding()が「次の入力を待って差し替える」流れを丸ごと担当。開始前のDisable()、キャンセルキー、Dispose()の3点セットを忘れずに。- 現在のキー表示は
GetBindingDisplayString()。変更待ちは表示を差し替えるだけで実現できる。 - 保存は
SaveBindingOverridesAsJson+ PlayerPrefs、復元は起動時にLoadBindingOverridesFromJson、リセットはRemoveAllBindingOverrides。
「キー変更できて当たり前」の時代に、この実装がそのまま自分のゲームの設定画面になります。ぜひ組み込んでみてください。