【Input System】Interaction~ダブルクリック・長押し・タップなど条件を付加【Unity】

Input System サムネ

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

Interactionとは

InteractionはInputActionを設定する際のオプション項目の一つで、「タップしたら」、「ダブルクリックしたら」等の動作する条件を設定します。入力デバイスから信号が届いたタイミングは、ここで設定する条件を満たすことで新たなタイミングに変換し、出力します。

条件はアクション毎、及び各デバイスごとに設定できます。タッチスクリーンやモバイルデバイスにのみタッチ系の条件を付加したり、例えばあるミニゲームで10秒以上HOLDしなければいけないみたいな条件はアクションに設定して全てのデバイスに適用できます。

具体的にはコールバックの変更処理を行っています。

ボタンを押す・離すなどの動作が行われるとstarted、performed、canceledなどのコールバックが発生します。併せて発生と同時にPhaseが変更します。この、コールバックやPhaseが変更するタイミングを変更する機能がInteractionです。

Interaction未使用時のコールバック

Startedボタンが押された瞬間
Performedボタンが離れた瞬間
Canceledボタンが離れた瞬間

デフォルトのInteraction

デフォルトでは5つのInteractionが用意されています。デフォルトはボタン、十字キー、タッチスクリーンなど全ての入力デバイスに対応しています。説明では便宜上ボタンとしていますが、他のデバイスにも当てはまります。

Press(押す)

ボタン押下状態を条件に見たします。何も条件を指定していない場合は常に条件を満たしているのに対し、この条件が付加されているとボタンを押した瞬間、離した瞬間を感知します。

新しいInput System Interaction Press

Press Pointはボタンを押す強さのしきい値です。

  • Trigger BehaviorがPress Onlyの時、ボタンが押された瞬間
  • Trigger BehaviorがRelease Onlyの時、ボタンが離れた瞬間
  • Trigger BehaviorがPress and Releaseの時、ボタンが押された瞬間と離れた瞬間。

Press Onlyの時のコールバック

Startedボタンが押された瞬間
Performedボタンが押された瞬間
Canceledボタンが離れた瞬間

Release Onlyの時のコールバック

Startedボタンが押されてた瞬間
Performedボタンが離れた瞬間
Canceledボタンが離れた瞬間

Press and Releaseの時のコールバック

Startedボタンが押された瞬間
Performedボタンが押された瞬間
ボタンが離れた瞬間
Canceledボタンが離れた瞬間

Hold(長押し)

ボタンを押し続けた時に条件を満たします。

新しいInput System Interaction Hold

HoldTime秒押し続けてから発生し、押す強さのしきい値はPress Pointになります。

コールバック

Startedボタンが押された瞬間
Performedボタンが押されてからHoldTime秒後
CanceledHoldTimeに関係なくボタンが離れた瞬間

Tap(タップ)

ボタンを押してから指定時間以内にボタンを離した時に条件を満たします。

ボタンを押した瞬間から換算し、Max Tap Duration秒以内にボタンを離した場合に発生します。押す強さのしきい値はPress Pointになります。

コールバック

Startedボタンが押された瞬間
Performedボタンが押されてからMax Tap Duration以内にボタンが離れた瞬間
Canceledボタンを押してからMax Tap Duration後も押し続けられた瞬間

Slow Tap(長押し後に離す)

ボタンを押してから一定時間経過後にボタンを離した時に条件を満たします。

ボタンを押した瞬間から換算し、Min Tap Duration秒以後にボタンを離した場合に発生します。押す強さのしきい値はPress Pointになります。

コールバック

Startedボタンが押された瞬間
Performedボタンを押されてからMin Tap Duration後にボタンが離れた瞬間
Canceledボタンを押されてからMin Tap Duration秒以前にボタンが離された瞬間

Multh Tap(ダブルクリック・連打)

ダブルクリックや連打が行われると条件を満たします。

TapCount回ボタンが押された場合に条件を満たします。ただし、以下の条件になるとキャンセルします。

  • ボタンを離してから再度押すまでの間にMax Tap Spacing秒を越えている。
  • ボタンを押してから離すまでの間にMax Tap Duration秒を越えている。

コールバック

Startedボタンが押される
Performedボタンが押された後、Max Tap Duration秒以内にボタンが離れた瞬間。以後、ボタンが押されるたびにコールバックが発生。
Canceledボタンが押されてからMax Tap Duration秒を越えた瞬間
ボタンが離れてから再度押されるまでMax Tap Spacing秒を越えた瞬間。

自作Interactionを追加する

Interactionは、自作して追加することがで簡単にできます。以下は、左・上ボタンを押して次に右・下ボタンを押したら感知するインタラクションです。

using UnityEngine;
using UnityEngine.InputSystem;

#if UNITY_EDITOR
using UnityEditor;
using UnityEngine.InputSystem.Editor;
#endif

#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public class MyInteraction : IInputInteraction
{
#if UNITY_EDITOR
    static MyInteraction()
    {
        Initialize();
    }
#endif

    [RuntimeInitializeOnLoadMethod]
    static void Initialize()
    {
        InputSystem.RegisterInteraction<MyInteraction>();
    }

    public float duration = 0.2f;

    public void Process(ref InputInteractionContext context)
    {
        //タイムアウトした場合の処理
        if (context.timerHasExpired)
        {
            context.Canceled();
            return;
        }

        switch (context.phase)
        {
            case InputActionPhase.Waiting:
                //入力受付状態になった時
                if (context.ReadValue<float>() == 1)
                {
                    context.Started();
                    context.SetTimeout(duration);

                }
                break;

            case InputActionPhase.Started:
                //入力開始後
                if (context.ReadValue<float>() == -1)
                    context.Performed();
                break;
        }
    }

    public void Reset()
    {
    }

#if UNITY_EDITOR
    public class MyInteractionEditor : InputParameterEditor<MyInteraction>
    {
        public override void OnGUI()
        {
            target.duration = EditorGUILayout.FloatField("間隔", target.duration);
        }

    }
#endif
}

UNITY InputSystem 自作Interaction1

Interactions横の+にMy が追加され、選択すると独自のインタレクションが選択できます。では、順番に見ていきます。

クラス宣言と事前読み込み

public class MyInteraction : IInputInteraction

自作インタレクションはIInputInteractionインターフェースを継承します。タイトルは「~Interaction」にすると、InputActionは~の部分をタイトルにします。

[InitializeOnLoad]
~
    static MyInteraction()
    {
        Initialize();
    }

    [RuntimeInitializeOnLoadMethod]
    static void Initialize()
    {
        InputSystem.RegisterInteraction<MyInteraction>();
    }

自作インタレクションをInput Systemに登録しています。InitializeOnLoadを利用することにより、エディタ起動時に処理が走ります。

Process

重要なのは上記にも書きましたが、Interactionsの役割はコールバックを発生するタイミングの調整です。適切な場所で以下の3つを定義してあげる必要があります。この定義を行うメソッドがProcessです。

Processは入力デバイスから値の変化があった時に呼ばれます。例えばボタンならボタンが押された瞬間・ボタンが離れた瞬間の2回のみ呼ばれます。その中から、以下の3つのメソッドを呼ぶことによって、使用者側のコールバックが発生するタイミングを調節できます。

Started()started()のコールバックが発生し、PhaseがStartedに変化
Performed()performed()のコールバックが発生し、PhaseがPerformedに変化
Canceled()canceled()のコールバックが発生し、PhaseがCanceledに変化。Canceled後は自動的にWaitingに変わります。
PerformedAndGoBackToWaiting()performed()のコールバックが発生し、PhaseがWaitingに変化。
PerformedAndStayPerformed()performed()のコールバックが発生し、PhaseがPerformedに変化。
PerformedAndStayStarted()performed()のコールバックが発生し、PhaseがStartedに変化。

使用例

context.Started()

サンプルはcontext.phoseがどの状態かを見て判断しています。phoseは以下の状態を持ちます。

  • Disabled:利用できない時
  • Waiting:待機状態
  • Started:ボタンを押した瞬間
  • Performed:ボタンを押した瞬間
  • Canceled:ボタンを離した瞬間

上記の例で言えば、上、又は右ボタンを押した時にStartedになり、0.2秒以内に左、下ボタンを押すとPerformedになります。しかし、0.2秒以内に押さなければCanceledを通ったのち、再びWaitingになります。

もう少し拡張すれば左右連打を扱うような処理が書けそうですね。

timerHasExpiredとSetTimeout

    public void Process(ref InputInteractionContext context)
    {
        //タイムアウトした場合の処理
        if (context.timerHasExpired)
        {
            context.Canceled();
            return;
        }

        context.SetTimeout(0.2f);
    }

SetTimeoutを実行することで、時間を過ぎた後にコントロールの変化が無くてもProcessが呼び出されます。その場合、timerHasExpiredがtrueになって帰ってきます。

ただし、時間が来る前にPerformedが実行された場合は、処理が無効化します。

ControlIsActuated

今回はReadValueで直接の値を利用していますが、通常はしきい値をInspectorから受け取り、context.ControlIsActuated()を利用してボタン押下の強さのしきい値を対応させます。ボタンが押された時にTrueを返しますが、引数に入力のしきい値を入れることが可能です。

if (context.ControlIsActuated(0.5f))
{
    context.Started();
}

Reset

例えば、ボタンを押してすぐ離すとPerformedになるようなInteractionを作ったとします。するとPerformedを止めるタイミングがありません。そのため、止めるための処理を記述します。

    public bool flg = false;
    public void Process(ref InputInteractionContext context)
    {
        switch (context.phase)
        {
            case InputActionPhase.Started:
                flg = true;
                break;
            case InputActionPhase.Performed:
                if (flg == false)
                {
                    context.Canceled();
                }
                break;
        }
    }

    public void Reset()
    {
        flg = false;
    }

他にも、長押しすると連射と判断するInteractionを公開していますので、参考にどうぞ。

関連リンク

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

コメントを残す

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

CAPTCHA