讓我們實際的研究一下如何將NGUI和C#LightEvil結合起來。
這裡使用NGUI2.7,因為他是一個開源的版本,NGUI最新的版本未經作者的許可,是不可以帶入我們的開源專案使用的。
這個例子完成的功能是從NGUI例子裡找出了三個介面,按最下方的按鈕依次進行切換
這是在之前的框架演示Mode1的基礎上做的
由一個狀態機去進行驅動,這也是我推薦各位使用指令碼的方式。
Mode1的模式是定義一個介面類,然後由指令碼繼承此型別實現,因為隨時考慮AOT的緣故(要相容IOS),我們的指令碼有很多限制,比如不能執行時產生IL型別。
那麼如果你熟悉AOT和JIT的機制,你一定會發現,指令碼繼承程式型別的是不可能的。
由於我們的指令碼和C#語法相容,所以,其實這個IState 會在程式中會和指令碼中分別使用,他們是兩個不同的東西。只是從語法上看起來一模一樣。
通過一個叫做ScriptInstanceState的類,他是程式中的IState,他的作用是呼叫指令碼中的IState,通過這個型別,指令碼狀態和程式狀態可以實現無縫切換。
繞口令來了:
在實際的遊戲中,你可以一部分狀態用程式實現,一部分狀態用指令碼實現。
由於我們的指令碼是c#的嚴格子集,所有指令碼實現的狀態,作為程式也都可以正常執行。
程式實現的狀態,對語法進行改寫,改成C#Light可以通過的狀態,也就可以作為指令碼執行了。
先不管這個,其實無縫切換很簡單,往這裡看。
s 就是狀態,直接new 就是程式,從我們的粘合類ScriptInstanceState建立,就是指令碼
大部分的操作都是沒問題的
注意以下紅字是舊的部分,新0.41Beta已經修改成
1.不強制使用event,所以不修改UIEventListener也可以掛事件,直接使用等號即可
2.修改了Reg機制,註冊更簡潔,不需要特別處理
黃字為新的部分。
不需修改UIEventListener,使用方法與程式碼一致
RegHelper_DeleAction<GameObject>的意思是,我們註冊的委託型別
是 void xxx(GameObject p1) 的形式。因為VoidDelegate就是這個形式
如果我們要註冊一個 void xxx(int p0,string p1)的委託型別 就用RegHelper_DeleAction<int,string>
不需獨立實現,用RegHelper_DeleAction即可
新部分結束
舊的部分
有一個比較討厭的地方是回撥,這裡C#LightEvil 處於嚴謹的考慮只支援了對event的訪問,而NGUI的使用卻不是event
這裡我們可以修改一下NGUI,對功能沒有任何不良影響。
這是指令碼中的程式碼,比較偷懶使用了匿名函式,實際上建議你使用一個獨立定義在指令碼里的函式,記得我們是一個嚴格照顧AOT的專案麼,匿名函式我們是不可能真的產生的。
他是一個模擬匿名的實現,為了閉包是有額外的開銷的。
這裡的onClick +=是 event的用法。,
就是這裡,需要把onclick前面加一個event,由於目前C#LightEvil只支援了對event的訪問,不允許直接對delegate賦值。
這個DeleType也要特別實現下,他的定義和Action<Gameobject>是一樣的,只要將 RegHelper_DeleAction Copy過來修改一下就是了。
舊的部分
指令碼註冊回撥並不是我推薦的方法,他實際上可以在IState裡面定義一個OnClick事件,由程式處理,集中通過實現介面來完成。
這個例子專門使用了匿名,自定義事件,只是為了展示C#LightEvil的更多方面給大家看。
至於推薦的C#LightEvil使用方法,主要是通過一個介面來完成指令碼和程式的對接,並且可以無縫切換。