Input Actionにボタンを長押しするとボタンを連射しているかのように振る舞うInteraction「Long Pressed Rapdfire」を追加します。下記コードをコピーし、LongPressedRapidfireInteraction.csファイルに上書きしてご使用ください。
Table of Contents
配布
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タイムごと |
Canceled | Durationタイムごと、ボタンが離れた瞬間 |
使い方
コードをプロジェクトに配置すると、Input ActionのInteractionの項目にLong Pressed Rapidfireが追加されるので、使用したいアクション・Composite・コントロールの右の+ボタンを押してください。
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を再実行しているため、また指定時間になるとこの処理を通るわけです。