インスペクターからInput SystemのActionを指定する時、直接指定なのかInput Action Assetの参照なのかを場面に応じて変える方法はないの?
InputActionProperty構造体を使えば良いわ。
Input SystemのActionをスクリプトから扱う際、インスペクターからActionを指定する方法は主に次の2通りが考えられます。
- Input Actionの設定内容を直接指定する
- Input Action Asset側で管理しているAction(参照)を指定する
両者はそれぞれデータの持ち方が別ですが、InputActionProperty構造体を使うと、同じスクリプトで動的にどちらの方法でActionを設定するかを切り替えることができます。
参考:Struct InputActionProperty| Input System | 1.5.1
InputActionProperty型として[SerializeField]などでフィールド定義すると、以下のようにインスペクターから指定方法を切り替えてActionを設定できるようになります。
本記事では、このInputActionPropertyの使い方について解説していきます。
- Unity 2022.2.16f1
- Input System 1.5.1
目次 非表示
前提条件
事前にInput Systemパッケージがインストールされ、有効化されているものとします。
ここまでの手順は以下記事で解説しています。
また、Input Action経由で入力を受け取ることとします。
Input Actionの基本的な使い方は以下記事で解説しています。
InputActionProperty構造体の使い方
次のようにフィールド定義するだけで使えます。
以下、InputActionProperty構造体をフィールドで定義し、ここからInputAction経由で入力を取得するサンプルです。
上記をInputActionPropertyExample.csという名前で保存し、適当なゲームオブジェクトにアタッチします。
すると、以下のようにインスペクターからActionを設定できるようになるため、お好みのActionを設定してください。
上記のようにUse Reference項目のチェックを外すと、Actionを直接スクリプト側で定義できるようになります。
Use Referenceにチェックを入れると参照モードとなり、Input Action AssetのActionのアタッチ(参照の指定)が可能になります。
例では、直接Actionを定義し、スペースキーが押されたらperformedコールバックが発火するBindingを定義してみます。
実行結果
指定されたActionのキーが押されるたびに、コンソールにログ出力されます。
参照モードで実行すると、次のようにInput Action Assetで定義したAction名がログ出力されます。
スクリプトの説明
まず、[SerializeField]属性などでInputActionProperty型をシリアライズ可能なフィールドとして定義します。
その後、上記のインスペクターから設定されたActionをInputActionインスタンスとして取得します。actionプロパティから取得できます。
未定義の場合もあり得るため、nullチェックも行っています。
InputActionインスタンスを無事に取得できたら、performedコールバックにメソッドを登録し、Actionを有効化します。
Actionの有効化を忘れると、performedコールバックに登録しても入力を受け取れない(コールバックが発火しない)のでご注意ください。
InputActionProperty構造体の仕様
InputActionProperty構造体の仕様は以下リファレンスに記載されています。
参考:Struct InputActionProperty| Input System | 1.5.1
基本的に、スクリプト中から扱うのは次のactionプロパティでしょう。
直接指定か参照指定かによって返すActionを内部的に振り分けてくれるため、使用側が特に意識する必要はありません。
また、referenceプロパティによってActionへの参照(InputActionReference型)を取得することも可能です。
ただし、参照モード(インスペクターからUse Referenceにチェックが入っている状態)でないと常にnullを返します。
InputActionProperty構造体の内部実装
内部的には次の3つのシリアライズ可能フィールドを持っています。
直接指定か参照指定かを示すフラグm_UseReferenceを持ち、それぞれの指定に応じた設定情報を両方保持しています。
直接指定の時はm_Actionフィールド、参照指定の時はm_Referenceフィールドが内部的に使用されます。
インスペクター上では、エディタ拡張(Property Drawer)によってm_UseReferenceフィールドの状態に応じて必要なフィールド(m_Actionかm_Referenceか)のみを設定可能になるように表示切り替えしています。
さいごに
InputActionPropertyをAction指定用のフィールドとして用いると、臨機応変にActionの指定方法を変えることができます。
スクリプトから単独のActionを指定する場合に活躍できるでしょう。
ただし、余分にフィールドを持つことになり、シリアライズされるデータサイズが増えることを念頭に置けば良いでしょう。