Last active
September 7, 2020 08:23
-
-
Save Shilo/29a3cbd994ba81dd4ae607adc24cae5e to your computer and use it in GitHub Desktop.
Unity class to handle pointer click events.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.Events; | |
using UnityEngine.EventSystems; | |
namespace Shilo | |
{ | |
public class PointerHandler : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler | |
{ | |
private UnityEvent _onLeftClick; | |
private UnityEvent _onMiddleClick; | |
private UnityEvent _onRightClick; | |
private bool _isPointerOver; | |
private bool _isLeftDown; | |
private bool _isMiddleDown; | |
private bool _isRightDown; | |
private float _leftContinuousDuration; | |
private float _middleContinuousDuration; | |
private float _rightContinuousDuration; | |
public bool ListenOnUpdate { get; set; } | |
public float ContinuousInterval { get; set; } | |
public float InitialContinuousInterval { get; set; } | |
public int InvokesPerEvent { get; set; } | |
public float InitialContinuousIntervalOffset | |
{ | |
get | |
{ | |
return InitialContinuousInterval - ContinuousInterval; | |
} | |
set | |
{ | |
InitialContinuousInterval = ContinuousInterval + value; | |
} | |
} | |
public UnityEvent OnLeftClick | |
{ | |
get | |
{ | |
if (_onLeftClick == null) _onLeftClick = new UnityEvent(); | |
return _onLeftClick; | |
} | |
} | |
public UnityEvent OnMiddleClick | |
{ | |
get | |
{ | |
if (_onMiddleClick == null) _onMiddleClick = new UnityEvent(); | |
return _onMiddleClick; | |
} | |
} | |
public UnityEvent OnRightClick | |
{ | |
get | |
{ | |
if (_onRightClick == null) _onRightClick = new UnityEvent(); | |
return _onRightClick; | |
} | |
} | |
public void OnPointerClick(PointerEventData pointerEventData) | |
{ | |
if (ListenOnUpdate || ContinuousInterval > -1) return; | |
if (pointerEventData.button == PointerEventData.InputButton.Left) | |
{ | |
if (_onLeftClick != null) InvokePointerEvent(_onLeftClick); | |
} | |
else if (pointerEventData.button == PointerEventData.InputButton.Right) | |
{ | |
if (_onRightClick != null) InvokePointerEvent(_onRightClick); | |
} | |
else if (pointerEventData.button == PointerEventData.InputButton.Middle) | |
{ | |
if (_onMiddleClick != null) InvokePointerEvent(_onMiddleClick); | |
} | |
} | |
public void OnPointerEnter(PointerEventData eventData) | |
{ | |
_isPointerOver = true; | |
} | |
public void OnPointerExit(PointerEventData eventData) | |
{ | |
_isPointerOver = false; | |
} | |
void Update() | |
{ | |
if (ListenOnUpdate || ContinuousInterval > -1) | |
{ | |
UpdateDown(); | |
UpdateContinuous(); | |
UpdateUp(); | |
} | |
} | |
void UpdateDown() | |
{ | |
if (_isPointerOver) | |
{ | |
if (Input.GetMouseButtonDown(0)) | |
{ | |
if (ContinuousInterval > -1) | |
{ | |
if (_onLeftClick != null) InvokePointerEvent(_onLeftClick); | |
_leftContinuousDuration = InitialContinuousInterval != 0 ? -InitialContinuousIntervalOffset : 0; | |
} | |
_isLeftDown = true; | |
} | |
if (Input.GetMouseButtonDown(1)) | |
{ | |
if (ContinuousInterval > -1) | |
{ | |
if (_onRightClick != null) InvokePointerEvent(_onRightClick); | |
_rightContinuousDuration = InitialContinuousInterval != 0 ? -InitialContinuousIntervalOffset : 0; | |
} | |
_isRightDown = true; | |
} | |
if (Input.GetMouseButtonDown(2)) | |
{ | |
if (ContinuousInterval > -1) | |
{ | |
if (_onMiddleClick != null) InvokePointerEvent(_onMiddleClick); | |
_middleContinuousDuration = InitialContinuousInterval != 0 ? -InitialContinuousIntervalOffset : 0; | |
} | |
_isMiddleDown = true; | |
} | |
} | |
} | |
void UpdateContinuous() | |
{ | |
if (_isPointerOver && ContinuousInterval > -1) | |
{ | |
if (_isLeftDown && Input.GetMouseButton(0)) | |
{ | |
_leftContinuousDuration += Time.deltaTime; | |
if (_leftContinuousDuration >= ContinuousInterval) | |
{ | |
if (_onLeftClick != null) InvokePointerEvent(_onLeftClick); | |
_leftContinuousDuration = 0; | |
} | |
} | |
if (_isRightDown && Input.GetMouseButton(1)) | |
{ | |
_rightContinuousDuration += Time.deltaTime; | |
if (_rightContinuousDuration >= ContinuousInterval) | |
{ | |
if (_onRightClick != null) InvokePointerEvent(_onRightClick); | |
_rightContinuousDuration = 0; | |
} | |
} | |
if (_isMiddleDown && Input.GetMouseButton(2)) | |
{ | |
_middleContinuousDuration += Time.deltaTime; | |
if (_middleContinuousDuration >= ContinuousInterval) | |
{ | |
if (_onMiddleClick != null) InvokePointerEvent(_onMiddleClick); | |
_middleContinuousDuration = 0; | |
} | |
} | |
} | |
} | |
void UpdateUp() | |
{ | |
if (_isLeftDown && Input.GetMouseButtonUp(0)) | |
{ | |
if (_isPointerOver && _onLeftClick != null && ContinuousInterval < 0) InvokePointerEvent(_onLeftClick); | |
_isLeftDown = false; | |
_leftContinuousDuration = 0; | |
} | |
if (_isRightDown && Input.GetMouseButtonUp(1)) | |
{ | |
if (_isPointerOver && _onRightClick != null && ContinuousInterval < 0) InvokePointerEvent(_onRightClick); | |
_isRightDown = false; | |
_rightContinuousDuration = 0; | |
} | |
if (_isMiddleDown && Input.GetMouseButtonUp(2)) | |
{ | |
if (_isPointerOver && _onMiddleClick != null && ContinuousInterval < 0) InvokePointerEvent(_onMiddleClick); | |
_isMiddleDown = false; | |
_middleContinuousDuration = 0; | |
} | |
} | |
void InvokePointerEvent(UnityEvent pointerEvent) | |
{ | |
int i = 0; | |
do | |
{ | |
if (pointerEvent != null) pointerEvent.Invoke(); | |
i++; | |
} while (i < InvokesPerEvent); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.Events; | |
namespace Shilo | |
{ | |
class Utils | |
{ | |
public enum PointerEventType | |
{ | |
Left, | |
Right, | |
Middle | |
} | |
public static void AddPointerListener(GameObject gameObj, UnityAction call, PointerEventType pointerEventType = PointerEventType.Left, float continuousInterval = -1, float initialContinuousInterval = 0, int invokesPerEvent = 0, bool listenOnUpdate = true) | |
{ | |
if (!gameObj) return; | |
PointerHandler pointerHandler = gameObj.GetComponent<PointerHandler>(); | |
if (pointerHandler == null) pointerHandler = gameObj.AddComponent<PointerHandler>(); | |
pointerHandler.ListenOnUpdate = listenOnUpdate; | |
pointerHandler.ContinuousInterval = continuousInterval; | |
pointerHandler.InitialContinuousInterval = initialContinuousInterval; | |
pointerHandler.InvokesPerEvent = invokesPerEvent; | |
UnityEvent pointerEvent; | |
if (pointerEventType == PointerEventType.Right) | |
{ | |
pointerEvent = pointerHandler.OnRightClick; | |
} | |
else if (pointerEventType == PointerEventType.Middle) | |
{ | |
pointerEvent = pointerHandler.OnMiddleClick; | |
} | |
else | |
{ | |
pointerEvent = pointerHandler.OnLeftClick; | |
} | |
pointerEvent.RemoveAllListeners(); | |
pointerEvent.AddListener(call); | |
} | |
public static void RemoveAllPointerListeners(GameObject gameObj) | |
{ | |
PointerHandler pointerHandler = gameObj.GetComponent<PointerHandler>(); | |
if (pointerHandler) | |
{ | |
if (pointerHandler.OnLeftClick != null) pointerHandler.OnLeftClick.RemoveAllListeners(); | |
if (pointerHandler.OnRightClick != null) pointerHandler.OnRightClick.RemoveAllListeners(); | |
if (pointerHandler.OnMiddleClick != null) pointerHandler.OnMiddleClick.RemoveAllListeners(); | |
UnityEngine.Object.Destroy(pointerHandler); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment