Unityの入力システム「 Input System」で使用するCompositeのオプション項目「Composite」の解説とデフォルトの機能、及び自作する方法を解説します。
Table of Contents
Compositeとは
CompositeはInputActionを設定する際のオプション項目の一つで、2つ以上のバインドをまとめて、左右の移動、ボタン同時押しなどの条件を満たすことで新しい出力結果を実現する機能です。

Binding
1つの入力デバイスキーを1つだけ割り当てます。Compositeを使わず純粋なバインディング処理です。
1D Axis Composite
Positive、Negativeの2つのキーを割り当て、片方はマイナスを掛けます。左右の移動キー、上下の移動キーなど対になっている操作を想定しています。

ReadValueの値
- Negativeに割り当てたキーの入力があった場合は-1を掛けて出力
- Positiveに割り当てたキーの入力があった場合はそのまま出力
- NegativeとPositiveに割り当てたキーから同時に入力があり、Which Side Wins = Positiveだった場合は、Positiveを出力
- NegativeとPositiveに割り当てたキーから同時に入力があり、Which Side Wins = Negativeだった場合は、Negativeに-1を掛けて出力
- NegativeとPositiveに割り当てたキーから同時に入力があり、Which Side Wins = Neitherだった場合は、(Min Value + Max Value) / 2を出力
EvaluateMagnitudeの値
- 値が(Min Value + Max Value) / 2未満の場合は値 – ((Min Value + Max Value) / 2)の絶対値を0とMin Valueの絶対値の間でノーマライズ化
- 値が(Min Value + Max Value) / 2より大きい場合は値 – ((Min Value + Max Value) / 2)の絶対値を0とMax Valueの絶対値の間でノーマライズ化
ノーマライズの方法はProcessorのNormalizeと同じ手法を用いています。
Button With One Modifier Composite
ボタンの同時押しを想定したComposite。

ReadValueの値
Modifierに値がある時に、Buttonの値を出力します。
EvaluateMagnitudeの値
ReadValueと同じ
Button With Two Modifiers Composite
ボタンの3つ同時押しを想定したComposite

ReadValueの値
Modifier1とModifier2が共に値がある時に、Buttonの値を出力します。
EvaluateMagnitudeの値
ReadValueと同じ
2D Vector Composite
Up、Down、Left、Rightの4つのキーを割り当て、Down・Leftはマイナスを掛けます。四方向の移動を想定しています。

ReadValueの値
- Mode = Analogの場合、(Rightボタン – Leftボタン, Upボタン – Downボタン)
- Mode = Degital,Degital Normalizedの場合、それぞれのボタンに値があれば1、なければ0で(Rightボタン – Leftボタン, Upボタン – Downボタン)
EvaluateMagnitudeの値
ReadValueにVectorw.magnitudeを行った値。
自作Compositeを追加する
Compositeは、自作して追加することがで簡単にできます。以下は、入力キー6つでVector3を取得するCompositeです。ついでにInspectorで各方角の速度を変更します(本来速度は入力システム側でいじるものではありませんが(^^;)。
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.Utilities;
#if UNITY_EDITOR
using UnityEditor;
#endif
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
[DisplayStringFormat("{up}/{left}/{down}/{right}/{front}/{back}")]
public class MyComposite : InputBindingComposite<Vector3>
{
#if UNITY_EDITOR
static MyComposite()
{
Initialize();
}
#endif
[RuntimeInitializeOnLoadMethod]
static void Initialize()
{
InputSystem.RegisterBindingComposite<MyComposite>();
}
[InputControl(layout = "Button")] public int up = 0;
[InputControl(layout = "Button")] public int down = 0;
[InputControl(layout = "Button")] public int left = 0;
[InputControl(layout = "Button")] public int right = 0;
[InputControl(layout = "Button")] public int front = 0;
[InputControl(layout = "Button")] public int back = 0;
public float xSpeed = 1f;
public float ySpeed = 1f;
public float zSpeed = 1f;
public override Vector3 ReadValue(ref InputBindingCompositeContext context)
{
return new Vector3(xSpeed * (right - left), ySpeed * (up - down), zSpeed * (back - front));
}
public override float EvaluateMagnitude(ref InputBindingCompositeContext context)
{
return ReadValue(ref context).magnitude;
}
}

アクションのControlTypeがVector3の時、アクション項目横の+にMy が追加され、独自のCompositeが選択できます。では、順番に見ていきます。
public class MyComposite : InputBindingComposite<Vector3>
自作プロセッサーはInputBindingCompositeを継承します。タイトルは「~Composite」にすると、InputActionは~の部分をタイトルにします。型を指定することで、その型のOperand Systemにしか対応しないことを明示します。
今回の場合はVector3のため、アクションのControlTypeがVector3のアクション以外は選択できません。
[InitializeOnLoad]
~
static MyComposite()
{
Initialize();
}
[RuntimeInitializeOnLoadMethod]
static void Initialize()
{
InputSystem.RegisterBindingComposite<MyComposite>();
}
自作CompositeをInput Systemに登録しています。InitializeOnLoadを利用することにより、エディタ起動時に処理が走ります。
[DisplayStringFormat("{up}/{left}/{down}/{right}/{front}/{back}")]
public class MyComposite : InputBindingComposite<Vector3>
{
[InputControl(layout = "Button")] public int up = 0;
~
public float xSpeed = 1f;
~
}
変数はPublicやシリアライズしたPrivateなどはInspector入力項目に追加されます。また、InputControlを宣言した変数に関しては入力デバイスからの受付変数となります。
InputControlで宣言した変数はInputActionアセットの画面から入力を受け取れるようにしなければいけません。そのための宣言はクラス名の上のDisplayStringFormat属性で行います。ここで入力してもらう順に(“{変数名}/{..}..”}に記載することで、実際の画面に入力デバイス欄が出現します。
public override Vector3 ReadValue(ref InputBindingCompositeContext context)
{
return new Vector3(xSpeed * (right - left), ySpeed * (up - down), zSpeed * (back - front));
}
ReadValueに出力する値を記述します。
public override float EvaluateMagnitude(ref InputBindingCompositeContext context)
{
return ReadValue(ref context).magnitude;
}
EvaluateMagnitudeに出力する値を記述します。contextは上記ReadValue(ref Context)とすることで上記ReadValueの値を取得します。