Unity中使用ulua的個人經驗總結


 

熱度 286052 2015-3-15 14:32 |個人分類:技術類Lua

Lua代碼都是運行時才編譯的,不運行的時候就如同一張圖片、一段音頻一樣,都是文件;所以更新邏輯只需要更新腳本,不需要再編譯,因而Lua能輕松實現“熱更新”。Ulua是一款非常實用的unity插件,它能讓unity支持Lua語言,而且運行效率還不錯。下面就跟大家談談我用ulua的一些心得。

 

Ulua的使用流程一般為:

實例化LuaState對象(new LuaState())è加載Lua代碼(LuaState. DoString(string))è調用Lua代碼中的方法(GetFunction(string),LuaFunction.callFunction(string))。其中,加載Lua代碼這一塊,可以直接賦一段Lua代碼字符串,也可以指定一個Lua腳本文件。為了熱更新,應當采用第二種加載方法,即創建一個Lua腳本文件。由於Unity不支持擴展名為lua的文件,所以可將Lua腳本擴展名定為txt(純文本文件),並用unity的TextAsset列表負責記錄所有腳本文件。建議列表中給每個腳本搭配一個string類型的ID,這樣憑此ID即可加載正確的lua腳本;另外在LuaState類中新增一個String類型的public成員,賦值為該ID。這樣一旦某個Lua腳本在運行時報錯,可根據輸出的ID值判斷是哪個Lua腳本有錯誤。

 

關於Lua里的預處理:

luanet.load_assembly("Assembly-CSharp")

luanet.load_assembly('UnityEngine')

Vector2 = luanet.import_type('UnityEngine.Vector2')

Vector3 = luanet.import_type('UnityEngine.Vector3')

GameObject = luanet.import_type('UnityEngine.GameObject')

luanet.import_type('System.Collections.Generic.List')

Debug = luanet.import_type('UnityEngine.Debug')

這些都是常用的Lua預處理,建議單獨寫個Lua腳本記錄這些,以后加載其他Lua腳本前都先加載一下這個腳本。自定義C#類也是可以import的,import操作是Lua調用C#的前提。當然在C#中實例化的LuaState也可以預定義一些Lua全局變量,這都是在C#里完成的,比如:

[code]csharpcode:

void SetLuaData(LuaState lua)
{
       lua["transform"] = transform;
       lua["gameObject"] = gameObject;
}

預定義了兩個變量,一個是transform,一個是gameObject。

 

關於Lua里的全局變量:

Lua里所有的字符串,如果不是關鍵字或者運算符,就都是變量;這些變量中,凡是沒用local關鍵字修飾的,就是全局變量,反之,則是局部變量。每個LuaState對象,當它加載過Lua代碼以后,它里面定義的全局變量,在這個對象生命期內是一直存在的。如果兩次調用這個LuaState的某方法,第一次將某全局變量進行了修改,那么第二次,這個全局變量會在第一次修改的基礎上繼續修改。

 

關於Lua在Unity的適用范圍:

雖然Lua可以負責Unity工程的任何模塊,但是出於對游戲性能的考慮,盡量少的低頻率的調用Lua,比如盡量少在Update函數中調用Lua、循環利用已經實例化過的LuaState避免浪費資源。對於那些不需要高效運算的模塊,比如UI部分,就可以放心大膽的使用Lua。

 

關於Lua與NGUI的適配:

調用Lua的主要方式就是callFunction,而對於NGUI來說,一般都是按鈕觸發某C#腳本的函數,那么如何用按鈕觸發Lua的函數呢?這就需要有個C#腳本作為“中介”,這個“中介”需要有自己的LuaState實例,當執行“中介”的某個方法時,由該方法調用callFunction。至於具體調用Lua腳本的哪個方法,可以通過傳參的方式告訴這個“中介”——修改NGUI的ButtonMessage類,加入新的public string LuaFunctionName成員,以后由它來制定要調用的Lua方法名就好了。而通過NGUI的UIButton等調用C#的方法,也是同理的(NGUI3.5.6版以后,可以給UIButton等等組件的觸發方法添加參數了)。

 

關於Lua與SimpleJSON的適配:

SimpleJSON是一個開源的JSON庫,這個詳見之前的博客。由於Lua語言無法理解C#里面的屬性,所以凡是SimpleJSON里的public A{get,set}這種,要新寫一些接口函數返回它們的取值,以供Lua調用。而且Lua調用C#里經過很多重載的函數,也經常判斷錯誤(這是個bug?),所以干脆多弄一些函數名,避免調用錯誤。

 

關於Lua與Lua之間的調用:

在Unity中使用Ulua,想要讓兩個Lua腳本彼此調用是很難的,需要通過C#作為“中介”,而且Lua不支持C#的泛型,所以不能用GetComponnet<類名>()的形式,只能用GetComponnet (“類名”)的形式去獲取組件。兩個Lua腳本相互傳參也很麻煩,因為有了C#腳本作為“中介”,所以不能傳tabel類型的參數,我的做法是將若干參數拼成一個json字符串傳遞過去,另一方再解json包。感覺有點蛋疼。不過這種情況並不多見,都是可以避免的(比如一個模塊只用一個大Lua腳本,各自獨立減少溝通)。

 

關於Lua編輯器:

個人使用的是notepad++,也有很多人用sublime,代碼折疊這塊notepad++更好一些,而sublime在功能上貌似更強大一些。

 

Unity編程的親們,有沒有在Unity運行狀態下修改並保存了腳本,然后切回來Unity直接卡死的慘痛經歷?使用Lua,你將告別這一現象,有木有心動呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM