はじめに
CyberAgent Developers Advent Calendar 2018 その2 の12日目の投稿です。
株式会社サムザップの尾崎です。
開発中タイトルのリンクスリングスでUnityエンジニアしています。
内容
リンクスリングスのボタン長押しのためのコンポーネントを紹介したいと思います。
Unityは標準でボタンをタップしたときに処理を行う機能を提供していますが、長押ししたときに処理する機能は提供されていません。
そのため新規にコンポーネントを作成しました。
キャラクターや武器のアイコンを長押ししたときに詳細画面を表示するところなどで使用しています。
実装
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UniRx;
namespace Linqs.UI
{
[AddComponentMenu("Linqs/UI/LongPressTrigger")]
public class LongPressTrigger : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public float Duration = 0.5f;
public UnityEvent OnLongPressDown = new UnityEvent();
public UnityEvent OnLongPressUp = new UnityEvent();
private bool _pressed;
private float _pressedTime;
private IDisposable _disposable;
public void OnPointerDown(PointerEventData eventData)
{
_pressed = true;
if (_disposable == null)
{
_disposable = Observable.EveryUpdate().Subscribe(i =>
{
if (_pressed)
{
_pressedTime += Time.deltaTime;
if (_pressedTime >= Duration)
{
_pressed = false;
OnLongPressDown.Invoke();
}
}
}).AddTo(this);
}
}
public void OnPointerUp(PointerEventData eventData)
{
OnLongPressUp.Invoke();
_pressed = false;
_pressedTime = 0f;
_disposable.Dispose();
_disposable = null;
}
}
}
実装について
いくつか実装上のポイントがあります。
- Buttonクラスを継承せずに実装したコンポーネントになっていて、EventSystemのポインターイベントを受け取れるGameObjectなら長押しできます。(例. ToggleやImageなど)
- UnityEventを用いることでコードで処理を登録することも、インスペクタから登録することもできます。
- Update、コルーチンの代わりにUniRxのマイクロコルーチンを用いることでパフォーマンスを高めています。
スクリーンショット
動作環境
- Unity2018.2
- UniRx