Unity button事件监听的四种方式
使用UGUI进行可视化界面构建的同时,处理关联事件也非常高效。实时生成界面基于预先构建好的Prefab组件能够快速生成实例。主要难点在于处理关联事件较为繁琐。本文着重探讨了如何将按钮与多种事件绑定起来的方法
1. 可视化创建及事件绑定 #
Step 1 : 通过 Hierarchy 面板创建 UI > Button.
Step 2 : 创建一个脚本 TestClick.cs, 定义了一个 Click 的 public 方法.
Step 3 : 选中 Hierarchy 中的 Button, Add Component 脚本 TestClick.cs
Step 4 : 在 Button(Script) 关联 TestClick 脚本里的 Click 方法.
Step 5 : TestClick.cs
public class TestClick : MonoBehaviour
{
public void Click()
{
Debug.Log ("Button Clicked. TestClick.");
}
}
cs
2. 通过直接绑定脚本来绑定事件 #
Step 1 : 通过 Hierarchy 面板创建 UI > Button.
Step 2 : 编写一个名为 ClickHandler.cs 的C#脚本文件,在其中定义了一个私有的名为"OnClick()"的方法。随后,在该脚本的 onStart() 方法中为指定的Button对象添加了点击事件监听,并将此事件作为参数传递给"OnClick()"方法。
Step 3 : 在完成上述操作后,请将该handler与Button对象关联起来。
Step 4 :ClickHandler.cs
public class ClickHandler : MonoBehaviour
{
void Start ()
{
Button btn = this.GetComponent<Button> ();
btn.onClick.AddListener (OnClick);
}
private void OnClick()
{
Debug.Log ("Button Clicked. ClickHandler.");
}
}
cs

3. 借助 EventTrigger 实现按钮的事件触发机制 #
在UGUI系统中,默认情况下Button类仅支持提供OnClick事件的方法,在某些情况下, 我们可能还需要关注鼠标进入(MouseIn)和离开(MouseOut)的事件。就可以借助UI系统中的EventTrigger脚本来实现这一功能。
Step 1 : 通过 Hierarchy 面板创建 UI > Button.
Step 2: 生成一个EventTriggerHandler.cs脚本,并通过UnityEngine
Step 3: 将该EventTriggerHandler.cs脚本绑定至Button组件上。
Step 4 : EventTriggerHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
// 需要 EventTrigger 脚本的支援
[RequireComponent(typeof(UnityEngine.EventSystems.EventTrigger))]
public class EventTriggerHandler : MonoBehaviour
{
void Start ()
{
Button btn = this.GetComponent<Button> ();
EventTrigger trigger = btn.gameObject.GetComponent<EventTrigger> ();
EventTrigger.Entry entry = new EventTrigger.Entry ();
// 鼠标点击事件
entry.eventID = EventTriggerType.PointerClick;
// 鼠标进入事件 entry.eventID = EventTriggerType.PointerEnter;
// 鼠标滑出事件 entry.eventID = EventTriggerType.PointerExit;
entry.callback = new EventTrigger.TriggerEvent ();
entry.callback.AddListener (OnClick);
// entry.callback.AddListener (OnMouseEnter);
trigger.triggers.Add (entry);
}
private void OnClick(BaseEventData pointData)
{
Debug.Log ("Button Clicked. EventTrigger..");
}
private void OnMouseEnter(BaseEventData pointData)
{
Debug.Log ("Button Enter. EventTrigger..");
}
}
cs

4. 通过Beanicade实现事件类接口以实现事件监听 #
第1步:在层级面板中创建UI中的Button.
Step 2 : 创建一个 EventHandler.cs 脚本.
Step 3 : 将脚本绑定在 Button 对象上.
Step 4 : EventHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class EventHandler : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IDragHandler
{
public void OnPointerClick(PointerEventData eventData)
{
if(eventData.pointerId == -1){
Debug.Log ("Left Mouse Clicked.");
} else if(eventData.pointerId == -2){
Debug.Log ("Right Mouse Clicked.");
}
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log ("Pointer Enter..");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log ("Pointer Exit..");
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log ("Pointer Down..");
}
public void OnDrag(PointerEventData eventData)
{
Debug.Log ("Dragged..");
}
}
cs

如何通过UGUI确定UI元素在被点击时所使用的鼠标键类型?代码中可以利用dataEvent_pointerId属性来区分左键和右键。如果每个UI元素都要创建一个Eventbite对象来监听所有事件显然效率不高。可以通过将Delegate与Event结合使用的方式开发一个通用类UIEventListener(基于观察者模式)
UIEventListener.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class UIEventListener : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
// 定义事件代理
public delegate void UIEventProxy(GameObject gb);
// 鼠标点击事件
public event UIEventProxy OnClick;
// 鼠标进入事件
public event UIEventProxy OnMouseEnter;
// 鼠标滑出事件
public event UIEventProxy OnMouseExit;
public void OnPointerClick(PointerEventData eventData){
if (OnClick != null)
OnClick (this.gameObject);
}
public void OnPointerEnter(PointerEventData eventData){
if (OnMouseEnter != null)
OnMouseEnter (this.gameObject);
}
public void OnPointerExit(PointerEventData eventData){
if (OnMouseExit != null)
OnMouseExit (this.gameObject);
}
}
cs

TestEvent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestEvent : MonoBehaviour
{
void Start ()
{
Button btn = this.GetComponent<Button> ();
UIEventListener btnListener = btn.gameObject.AddComponent<UIEventListener> ();
btnListener.OnClick += delegate(GameObject gb) {
Debug.Log(gb.name + " OnClick");
};
btnListener.OnMouseEnter += delegate(GameObject gb) {
Debug.Log(gb.name + " OnMouseEnter");
};
btnListener.OnMouseExit += delegate(GameObject gb) {
Debug.Log(gb.name + " OnMOuseExit");
};
}
}
cs

TestEvent 脚本绑定在 Button 上即可.
