Batting a thousand:Unityのイベント駆動型Input Systemが『Backyard Baseball 2026』のコントロールにもたらすパワー

これは、Mega Cat StudiosがUnityの専門知識と、実際の商用ゲーム開発の課題に対するソリューションを共有するブログ記事シリーズの第2弾です。Matthew Wojtechko氏は、Unityのイベント駆動型Input Systemパッケージを活用して応答性を向上させ、非効率的なポーリングを削減する方法について考察しています。
シリーズの最初の投稿をお読みください:Unityワークフローのスケーリング:中規模プロジェクトから大規模プロジェクトまでのレッスン
入力は、ゲームを開始するときに最初に実装することが多く、それには正当な理由があります。キャラクターの移動やメニューの操作ができない場合は、それ以外は関係ありません。しかし 、 " just get it working" 入力コードには恒久的になる癖があります。ポーリングの単純な数行として始まったものが、再バインド可能なコントロールやローカルMultiplayerなどの実際の要件が到着すると、静かに崩れる脆弱なコードベースになることがあります。
Mega Cat Studiosでは、フレームごとの定数チェック(ポーリング)から、イベント駆動型のワークフローへと移行しました。『ファイブ・ナイト・アット・フレディーズ』のジャンプスケア反応のQTEを開発しているかどうか:Backyard Baseball 2026のピットまたはローカルMultiplayerでは、UnityのInput Systemパッケージを活用することで、ゲームプレイの応答性とメンテナンス性を維持できます。
次のような機能は、入力のプログラミング中にトップオブマインドでないとサポートが面倒になります。
- 複数の入力デバイス(キーボード、コントローラー、タッチ)
- 再バインド可能なコントロール
- ゲームプレイ入力と戦わないUIナビゲーション
- ローカルMultiplayer
- タイミング重視のゲームプレイ
この記事では、Input Systemを使用してこれらの問題を解決する方法を順を追って説明します。途中、アーキテクチャ、つまりプロジェクトをスケール可能にするものや、それ自体のウェイトで崩れがちなものについてお話しします。
UnityのInput Systemが進化しました。我々もだ
Unityが2020年に新しいInput Systemをリリースしたとき、それは古い機能であるInput.GetAxisと入力.GetButtonDownの単なる変身ではありません。イベント駆動型でデバイス非依存、プレイヤーの意図に焦点を当てた入力とは根本的に異なるアプローチです。以下は内部化したコアコンセプトです。
アクション
アクションは基本要素です。『バックヤード・ベースボール2026』では、次のような形になっている。
- アクションマップは入力コンテキストを表します。
- ゲームプレイ
- メニュー
- デバッグ/開発者ツール
- アクションはプレイヤーの意図です:
- ブランコ
- スライド
- 盗ベース
- 確認
- キャンセル
我々のゲームコードはデバイスではなく意図に語りかける。プレイヤーがスペースキーを押したのかも。あるいはPlayStationのコントローラーの十字ボタンを叩くとか。何があっても、プレイヤーコードは「Swing」アクションが実行されるタイミングだけを気にすればよいのです。そのレベルの抽象化が私たちの生活を楽にしてくれます。
バインディング
バインディングは、デバイスとアクションの具体的なマッピングであり、これにより、複数の制御スキームを特別に複雑にすることなくハンドルできます。1つのアクションで複数のデバイスからの複数の入力に反応できます。
こうすることで、コードを忘却に分岐させることなく、キーボード+マウス、コントローラー、タッチ、アクセシビリティのセットアップをサポートできます。Editorとランタイムでアクションを簡単に再バインドできます。これについては、後のセクションで詳しく探ります。
レスポンシブ性
従来の入力はポーリングに依存していました。
if (Input.GetButtonDown("Swing Bat"))
{
SwingBat();
}
簡単ですが、入力検出をフレームループに結びつけます。入力をフレームレートより速く押して離すと、見えないことがあります。
格闘、リズム、精密プラットフォーミングのジャンルのように素早い反応が求められるゲームでは、入力に一貫性がないとエクスペリエンスが台無しになる可能性があります。また、ペースの遅いゲームでも、バックヤードベースボール2026で打者が重要なスイングをするときのように、重要な場面で入力をドロップすると壊滅的な打撃を与える可能性があります。
Input Systemはイベントを中心に設計されている。一度登録すると、入力が発生するとUnityから通知されます。これにより、CPU オーバーヘッドが低減され、ロジックが簡素化され、入力漏れが問題にならなくなります。ボタンの押下やリリースから軸の変更まで、すべてがキューに入れられるため、入力が迷うことはありません。変数フレームレートやサブフレームレートレベルのスピードであっても、それらのイベントは順番に処理され、コールバックに確実に配信されます。
結果はどのようになったでしょうか。千本打つ入力。
ローカルマルチプレイヤー
ローカルMultiplayerはInput Systemが古い機能である入力マネージャに対して大きな利点をもたらす領域の1つです。
PlayerInputコンポーネントとコントロールスキームを使用すると、以下のようになります。
- 各プレイヤーは独自のアクションインスタンスを取得します。
- デバイスは動的にペアリングできます。
- 分割キーボード、複数のコントローラー、ハイブリッドセットアップは「ただ機能する」だけです。
重要なのは、プレイヤーコントロールが設計上分離されている点です。デバイスインデックス作成やプレイヤー間の入力競合が発生しなくなります。これは 、 『 Backyard Baseball 2026』でカウチ生協を実施した際、メガキャットチームにとって大きなメリットとなりました。
ローカルMultiplayerがプロジェクトにとって可能性さえあるのであれば、Input Systemパッケージから始めると、後で手直しする手間を大幅に省くことができるでしょう。

Input Systemを使用していても、開発者がポーリングを使用し続けることがあります。Keyboard.current.spaceKey.isPressedと他の設定を気にせず入力するだけでも、どこか魅力があります。特定のプロジェクトではこれで良いかもしれませんが、長期的にビルドを行う場合は、入力アクションコールバックをサブスクライブするほうが良いアプローチであることに注意してください。
スケールのための構造体

入力を読み取るのは簡単です。本当の課題は、さまざまなメニュー、ゲームプレイのモード、ゲームプレイシステムへの入力に適合するアーキテクチャを作成することです。
複数の出荷済みゲームで使用したパターンは以下の通りです。
- 入力コンテキストの分離:少なくとも、ほとんどのプロジェクトでは、次のようなメリットがあります。
- ゲームプレイマップ – プレイヤー移動、戦闘、インタラクション
- UIマップ – ナビゲーション、確認/キャンセル、スクロール
- デバッグマップ – コンソール切り替えやタイムスケーリングなどの開発専用ショートカット
なぜこれが問題なのか?入力リークを回避するためです。コンテキストを分けないと、例えばスペースキーを押すとメニューの確認とプレイヤーのジャンプの両方が行われるようなエッジケースを避けるのがずっと難しくなります。アクションマップでは、ゲームの状態の変化に応じて、入力コンテキスト全体を明示的に有効または無効にすることができます。入力漏れを実質的に問題としません。
- 中央入力マネージャ:Input System はオブジェクトごとの InputActionReference をサポートしますが、大規模なプロジェクトでは、単一の権威ある入力マネージャからメリットが得られます。優れた入力マネージャは通常、
- アクションマップのイネーブル化とディセーブル化
- 入力コールバックをサブスクライブする
- デバイス変更を処理する
- 入力とゲームプレイロジックの境界として動作
以下は簡単な例です。
public class GameInputManager : MonoBehaviour
{
public PlayerInput playerInput;
public PlayerController player;
private void OnEnable()
{
playerInput.actions["Jump"].performed += OnJump;
playerInput.actions["Shoot"].performed += OnShoot;
}
private void OnDisable()
{
playerInput.actions["Jump"].performed -= OnJump;
playerInput.actions["Shoot"].performed -= OnShoot;
}
private void OnJump(InputAction.CallbackContext context)
{
Player.Jump();
}
private void OnShoot(InputAction.CallbackContext context)
{
Player.Shoot();
}
}
多くのコードベースでは、ゲーム入力用のカスタムクラスを用意しています。このクラスには、文字列キー以外を指定することなくコールバックの登録と登録解除を行うことができる関数が含まれています。また、特定のシナリオで特定の入力のリスニングを停止できる優先システムも追加します。たとえば、前述の入力コンテキストです。このマネージャーを使用してプレイヤー入力をフックすると、次のようになります。
InputManager.Register(“Swing”, Priority.Character, SwingBat);
入力によって制御されるGameObjectは、それらを制御する入力ロジックから切り離されます。そうすることで、プロセスの後半でリファクタリングするコストが削減されると同時に、それを使用する開発者のコードも簡素化されます。
再結合を包含する
リバインド可能なコントロールはもはや贅沢な特徴ではありません。アクセシビリティ、デバイスの多様性、基本的なユーザーエクスペリエンスなどが求められます。
Mega Cat Studiosの私たちの多くは、入力の再バインディングを実装しているので、それがどれほど苦痛だったか知っています(そして、それが私たちのひげにグレーが少なからずある理由かもしれません ) 。幸いなことに、Input Systemパッケージは、この特徴をほぼ無料で提供してくれます。
InputActionRebindingExtensions.PerformInteractiveRebinding()が負荷の高い処理を行います。ゲームコードに配線するだけです。通常は、フロントエンドとバックエンドで懸念を分ける2つのスクリプトでこれを行います。
- RebindsManager
- 現在の操作を処理して、一度に1つのアクションのみ再バインドされるようにする
- 再バインド時のコールバックを無効にする
- 入力アクション参照を含む
- RebindActionUI
- 操作を開始および終了するインタラクションを処理します
- 入力を再マップする各UIパネルに添付
「当初、これにはマネージャーがなかったため、UIスクリプトだけでインタラクションと再バインド操作の両方を処理していました」と、Backyard Baseball 2026の開発者であるSofia Nacional氏は言います。「これにより、スケールせず、複数のアクティブな再バインド操作を同時に行うことができました」
バックエンドで入力を適切に整理することで、正面のものもプレイヤーが自由にカスタマイズできるようになります。入力コンテキストの例を見てみましょう。野球の試合では、選手の行動はバッティング、ピッチング、フィールディング、ベースランニングという明確なフェーズで発生します。では、プレイヤーが「スイングバット」と「盗塁」の両方にボタンをバインドすることは許されています。これは、同じシナリオでこの2つのアクションが発生することはないからです。入力コンテキストを使用すると、複数の入力アクションが発生する問題のあるバインディングを防ぎながら、適切な複製バインディングを容易に許可できます。
入力はシステム
チームが犯す最大の間違いは、入力をコアゲームシステムではなく実装の詳細として扱うことです。入力はすべてに影響します。ゲームプレイの感触、UIの操作性、長期的なメンテナンス性です。小さなものをプロトタイピングしたり出荷したりすると、MonoBehavioursに埋もれた分散ポーリングから逃れられるかもしれません。しかし、ゲームにスケールが必要な場合は、堅牢なものが必要です。
ビデオゲーム開発者として、私たちはプレイヤーのために働きます。プレイヤーに仕事を適切に行うためのツールを与えることが私たちの仕事です!イベント駆動型アーキテクチャを採用することで、コードを最適化するだけでなく、プレイヤーのコントロールを苛立たせるバグからゲームを保護し、可能な限り最高のエクスペリエンスを提供します。
