日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UGUI内核大探究(一)EventSystem

發布時間:2025/5/22 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UGUI内核大探究(一)EventSystem 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

UGUI是Unity3D官方推出的UI系統,為了更好的使用UGUI,我們就需要去了解它。

UGUI代碼開源,我們可以從bitbucket下載到源碼。

雖然Unity官方喜歡藏著掖著,例如RectTransform和Canvas系列的源碼都放在了UnityEngine里面,但是這并不妨礙我們對已開源的代碼進行分析(其實多少也有些妨礙吧。。。)

今天我們就探究了一下UGUI的事件系統EventSystem。

雖然名字起得很大,但是實際上EventSystem處理和管理的其實是點擊、鍵盤輸入、觸摸等事件,所以應該成為輸入事件系統InputEventSystem更為恰當。

我們看到EventSystem最開始聲明了一個List和一個變量

[csharp]?view plain?copyprivate?List<BaseInputModule>?m_SystemInputModules?=?new?List<BaseInputModule>();??private?BaseInputModule?m_CurrentInputModule;??

?


系統輸入模塊表和當前輸入模塊。

BaseInputModule是一個抽象類,PointerInputModule繼承自它,同樣也是抽象類,而StandaloneInputModule和TouchInputModule又繼承自PointerInputModule。StandaloneInputModule是面向“PC, Mac& Linux Standalone”這個平臺的輸入模塊,而TouchInputModule是面向“iOS”、“Android”等可觸摸移動平臺的輸入模塊。

EventSystem會每一幀都處理這些輸入模塊,首先是調用TickModules方法,更新每一個InputModule。

然后遍歷m_SystemInputModules判斷這些module是否支持當前的平臺(例如StandaloneInputModule需要判斷是否鼠標已連接,而TouchInputModule需要判斷是否支持觸摸)且module是否可激活(可激活條件祥參StandaloneInputModule和TouchInputModule的源碼)。

如果有符合條件的module便賦值給m_CurrentInputModule(當前輸入模塊)并break。

如果沒有符合條件的module便選取第一個支持當前平臺的module作為m_CurrentInputModule。

最后如果m_CurrentInputModule的值變化了并且m_CurrentInputModule不為null便調用:

而這個方法會將各種輸入事件(如點擊、拖拽等事件)傳遞給EventSystem當前選中的GameObject(m_CurrentSelected)。

[csharp]?view plain?copym_CurrentInputModule.Process();??

而m_CurrentSelected大部分情況是Selectable組件(繼承自它的有Button、Dropdown、InputField等組件)設置的,相關代碼我們會在后續的文章中介紹。

而設置m_CurrentSelected的時候,會通過ExecuteEvents這個類對之前的對象執行一個被取消事件,且對新選中的對象執行一個被選中事件。這就是OnSelect和OnDeselect兩個方法的由來。

?

EventSystem的RaycastAll方法使用射線從相機到某個點(設為點E)照射在UI上,然后對被照射到的所有對象進行排序,大致是遠近排序。

而這個方法實在PointerInputModule中使用的,如果點擊(或觸摸)事件移動的時候,被該事件影響的對象也會發生變化,通過RaycastAll方法(傳入的eventData中的position屬性作為點E)獲得到第一個被射線照射到的對象,如果與之前的對象不同,便變更對象(同時會回調原對象的OnPointerExit和新對象的OnPointerEnter方法)。

IsPointerOverGameObject是EventSystem類里特別常用的一個方法,用于判斷是否點擊在UI上,具體是在PointerInputModule中實現的,以后我們研究UGUI的輸入模塊的時候會深入講解,概括一下就是判斷當前是否存在某個鍵位(默認是-1鼠標左鍵)的數據。

最后我們注意到EventSystem有一個static屬性:

[csharp]?view plain?copypublic?static?EventSystem?current?{?get;?set;?}??


因為是靜態屬性,所以只存在一個current,而并不會每個實例對象會有一個.

?

當一個EventSystem組件OnEnable的時候會將這個對象賦值給current。參考OnEnabled與OnDisabled。

[csharp]?view plain?copyprotected?override?void?OnEnable()??{??base.OnEnable();??if?(EventSystem.current?==?null)??EventSystem.current?=?this;?? #if?UNITY_EDITOR??else??{??Debug.LogWarning("Multiple?EventSystems?in?scene...?this?is?not?supported");??}?? #endif??}??


OnDisable的時候會將current賦值為null(當current==this)。參考OnEnabled與OnDisabled。

?

[csharp]?view plain?copyprotected?override?void?OnDisable()?? {??if?(m_CurrentInputModule?!=?null)??{??m_CurrentInputModule.DeactivateModule();??m_CurrentInputModule?=?null;??}??if?(EventSystem.current?==?this)??EventSystem.current?=?null;??base.OnDisable();?? }??


這就是為什么我們在Unity Editor里面增加多個EventSystem的時候會報警告。

?

當然在游戲運行的時候,我們也不能隨意的增加刪除EventSystem,一來似乎并沒有什么必要,二來雖然EventSystem本身并沒有太多東西,但是畢竟輸入模塊里面還是保存了一些數據的。

轉載于:https://my.oschina.net/u/2874878/blog/1594641

總結

以上是生活随笔為你收集整理的UGUI内核大探究(一)EventSystem的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。