【Input System】Composite~ボタン同時押しや移動キーなど【Unity】

Input System サムネ

Unityの入力システム「 Input System」で使用するCompositeのオプション項目「Composite」の解説とデフォルトの機能、及び自作する方法を解説します。

Compositeとは

CompositeはInputActionを設定する際のオプション項目の一つで、2つ以上のバインドをまとめて、左右の移動、ボタン同時押しなどの条件を満たすことで新しい出力結果を実現する機能です。

Unity InputSystem Composite

Binding

1つの入力デバイスキーを1つだけ割り当てます。Compositeを使わず純粋なバインディング処理です。

1D Axis Composite

Positive、Negativeの2つのキーを割り当て、片方はマイナスを掛けます。左右の移動キー、上下の移動キーなど対になっている操作を想定しています。

Unity InputSystem Composite 1d Axis

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。

Unity InputSystem Composite Button With One Modifier

ReadValueの値

Modifierに値がある時に、Buttonの値を出力します。

EvaluateMagnitudeの値

ReadValueと同じ

Button With Two Modifiers Composite

ボタンの3つ同時押しを想定したComposite

Unity InputSystem Composite Button With Two Modifier2

ReadValueの値

Modifier1とModifier2が共に値がある時に、Buttonの値を出力します。

EvaluateMagnitudeの値

ReadValueと同じ

2D Vector Composite

Up、Down、Left、Rightの4つのキーを割り当て、Down・Leftはマイナスを掛けます。四方向の移動を想定しています。

Unity InputSystem Composite 2D Vector

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;
    }
}
Unity InputSystem 独自のComposite

アクションの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の値を取得します。

関連リンク

参考 【Unity】Input Systemの紹介と解説 トップページゲーム開発65535 Ver2 参考 【Unity】Input Systemの紹介ゲーム開発65535 Ver2 参考 【Unity】Input Systemの基本的な使い方ゲーム開発65535 Ver2

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA