1. 程式人生 > >unity3D UGUI學習(五) EventSystem,EventTrigger響應事件介紹

unity3D UGUI學習(五) EventSystem,EventTrigger響應事件介紹

前言

UGUI中EventSystem主要負責處理輸入、射線以及傳送事件,一個場景中
只能有一個EventSystem並且需要 BaseInputModule型別組建的協助才
能工作。

EventSystem負責管理,BaseInputModule負責輸 入,BaseRaycaster負責確定目標物件。

UGUI中不僅可以對UI進行監測,還可以對場景中的物件進 行監測,以下會
有詳細介紹

需要引入的空間名

using UnityEngine.EventSystems;
using UnityEngine.Events;
一、StandaloneInputModule和TouchInoutModule兩個元件會監測一些輸入操作,以事件的方式通知目標物件,支援的事件有以下:
  1. IPointerEnterHandler - OnPointerEnter - Called when a pointer enters the object
  2. IPointerExitHandler - OnPointerExit - Called when a pointer exits the object
  3. IPointerDownHandler - OnPointerDown - Called when a pointer is pressed on the object
  4. IPointerUpHandler - OnPointerUp - Called when a pointer is released (called on the original the pressed object)
  5. IPointerClickHandler - OnPointerClick - Called when a pointer is pressed and released on the same object
  6. IInitializePotentialDragHandler - OnInitializePotentialDrag - Called when a drag target is found, can be used to initialise values

使用方式:
1. 引入名稱空間 using UnityEngine.EventSystems;
2. 使用某個方法就繼承某個介面
3. 根據方法的引數使用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// Button a.
/// UGUI處理其他型別事件的方式一:介面
/// </summary>
public class ButtonA : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerDownHandler,IPointerClickHandler{

    public void OnPointerEnter (PointerEventData eventData)
    {
        Debug.Log ("enter");
        //滑鼠進入到那,就把進入到那的那個物體名輸出
        Debug.Log (eventData.pointerEnter.name);
    }

    public void OnPointerExit(PointerEventData eventData){
        Debug.Log ("exit");
    }
    //按下就觸發
    public void OnPointerDown(PointerEventData eventData){
        Debug.Log ("down");
        //Debug.Log (eventData.pointerPress.name); eventData.pointerPress.name該值只能寫一個、不能重複寫
    }

    //滑鼠點選完成(按下,擡起)觸發 ,如果按下的時候在別的地方擡起,則不會觸發
    public void OnPointerClick(PointerEventData eventData){
        Debug.Log ("click");
    }
}

注意的:
1. 可以同時繼承多個介面,同時使用多個方法
2. 使用方式大致相同
3. 觸碰到那個,需要進行測試,尤其是對於組合的物體,它會是觸碰到某個子物體,還是指代完整的父物體?

二、以拖拽的方式新增事件方法給EventTrigger

先建立一個ButtonB UI物件,然後建立指令碼, 拖給ButtonB
以下是指令碼程式碼

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Button b.
/// UGUI處理其它型別事件的方式二:拖拽
/// </summary>
public class ButtonB : MonoBehaviour {

    public void PEnter(){
        Debug.Log ("PEnter");
    }
    public void PExit(){
        Debug.Log ("PExit");
    }
    public void PDown(){
        Debug.Log ("PDown");
    }
    public void PClick(){
        Debug.Log ("PClick");
    }

}

給ButtonB物件新增EventTrigger元件
然後把Button拖入EventTrigger,選擇對應的類,對應的方法
2

一般來說,這樣做不易於維護,查詢比較費勁。主要是用程式碼的形式新增

三、使用EventTrigger類和指令碼程式碼新增事件

EventTrigger類實際是一個類,裡面包含一個欄位,一個屬性,多個虛方法和二個內建類
其中具體的可以從API中讀一讀

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

using UnityEngine.Events;
/// <summary>
/// Button c.
/// UGUI處理其它型別事件的方式三:程式碼新增
/// </summary>
public class ButtonC : MonoBehaviour {
    EventTrigger trigger;
    void Start(){
        //1, 給需要的物體新增事件的元件EventerTrigger
        trigger = GetComponent<EventTrigger> ();

        if (trigger == null) {
            trigger = gameObject.AddComponent<EventTrigger> ();
        }

        //2.初始化EventTrigger.Entry容器
        trigger.triggers = new List<EventTrigger.Entry>();
        //例項化一個EventTrigger.Entry物件
        EventTrigger.Entry enter = new EventTrigger.Entry ();

        //根據方法需要的引數依次寫
        //3.指定事件觸發的型別
        enter.eventID = EventTriggerType.PointerEnter;
        //4.指定事件觸發的方法
        enter.callback = new EventTrigger.TriggerEvent ();
        //5.需要新增名稱空間using UnityEngine.Events;,並傳入一個要呼叫的方法名稱,這句可以先寫,因為這裡初始化只需要一個待呼叫的方法
        UnityAction<BaseEventData> action = new UnityAction<BaseEventData> (PEnter);

        //6.新增
        enter.callback.AddListener (action);
        trigger.triggers.Add (enter);
    }

    private void PEnter(BaseEventData pd){
        Debug.Log ("Penter");
    }
}

因為用程式碼寫的步數操作較多,每寫一個事件響應就要重複寫,因此可以寫一個函式工具

這個函式工具的引數有3個
1. 物體物件
2. 觸碰型別
3. 觸碰後呼叫的方法

例子
    private delegate void MyMehod(BaseEventData pd);

    private void addTriggersListener(GameObject obj, EventTriggerType eventTriggerType,MyMehod myMehod){
        EventTrigger ET = GetComponent<EventTrigger> ();
        if (ET == null) {
            ET = obj.AddComponent<EventTrigger> ();
        }
        if (trigger.triggers.Count == 0) {
            trigger.triggers = new List<EventTrigger.Entry> ();
        }

        UnityAction<BaseEventData> callBack = new UnityAction<BaseEventData> (myMehod);
        EventTrigger.Entry entry = new EventTrigger.Entry ();
        entry.eventID = eventTriggerType;
        entry.callback.AddListener (callBack);

        trigger.triggers.Add (entry);
    }

    private void myMehod(BaseEventData pd){
        Debug.Log (";-)");
    }   

//在Start呼叫該方法,傳入型別即可 
addTriggersListener (gameObject, EventTriggerType.PointerClick, myMehod);

這裡的使用的是list容器,所以對於不同型別的觸碰方法可以疊加,方法也可以重複使用,功能十分強大
重複使用該工具方法:

        addTriggersListener (gameObject, EventTriggerType.PointerClick, myMehod);
        addTriggersListener (gameObject, EventTriggerType.PointerClick, PEnter);
        addTriggersListener (gameObject, EventTriggerType.PointerExit, PEnter);
        addTriggersListener (gameObject, EventTriggerType.PointerEnter, myMehod);