1. 程式人生 > >Unity UGUI 繫結事件的 4 種方式

Unity UGUI 繫結事件的 4 種方式

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 UnityEngine;
using UnityEngine.EventSystems;


public class EventTriggerHandler: MonoBehaviour {


    EventTrigger trigger;


    void Start()
    {
        trigger= GetComponent<EventTrigger>();


        EventTrigger.Entry ENTER = new EventTrigger.Entry();
        EventTrigger.Entry EXIT = new EventTrigger.Entry();
        EventTrigger.Entry CLICK = new EventTrigger.Entry();
        EventTrigger.Entry DOWN = new EventTrigger.Entry();
        EventTrigger.Entry UP = new EventTrigger.Entry();


        ENTER.eventID = EventTriggerType.PointerEnter;  //滑鼠進入事件
        EXIT.eventID = EventTriggerType.PointerExit;  //滑鼠滑出事件
        CLICK.eventID = EventTriggerType.PointerClick;  //滑鼠點選事件
        DOWN.eventID = EventTriggerType.PointerDown;  //滑鼠按下事件
        UP.eventID = EventTriggerType.PointerUp;   //滑鼠擡起事件


        ENTER.callback.AddListener(OnPointerEnter);
        EXIT.callback.AddListener(OnPointerExit);
        CLICK.callback.AddListener(OnPointerClick);
        DOWN.callback.AddListener(OnPointerDown);
        UP.callback.AddListener(OnPointerUp);


        trigger.triggers.Add(ENTER);
        trigger.triggers.Add(EXIT);
        trigger.triggers.Add(CLICK);
        trigger.triggers.Add(DOWN);
        trigger.triggers.Add(UP);
    }


    public void OnPointerEnter(BaseEventData pointData)
    {
        print("PointerEnter");
    }


    public void OnPointerExit(BaseEventData pointData)
    {
        print("PointerExit");
    }


    public void OnPointerClick(BaseEventData pointData)
    {
        print("PointerClick");
    }


    public void OnPointerDown(BaseEventData pointData)
    {
        print("PointerDown");
    }


    public void OnPointerUp(BaseEventData pointData)
    {
        print("PointerUp");
    }
}

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 上即可.

Project 結構