LoginSignup
1
1

【Unity】UniTaskとUnityEventを用いたオリジナルな長押しボタンの紹介

Posted at

自己紹介

Plastic SCMばかりにファイルをあげていてもダメだなと思い始めてGitHubに公開できるものは公開しようと思い始めた大学生です。

今回の話題

今回はオリジナルなボタンを作るという趣旨ではなく、作ったものを紹介しながら問題点や気に入ってる点などを話します。
今回紹介する長押しボタンだけでなく少し作ったものを公開してみましたので是非ご覧ください。
(文字化けは許して)

長押しボタン

Unity標準のボタンにはない機能である長押しボタンを紹介します。

スクリプト

AtsuLongPressButton.cs
using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

public class AtsuLongPressButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    [SerializeField] private UnityEvent _longpressEvent;
    [SerializeField] private UnityEvent _pointerUpEvent;
    [SerializeField] private float _pressSecond;
    [SerializeField] private LocerlButton _button;

    private bool _isIvoked = false;
    private CancellationTokenSource _tokenSource;

    public async void OnPointerDown(PointerEventData eventData)
    {
        _tokenSource = new CancellationTokenSource();
        await LongPress(_tokenSource.Token);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        _tokenSource.Cancel();
        if(_isIvoked)
        {
            _isIvoked = false;
            _pointerUpEvent.Invoke();
        }
        else
        {
            if (_button != null) _button._isAbleIvoke = true;
        }
    }

    public async UniTask LongPress(CancellationToken _token)
    {
        await UniTask.Delay(TimeSpan.FromSeconds(_pressSecond));

        if (_token.IsCancellationRequested) return;

        _isIvoked = true;

        if (_button != null) _button._isAbleIvoke = false;

        _longpressEvent.Invoke();
    }
}

機能紹介

単純に長押したら一つのイベントが発火し、離したらもう一つのイベントが発火します。
このスクリプトと通常のボタン(AtsuButton.cs)を併用して使うことで、普通に押されたらシーン移行、長押しだったらシーンの詳細の表示、長押しをやめたときに詳細が非表示などを行うことができます。

問題点(?)

このスクリプトというかレポジトリにあるすべてのスクリプトに言えることなのですが、当たり前ですがボタンのテキストとイメージが別のものであるため、イメージを押していた際にテキストに手が触れるとキャンセルされるというバグがありました。そのため、ゲームオブジェクトの階層を少し複雑にしてあげないといけないという問題がありました。
しかし、テキストのRaycast Targetのチェックを外してあげることで解消するはずです。(要検証)

そもそも、Raycast Targetをオンにしておくと処理が少し重くなるので基本的にオフにしたほうが良いです。
解決しなくてもオフにしましょう…

まとめ

1年近く前に書いたスクリプトながらインターネットに今ある記事よりも圧倒的に使いやすいものになっていると自負しています。
コピペして使っていただいても大丈夫なのでいい感じに改変しながら使ってあげてください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1