前言
基于UnityEvent实现持续按键(长按)事件,单按/长按组合按钮以及滑动屏幕旋转模型等功能
1.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来实现。
2.持续按键
通过unityEvent来实现持续按键,按键时事件触发时间间隔为0.1s,即当按下时每个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;
}
}
3.单击/长按组合
如果需要用到此按钮既有点击又有长按则可用如下代码
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;
}
}
4.滑动屏幕,旋转模型
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);
}
}