|
using System; |
|
using UnityEngine.Events; |
|
using UnityEngine.EventSystems; |
|
|
|
namespace UnityEngine.UI |
|
{ |
|
public class RepeatButton : Selectable, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerClickHandler |
|
{ |
|
[SerializeField] private float interval = 0.1f; |
|
[SerializeField] private float delay = 1.0f; |
|
[SerializeField] private UnityEvent onInvoke = new UnityEvent(); |
|
|
|
private bool isPointDown = false; |
|
private float lastInvokeTime; |
|
|
|
private float delayTime = 0f; |
|
|
|
public UnityEvent OnInvoke => onInvoke; |
|
|
|
// Use this for initialization |
|
protected override void Start() |
|
{ |
|
base.Start(); |
|
delayTime = delay; |
|
} |
|
|
|
protected override void OnDisable() |
|
{ |
|
base.OnDisable(); |
|
|
|
isPointDown = false; |
|
delayTime = delay; |
|
} |
|
|
|
void Update() |
|
{ |
|
if (!IsInteractable() && isPointDown) |
|
{ |
|
isPointDown = false; |
|
delayTime = delay; |
|
|
|
return; |
|
} |
|
|
|
if (isPointDown) |
|
{ |
|
if ((delayTime -= Time.deltaTime) > 0f) |
|
{ |
|
return; |
|
} |
|
|
|
if (Time.time - lastInvokeTime > interval) |
|
{ |
|
Invoke(); |
|
lastInvokeTime = Time.time; |
|
} |
|
} |
|
} |
|
|
|
private void Invoke() |
|
{ |
|
if (!IsActive() || !IsInteractable()) |
|
return; |
|
|
|
onInvoke.Invoke(); |
|
} |
|
|
|
public virtual void OnPointerClick(PointerEventData eventData) |
|
{ |
|
if (eventData.button != PointerEventData.InputButton.Left) |
|
return; |
|
|
|
Invoke(); |
|
} |
|
|
|
public override void OnPointerDown(PointerEventData eventData) |
|
{ |
|
base.OnPointerExit(eventData); |
|
|
|
isPointDown = true; |
|
delayTime = delay; |
|
|
|
if (IsInteractable()) |
|
{ |
|
DoStateTransition(SelectionState.Pressed, false); |
|
} |
|
} |
|
|
|
public override void OnPointerUp(PointerEventData eventData) |
|
{ |
|
base.OnPointerExit(eventData); |
|
|
|
isPointDown = false; |
|
delayTime = delay; |
|
|
|
DoStateTransition(currentSelectionState, false); |
|
} |
|
|
|
public override void OnPointerExit(PointerEventData eventData) |
|
{ |
|
base.OnPointerExit(eventData); |
|
|
|
isPointDown = false; |
|
delayTime = delay; |
|
|
|
DoStateTransition(currentSelectionState, false); |
|
} |
|
|
|
[Serializable] |
|
public class ButtonRepeatEvent : UnityEvent { } |
|
} |
|
} |