天天看點

架構筆記:記錄XLua的簡單接入閱前提示XLua配置初始化小節

閱前提示

本系列為作者在學習架構與編寫架構時的心得與筆記

适合人群:All

閱讀方式:工具文章

本系列會不斷更新,如果對你有所幫助,點贊收藏吧:)

文章目錄

  • 閱前提示
  • XLua
  • 配置
    • [LuaCallCSharp]
    • [CSharpCallLua]
  • 初始化
  • 小節

XLua

XLua的快速使用正如它的文檔中所描述的那樣,僅僅三行就完事了~

XLua.LuaEnv luaenv = new XLua.LuaEnv();
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
luaenv.Dispose();
           

接下來就是如何将這三行所包含的内容接入到我們的工程架構中了。

配置

在使用Unity做開發的過程中,多多少少在用到Lua時會需要和C#進行一些資料互動。在XLua中,無論是[LuaCallCSharp]還是[CSharpCallLua]用到的一個方式:Wrap。

Wrap,可以了解成**“包裝”**。比如 我們想要在Lua中擷取Unity中的一個GameObject,那我們Lua中的代碼基本上會寫成如下的形式

可以看出,這基本上和我們在C#端的書寫方式并沒有什麼差别,但實際上他們的原理卻很不一樣。

很明顯的一點,lua的資料類型根本無法支援GameObject,是以我們引入了Wrap。無論使用XLua還是ToLua,在初始化的過程中必不可少的是将我們可能需要使用到的C#類、方法包裝起來,以便在Lua中可以相對應的進行資料傳遞。當我們在Lua中需要調用C#的方法時,将通過入棧出棧的方式将 “資料” 進行傳遞(注:這裡的資料是經過處理的每個Object的Id),最終完成Lua與C#的資料互動。

更多詳細的了解可閱讀:Lua C語言API、ToLua:逐行分析源碼,搞清楚Wrap檔案原理

[LuaCallCSharp]

講到着,大緻是說清楚了我們在配置什麼了… 根據自身的需求将需要在Lua中被調用的東西都配置好。

[LuaCallCSharp]
    public static List<Type> LuaCallCSharp = new List<Type>() 
    {
        typeof(Component),
        typeof(Transform),
        typeof(Rigidbody),
        typeof(Behaviour),
        typeof(MonoBehaviour),        
        typeof(GameObject),
        typeof(Time),        
        typeof(Texture),
        typeof(Texture2D),
        typeof(Shader),        
        typeof(Renderer),
        typeof(Screen),        
        typeof(AudioClip),   
        ...
        typeof(自定義...),   
    }
           

[CSharpCallLua]

​ 當然,也可以配置C#直接調用Lua的callback,着一般會配合LuaCallCSharp中的具體方法來使用。具體配置代碼XLua中也提供了參考這裡代碼太長了就不再放出了。

初始化

配置說完後,我們就可以針對一開始提及的三行代碼進行初始化了。

  • XLua.LuaEnv luaenv = new XLua.LuaEnv();

    啟動XLua,建立LuaEnv執行個體,這裡面會做XLua初始化的工作,其中就包含了Wrap配置中的内容。
  • luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");

    加載Lua腳本,XLua提供了DoString()提供了兩種方式:string/byte[] ,實際上最終都是變為byte[]。

    用例中的該方式比較直接,适合用來做簡單的性測使用,一般項目中并不會這麼用。

    XLua提供了luaenv.AddLoader(CustomLoader loader) 方法,讓我們自定義加載腳本的加載器。

    public delegate byte[] CustomLoader(ref string filepath);

    隻需定義一個傳回值為 byte[] 的方法即可。
  • luaenv.Dispose();

    Dispose就過多介紹了,在關閉的時候當然是需要對其進行釋放的~

這樣,XLua的接入就已經算是初步完成了。以下是作者架構中的相關代碼

//初始化
public override void Init()
{
    //建立執行個體
    mLuaEnv = new LuaEnv();
    //添加加載器
    mLuaEnv.AddLoader(XLuaLoader);
    var enterFile = LuaEnterFile;
    //加載Lua第一個腳本
    mLuaEnv.DoString(XLuaLoader(ref enterFile));
	...
}

//加載器
public byte[] XLuaLoader(ref string fileName)
{	
    //正式的加載交由資源管理子產品來進行加載
  #if XLua_VASSET || !UNITY_EDITOR
        if(!fileName.EndsWith(".lua"))
            fileName += ".lua";
    	return VAsset.Instance.LoadScriptFile(fileName);
  #elif UNITY_EDITOR
      //簡單粗暴的加載方式:)
        string filePath = string.Empty;
    	var name = fileName.Replace(".lua","");
    	mSearchPaths.ForEach(value=>{
            if(File.Exists(value.Replace("?",name)))
            {
                filePath = value.Replace("?",name);
                return;
            }   
    	});
        if(filePath.IsEmptyOrNull())
            return null;
        return File.ReadAllBytes(filePath);
  #endif
}
           

小節

因為作者目前還處于緩慢地撸架構階段,是以對于XLua的使用并沒有很深入的了解,也沒有淌過XLua的坑,是以目前就不再這裡在多說太多啦。就作者來言,對比了ToLua,XLua我覺得在接入上面會舒服很多。(因為二者我都接入了,因為我希望我的架構HotScript部分能滿足所有的Lua使用者~)

推薦閱讀:XLua在Unity中的用法摘要

.

.

.

.

.

嗨,我是作者Vin129,逐兒時之夢正在遊戲制作的技術海洋中漂泊。知道的越多,不知道的也越多。希望我的文章對你有所幫助:)