日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

UGUI内核大探究(一)EventSystem

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

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

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

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

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

今天我們就探究了一下UGUI的事件系統(tǒng)EventSystem。

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

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

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

?


系統(tǒng)輸入模塊表和當(dāng)前輸入模塊。

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

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

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

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

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

最后如果m_CurrentInputModule的值變化了并且m_CurrentInputModule不為null便調(diào)用:

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

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

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

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

?

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

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

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

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

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


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

?

當(dāng)一個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(當(dāng)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的時候會報警告。

?

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

轉(zhuǎn)載于:https://my.oschina.net/u/2874878/blog/1594641

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。