上一篇中提到一種鼠標按下時的事件觸發,即采用eventtrigger設定pointerdown和pointerup並綁定相應事件。但是若要實現持續按鍵則需要對綁定的每個方法都添加實現持續按鍵方法。所以在此通過unityevent來簡化過程。
(一)unityevent
unityevent為unity自定義的unity事件,需要與委托unityaction(它需要添加到event的監聽中使用)。
以下為例:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class UniytEventTest : MonoBehaviour { UnityAction action; [SerializeField] UnityEvent actionEvent = new UnityEvent(); public void OnTest01() { print("test01"); } public void OnTest02() { print("test02"); } // Use this for initialization void Start () { action = new UnityAction(OnTest01); action += OnTest02; if (action != null) { actionEvent.AddListener(action); } actionEvent.Invoke(); } // Update is called once per frame void Update () { } }
首先unityevent的特性聲明
[SerializeField]
表示此事件會出現在unity中的面板上,可以綁定事件,否則不可以。定義好事件以后就可以通過invoke方法激活一次。在此多說明一點,若通過代碼綁定方法,unityaction默認為無參數的,若果需要帶參數則需要通過泛型unityaction<T>來實現
(二)持續按鍵
通過unityEvent來實現持續按鍵,按鍵時事件觸發時間間隔為0.1s
代碼如下:
using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using System.Collections; using UnityEngine.UI; public class ConstantPressEvent : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler { public float interval = 0.1f; [SerializeField] UnityEvent m_OnLongpress = new UnityEvent(); private bool isPointDown = false; private float invokeTime; // Use this for initialization void Start() { } // Update is called once per frame void Update() { if (isPointDown) { if (Time.time - invokeTime > interval) { //觸發點擊; m_OnLongpress.Invoke(); invokeTime = Time.time; } } } public void OnPointerDown(PointerEventData eventData) { m_OnLongpress.Invoke(); isPointDown = true; invokeTime = Time.time; } public void OnPointerUp(PointerEventData eventData) { isPointDown = false; } public void OnPointerExit(PointerEventData eventData) { isPointDown = false; } }
(三)單擊/長按組合
如果需要用到此按鈕既有點擊又有長按則可用如下代碼
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class LongPressEvent : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
public float interval = 1f;
[SerializeField]
UnityEvent longPressEvent = new UnityEvent();
[SerializeField]
UnityEvent pressEvent = new UnityEvent();
private bool isPointDown = false;
private float invokeTime = 0;
private bool longPressInvoked = false;
private bool isPointUp = false;
private bool isDragging = true;
private float distance = 0;
private float precise = 5f;
private float time = 0.15f;
private Vector2 startPos;
private Vector2 endPos;
// Update is called once per frame
void Update()
{
if (isPointDown)
{
if (Time.time - invokeTime > interval)
{
//if (!isInvoked)
//{
// longPressEvent.Invoke();
// invokeTime = Time.time;
// isInvoked = true;
//}
longPressEvent.Invoke();
invokeTime = Time.time;
longPressInvoked = true;
}
}
if (isPointUp)
{
if (Vector2.Distance(startPos, endPos) <= precise && Time.time - invokeTime < time)//Vector2.Distance(startPos,endPos)<=precise&&
{
if (!longPressInvoked)
pressEvent.Invoke();
}
isPointUp = false;
longPressInvoked = false;
}
}
public void OnPointerDown(PointerEventData eventData)
{
startPos = eventData.position;
endPos = eventData.position;
isPointDown = true;
invokeTime = Time.time;
}
public void OnPointerUp(PointerEventData eventData)
{
endPos = eventData.position;
isPointUp = true;
isPointDown = false;
}
public void OnPointerExit(PointerEventData eventData)
{
endPos = eventData.position;
isPointDown = false;
longPressInvoked = false;
}
}
(四)滑動屏幕,旋轉模型
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class ModelRotation : MonoBehaviour, IDragHandler, IBeginDragHandler { public Transform axisRotation;//旋轉對象 public float speedRatate = 0.1f; float posStart = 0; float posDragging = 0; public void OnBeginDrag(PointerEventData eventData) { posStart = eventData.position.x; posDragging = eventData.position.x; //Debug.Log("begin Drag:"+eventData.position); } public void OnDrag(PointerEventData eventData) { posDragging = eventData.position.x; float scale = 0; if (posDragging - posStart > 0) { scale = 1; } else if(posDragging - posStart < 0) { scale = -1; } axisRotation.Rotate(Vector3.up * speedRatate * scale); posStart = posDragging; //Debug.Log("on Drag:" + eventData.position); } }