【Input System】長押しで連射扱いにするInteraction【Unity】

Input System サムネ

Input Actionにボタンを長押しするとボタンを連射しているかのように振る舞うInteraction「Long Pressed Rapdfire」を追加します。下記コードをコピーし、LongPressedRapidfireInteraction.csファイルに上書きしてご使用ください。

配布

using UnityEngine;
using UnityEngine.InputSystem;

#if UNITY_EDITOR
using UnityEditor;
#endif

/// <summary>
/// ボタン長押しで連射扱いにするInteractionクラス
/// </summary>
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public class LongPressedRapidfireInteraction : IInputInteraction
{
#if UNITY_EDITOR
    static LongPressedRapidfireInteraction()
    {
        Initialize();
    }
#endif

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

    [Tooltip("連射と判断する間隔")]
    public float duration = 0.2f;
    [Tooltip("ボタンを押したと判断するしきい値")]
    public float pressPoint = 0.5f;


    public void Process(ref InputInteractionContext context)
    {

        //連射判断タイミングの処理
        if (context.timerHasExpired)
        {
            context.Canceled();
            if (context.ControlIsActuated(pressPoint))
            {
                context.Started();
                context.Performed();
                context.SetTimeout(duration);
            }
            return;
        }

        switch (context.phase)
        {
            case InputActionPhase.Waiting:
                //入力受付状態になった時
                if (context.ControlIsActuated(pressPoint))
                {
                    //実行状態にする
                    context.Started();
                    context.Performed();
                    //連射の振る舞いをするタイミング
                    context.SetTimeout(duration);
                }
                break;

            case InputActionPhase.Performed:

                if (!context.ControlIsActuated(pressPoint))
                {
                    //ボタンが離れたらキャンセルにする。
                    context.Canceled();
                    return;
                }

                break;
        }
    }

    public void Reset()
    {

    }
}

内容

ボタンを長押しするとボタンを連射している時に発生するコールバックと全く同じように何度もコールバックを渡します。具体的には以下のようになっています。

Startedボタンが押された瞬間、以後Durationタイムごと
Performedボタンが押された瞬間、以後Durationタイムごと
CanceledDurationタイムごと、ボタンが離れた瞬間

使い方

コードをプロジェクトに配置すると、Input ActionのInteractionの項目にLong Pressed Rapidfireが追加されるので、使用したいアクション・Composite・コントロールの右の+ボタンを押してください。

Unity InputSystem LongPressedRapidfire Interaction1
Unity InputSystem LongPressedRapidfire Interaction2
Duration連射と判断する間隔
Press Pointボタンを押したと判断するしきい値

Press Pointは、本当はProject SettingのPress Pointから取得したいのですが、方法が分かりません。そのあたりのクラスが全てご存知の方がいましたら教えてくださるとありがたいです。

コードの説明

Interactionの基本的な拡張方法は以下のページをご確認ください。


        if (context.timerHasExpired)
        {
            context.Canceled();
            if (context.ControlIsActuated(pressPoint))
            {
                context.Started();
                context.Performed();
                context.SetTimeout(duration);
            }
            return;
        }

本コードの肝はtimerHasExpiredです。本来はSetTimeoutは時間が来たらフェーズがWaitingになるのですが、この段階でボタンを押し続けている場合はすぐに開始処理を行っています。さらに、SetTimeoutを再実行しているため、また指定時間になるとこの処理を通るわけです。

関連リンク

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です