Skip to content

Instantly share code, notes, and snippets.

@Shilo
Last active September 7, 2020 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shilo/29a3cbd994ba81dd4ae607adc24cae5e to your computer and use it in GitHub Desktop.
Save Shilo/29a3cbd994ba81dd4ae607adc24cae5e to your computer and use it in GitHub Desktop.
Unity class to handle pointer click events.
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);
}
}
}
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