Выделение UI кнопки Unity
Как в Unity сделать так, чтобы кнопка при одиночном клике слала событие OnClick(она по умолчанию это делает и так), а если удерживаешь её более 3х секунд - слала событие OnSelected, а при повторном "отжатии" на 3 секунды - слала событие OnDeseleсted?
Фактически аналогичный функционал есть у иконок в меню андроида - тыкаешь 1 раз - запускается приложение, жмешь 3 секунды не отпуская - открывается меню удаления или чего либо еще, жмешь на уже выделенную кнопку 3 секунды - состояние сбрасывается на стартовое.
Возможно в UI нет встроенной поддержки такого, тогда может быть, кто то написал велосипед для такого?
Ответы (1 шт):
Здесь особо ничего сложного нет, вы вполне можете написать свою реализацию, используя интерфейсы IPointerDownHandler и IPointerUpHandler, методы которых вызываются EventSystem при взаимодействие с UI-ем. Если вам нужно прям кнопку расширить, а не дополнительный скрипт сделать - пишите свой класс, наследуйтесь от Button и переопределяйте методы OnPointerDown и OnPointerUp - там совсем всё просто, что-нибудь вроде:
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DelayedButton : Button
{
public UnityEvent OnSelectedEvent = new UnityEvent();
public UnityEvent OnDeselectedEvent = new UnityEvent();
[SerializeField]
float _delay = 3;
Coroutine _waitRoutine;
ButtonState _state = ButtonState.Idle;
public override void OnPointerDown(PointerEventData eventData)
{
base.OnPointerDown(eventData);
_waitRoutine = StartCoroutine(WaitRoutine());
}
public override void OnPointerUp(PointerEventData eventData)
{
if (_waitRoutine != null)
{
StopCoroutine(_waitRoutine);
_waitRoutine = null;
}
if (_state == ButtonState.Selected)
OnDeselectedEvent?.Invoke();
_state = ButtonState.Idle;
base.OnPointerUp(eventData);
}
IEnumerator WaitRoutine()
{
yield return new WaitForSeconds(_delay);
_state = ButtonState.Selected;
OnSelectedEvent.Invoke();
_waitRoutine = null;
}
enum ButtonState
{
Idle,
Selected
}
}