UGUI 事件系統

當我們在場景中創建任一UI對象後,Hierarchy面板中都可以看到系統自動創建了EventSystem對象,EventSystem對象負責管理所有事件相關對象,該對象下掛載了EventSystem組件和StandaloneInputModule組件,前者爲管理腳本,後者爲輸入模塊。Canvas對象下掛載了GraphicRaycaster負責處理射線相關運算,用戶的操作都會通過射線檢測來映射到UGUI組件上,InputModule將用戶的操作轉化爲射線檢測,Raycaster則找到目標對象並通知EventSystem,最後EventSystem發送事件讓目標對象進行響應。
總結來說就是:EventSystem負責管理,BaseInputModule負責輸入,BaseRaycaster負責確定目標對象,目標對象負責接收事件並處理,然後一個完整的事件系統就有了


一:EventSystem事件系統


一個場景中只能有一個EventSystem組件
——First Selected:第一次默認選擇的物體
——Send Navigation Events:是否可以使用導航事件(鍵盤上下左右)控制
——Drag Threshold:視爲拖拽操作的最小距離

二:EventInterface事件接口


 

(實現Tooltip)
——IPointerEnterHandler
鼠標進入時響應
——IPointerExitHandler
鼠標離開時響應

 

——IPointerDownHandler
在可視元素矩形區域內按下時響應
——IPointerUpHandler
在可視元素矩形區域內按下後,在任意區域擡起時響應
——IPointerClickHandler
在可視元素矩形區域內按下後,在同一可視元素矩形區域內擡起時響應

 

(實現揹包物體交換)
——IBeginDragHandler
開始拖動時相應
——IDragHandler
拖動中時相應
——IEndDragHandler
結束拖動時相應
——IDropHandler
接收拖動事件,必須先實現IDragHandler
例子:物體A上實現了IDragHandler,物體B上實現了IDropHandler,從物體A上開始Drag,在物體A上結束Drag,沒有觸發OnDrop。從物體A上開始Drag,在物體B上結束Drag,可以觸發OnDrop
——IInitializePotentialDragHandler
與IPointerDownHandler觸發條件大致相同,幾乎沒用
——IScrollHandler
鼠標滾動滾動時響應

 

——ISelectHandler
每次選擇UI元素時響應,但是如果此物體不是Button這種有選擇操作的UI元素,需要寫代碼進行選擇:EventSystem.current.SetSelectedGameObject(gameObject)
——IDeselectHandler
每次取消選擇UI元素時響應,點擊此可視元素矩形區域外即爲取消選擇
——IUpdateSelectedHandler
選擇了UI元素時一直響應

 

(與BuildSettings—PlayerSettings—Input中的設置相對應。與Select相關的三個接口類似也需要元素本身具有選擇操作)
——IMoveHandler
與Horizontal和Vertical相對應
——ISubmitHandler
與Submit相對應
——ICancelHandler
與Cancal相對應

三:EventData事件數據


 

——BaseEventData:基礎事件數據—事件數據的基類

 


——PointerEventData:光標事件數據—鼠標與觸摸的相關數據(進入,點擊,拖動),UGUI的大部分事件數據的類型都是PointerEventData
1.button:鼠標的(左,中,右)鍵哪個鍵點擊的
2.clickCount:連續點擊的次數(從1開始累加)
3.clickTime:當前點擊的時間(根據上一次點擊的時間累加)
4.position:鼠標當前的位置
5.pressPosition:鼠標點擊時的位置
6.delta:當前點擊與上一次點擊的位置差值
7.dragging:是否爲拖拽狀態(不受EventSystem組件上Drag Threshold的影響,只在使用OnDrag相關事件接口時才起作用)
8.pointerEnter:鼠標進入時的物體
9.pointerPress:鼠標點擊時的物體(OnPointerDown,OnPointerEnter等沒有鼠標擡起的事件不能使用,因爲沒有擡起並不算一次點擊)
10.pointerDrag:鼠標拖拽的物體
11.lastPress:最後一次點擊的物體
12.rawPointerPress:第一次點擊的物體
13.worldNormal:射線檢測到的第一個物體的法線
14.enterEventCamera:鼠標進入時的相機
15.pressEventCamera:鼠標點擊時的相機
16.pointerCurrentRaycast:鼠標進入時的射線信息
17.pointerPressRaycast:鼠標點擊時的射線信息

 


——AxisEventData:軸向事件數據—手柄和鍵盤中控制軸向的相關數據(參考BuildSettings—PlayerSettings—Input中的設置)

四:Raycaster射線檢測


UGUI的射線檢測是從攝像機發起的並配合碰撞器

必須與Canvas組件一起掛載在同一物體身上
1.Ignore Reversed Graphics:忽略顛倒的圖形的射線檢測,即旋轉180°後的圖片不會與射線發生檢測
2.Blocking Objects:屏蔽指定類型的物理(必須添加碰撞器)對象,使它們不參與射線檢測(渲染模式不爲Overlay並添加渲染相機時起作用)
3.Blocking Mask:使屏蔽對象中的指定層不參與射線檢測(渲染模式不爲Overlay並添加渲染相機且Blocking Objects不爲None時起作用)

 

——PhysicsRaycaster和Physics2DRaycaster

必須與Camera組件一起掛載在同一物體身上,給掛載了Camera物體的同一物體添加PhysicsRaycaster組件就可以讓3D物體利用EventSystem響應事件了
1.Event Mask::屏蔽指定層不參與射線檢測
————————————————
版權聲明:本文爲CSDN博主「LLLLL__」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/LLLLL__/article/details/104008976

 

IPointerEnterHandler
指針進入
public void OnPointerEnter(PointerEventData eventData);

IPointerExitHandler
指針退出
public void OnPointerExit(PointerEventData eventData);

IPointerDownHandler
指針按下
public void OnPointerDown(PointerEventData eventData);

IPointerUpHandler
指針釋放(可能按下時的指針位置跟釋放時的指針位置不同,這裏指的是按下時指針指着的物體)
public void OnPointerUp(PointerEventData eventData);

IPointerClickHandler
在同一物體上按下並釋放
public void OnPointerClick(PointerEventData eventData);

IInitializePotentialDragHandler
拖拽時的初始化,跟IPointerDownHandler差不多,在按下時調用 
public void OnInitializePotentialDrag(PointerEventData eventData);

IBeginDragHandler
開始拖拽
public void OnBeginDrag(PointerEventData eventData);

IDragHandler
拖拽中
public void OnDrag(PointerEventData eventData);

IEndDragHandler
拖拽結束(被拖拽的物體調用)
public void OnEndDrag(PointerEventData eventData);

IDropHandler
拖拽結束(拖拽結束後的位置(即鼠標位置)如果有物體,則那個物體調用)
public void OnDrop(PointerEventData eventData);

IScrollHandler
滾輪滾動
public void OnScroll(PointerEventData eventData);

IUpdateSelectedHandler
被選中的物體每幀調用
public void OnUpdateSelected(BaseEventData eventData);

ISelectHandler
物體被選中時(EventSystem.current.SetSelectedGameObject(gameObject))
public void OnSelect(BaseEventData eventData);

IDeselectHandler
物體從選中到取消選中時
public void OnDeselect(BaseEventData eventData);

IMoveHandler
物體移動時(與InputManager裏的Horizontal和Vertica按鍵相對應),前提條件是物體被選中
public void OnMove(AxisEventData eventData);

ISubmitHandler
提交按鈕被按下時(與InputManager裏的Submit按鍵相對應,PC上默認的是Enter鍵),前提條件是物體被選中
public void OnSubmit(BaseEventData eventData);

ICancelHandler
取消按鈕被按下時(與InputManager裏的Cancel按鍵相對應,PC上默認的是Esc鍵),前提條件是物體被選中
public void OnCancel(BaseEventData eventData);


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
總結:
1.共有17個接口方法
2.其中OnMove使用的參數是AxisEventData eventData
3.其中OnUpdateSelected、OnSelect 、OnDeselect 、OnSubmit 、OnCancel 使用的參數是BaseEventData eventData
4.其餘使用的參數是PointerEventData eventData
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
實現事件的兩種方式:
1.編輯器:添加Event Trigger組件
2.代碼:繼承EventTrigger,實現方法(EventTrigger繼承了上面所說的接口)

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
 
public class TestUI3 : MonoBehaviour
{
    private GameObject button;
    private GameObject image;
 
    void Start () 
    {
        button = GameObject.Find("Button");
        image = GameObject.Find("Image");
        EventTriggerListener.GetListener(button).onPointerClick += Click;
        EventTriggerListener.GetListener(image).onDrag += Drag;
    }
 
    public void Click(GameObject go)
    {
        Debug.Log(go.name);
    }
 
    public void Drag(GameObject go)
    {
        Debug.Log(go.name);
    }
}

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
 
public class EventTriggerListener : EventTrigger
{
    #region 變量
    //帶參數是爲了方便取得綁定了UI事件的對象  
    public delegate void PointerEventDelegate(GameObject go, PointerEventData eventData);
    public delegate void BaseEventDelegate(GameObject go, BaseEventData eventData);
    public delegate void AxisEventDelegate(GameObject go, AxisEventData eventData);
 
    public event PointerEventDelegate onPointerEnter;
    public event PointerEventDelegate onPointerExit;
    public event PointerEventDelegate onPointerDown;
    public event PointerEventDelegate onPointerUp;
    public event PointerEventDelegate onPointerClick;
    public event PointerEventDelegate onInitializePotentialDrag;
    public event PointerEventDelegate onBeginDrag;
    public event PointerEventDelegate onDrag;
    public event PointerEventDelegate onEndDrag;
    public event PointerEventDelegate onDrop;
    public event PointerEventDelegate onScroll;
    public event BaseEventDelegate onUpdateSelected;
    public event BaseEventDelegate onSelect;
    public event BaseEventDelegate onDeselect;
    public event AxisEventDelegate onMove;
    public event BaseEventDelegate onSubmit;
    public event BaseEventDelegate onCancel;
    #endregion
 
    public static EventTriggerListener GetListener(GameObject go)
    {
        EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
        if (listener == null) listener = go.AddComponent<EventTriggerListener>();
        return listener;
    }
 
    #region 方法
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onPointerEnter != null) onPointerEnter(gameObject, eventData);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onPointerExit != null) onPointerExit(gameObject, eventData);
    }
    public override void OnPointerDown(PointerEventData eventData)
    {
        if (onPointerDown != null) onPointerDown(gameObject, eventData);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onPointerUp != null) onPointerUp(gameObject, eventData);
    }
    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onPointerClick != null) onPointerClick(gameObject, eventData);
    }
    public override void OnInitializePotentialDrag(PointerEventData eventData)
    {
        if (onInitializePotentialDrag != null) onInitializePotentialDrag(gameObject, eventData);
    }
    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (onBeginDrag != null) onBeginDrag(gameObject, eventData);
    }
    public override void OnDrag(PointerEventData eventData)
    {
        if (onDrag != null) onDrag(gameObject, eventData);
    }
    public override void OnEndDrag(PointerEventData eventData)
    {
        if (onEndDrag != null) onEndDrag(gameObject, eventData);
    }
    public override void OnDrop(PointerEventData eventData)
    {
        if (onDrop != null) onDrop(gameObject, eventData);
    }
    public override void OnScroll(PointerEventData eventData)
    {
        if (onScroll != null) onScroll(gameObject, eventData);
    }
    public override void OnUpdateSelected(BaseEventData eventData)
    {
        if (onUpdateSelected != null) onUpdateSelected(gameObject, eventData);
    }
    public override void OnSelect(BaseEventData eventData)
    {
        if (onSelect != null) onSelect(gameObject, eventData);
    }
    public override void OnDeselect(BaseEventData eventData)
    {
        if (onDeselect != null) onDeselect(gameObject, eventData);
    }
    public override void OnMove(AxisEventData eventData)
    {
        if (onMove != null) onMove(gameObject, eventData);
    }
    public override void OnSubmit(BaseEventData eventData)
    {
        if (onSubmit != null) onSubmit(gameObject, eventData);
    }
    public override void OnCancel(BaseEventData eventData)
    {
        if (onCancel != null) onCancel(gameObject, eventData);
    }
    #endregion
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章