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 : Done.
TestClick.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestClick : MonoBehaviour {
public void Click(){
Debug.Log ("Button Clicked. TestClick.");
}
}
2. 通過直接繫結指令碼來繫結事件 #
Step 1 : 通過 Hierarchy 面板建立 UI > Button.
Step 2 : 建立一個 ClickHandler.cs 指令碼, 定義了一個私有方法 OnClick(), 並在 Start() 方法裡為 Button 新增點選事件的監聽,作為引數傳入 OnClick 方法.
Step 3 : 將 ClickHandler 繫結在 Button 物件上.
Step 4 : Done.
ClickHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ClickHandler : MonoBehaviour {
void Start () { Button btn = this.GetComponent<Button> (); btn.onClick.AddListener (OnClick); } private void OnClick(){ Debug.Log ("Button Clicked. ClickHandler."); }
}
3. 通過 EventTrigger 實現按鈕點選事件 #
UGUI 系統中 Button 預設只提供了 OnClick 的呼叫方法, 有時候我們還需要監聽滑鼠進入事件 (MouseIn) 和滑鼠滑出事件 (MouseOut). 就需要藉助 UI 系統中的 EventTrigger 指令碼來實現.
Step 1 : 通過 Hierarchy 面板建立 UI > Button.
Step 2 : 建立一個 EventTriggerHandler.cs 指令碼, 利用 UnityEngine.EventSystems.EventTrigger 新增監聽事件.
Step 3 : 繫結 EventTriggerHandler.cs 指令碼到 Button 上.
Step 4 : Done.
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 {
// Use this for initialization
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..");
}
}
4. 通過 MonoBehaviour 實現事件類介面來實現事件的監聽 #
Step 1 : 通過 Hierarchy 面板建立 UI > Button.
Step 2 : 建立一個 EventHandler.cs 指令碼.
Step 3 : 將指令碼繫結在 Button 物件上.
Step 4 : Done.
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..");
}
}
UGUI 如何判斷 UI 元素被點選時是滑鼠的哪個按鍵, 上面的程式碼中我們可以根據 eventData.pointerId 來監聽是滑鼠左鍵還是右鍵. 但是每個 UI 元素都建立一個 MonoBehaviour 來監聽各個事件顯然不好, 下面是通過利用 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);
}
}
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");
};
}
}
TestEvent 指令碼繫結在 Button 上即可.