ToLua(LuaFramework) -ToLua框架使用指南

LuaFramework 熱更新流程:
在這裏插入圖片描述

  1. Main腳本調用整個遊戲的啓動函數Startup
  2. 遊戲管理器GameManager生成
  3. GameManager調用CheckExtractResource函數,檢查“數據目錄”是否存在
  4. 如果“數據目錄”不存在,說明是初次運行遊戲,就將“遊戲包資源目錄”的內容解壓縮到“數據目錄”
  5. 如果“數據目錄”存在,就檢查是否需要從服務器下載資源,GameManager調用OnUpdateResource函數下載“網絡資源地址”上的files.txt,然後與“數據目錄”中文件的md5碼做比較,更新有變化的文件
  6. 更新完成後,GameManager調用OnResourceInited函數,啓動Lua狀態機,遊戲開始

調試:在Main.lua加入調試語句,在LuaManager的StartMain訪問熱更新增的Lua腳本,生成新打包的Prefab

AppConst類的UpdateMode設爲true,則從指定服務器下載資源,否則從本地“數據目錄”獲取。LuaBundleMode設爲true,則從AssetBundle解壓Lua腳本,否則直接讀取項目腳本。

可以打開AssetsLuaFrameworkEditorCustomSettings.cs看到所有可以供lua調用的類

添加新的Lua腳本到AssetBundle包:

將Lua腳本存放到 Assets/LuaFramework/Lua 目錄,因爲,當按下LuaFramework-Build XXX Resources的時候,框架會自動將Assets/LuaFramework/Lua下的所有內容打成AssetBundle包,放在StreamingAssets下,所以可以發現,StreamingAssets文件夾下會有個Lua文件夾,裏面放的就是我們Assets/LuaFramework/Lua在打包之後的結果

注意1:打開StreamingAssets/Lua,會發現,這個文件夾下大致分爲兩部分,3rd文件夾,和一堆資源包
在這裏插入圖片描述
其中,資源包的命名特點是對應着路徑信息的,例如lua_3rd_cjson和lua_3rd_cjson.unity3d這一組資源包,他對應着的是LuaFramework/Lua/3rd/cjson裏面的Lua文件,告訴使用者,我這組資源包就是這個文件夾下的lua文件打包出來的結果,那麼我們的 打包出來的資源包又是誰呢?那就是: 這一組資源包
在這裏插入圖片描述
在這裏插入圖片描述
注意2:我們會發現StreamingAssets/Lua文件夾下,除了有一堆資源包外,還有一個3rd文件夾,裏面放的又是啥呢?其實,我們可以打開Assets/LuaFramework/Lua/3rd 目錄,然後打開其中一個,例如cjson的文件夾,可以發現,這文件夾裏面除了放置一些lua文件外,還有一些其他的txt配置文件或說明文件,所以,這個StreamingAssets/Lua/3rd文件夾下,放的就是這些不是lua文件的文件資源

注意3:綜上所述,如果我們要打包一個自定義的Lua文件(不是框架提供的Main.lua文件)的話,那麼我們完全可以先在Assets/LuaFramework/Lua這個文件夾下,自定義一個專門放我們編寫的Lua文件的文件夾,然後當打包出來後,會發現,StreamingAssets/Lua下會有一個你自定義的文件夾名.unity3d這麼一組資源包,例如:
在這裏插入圖片描述
這裏的MyLua以及底下的MyLua文件是我自定義的,然後當我打包出來後,會發現StreamingAssets/Lua這個文件夾下多了一個與之對應的一組資源包
在這裏插入圖片描述
注意4:
在這裏插入圖片描述
更改Lua入口,不用框架提供給我們的Main.lua這個文件:
找到LuaManger這個C#類,然後找到StartMain()這個方法,

只需要把lua.DoFile裏面的參數修改爲你自定義的lua文件名,然後LuaFunction main=lua.GetFunction(“Main”)這一行的括號內的參數,修改爲作爲入口且存在於你自定義的lua文件中的lua方法即可,當然,
在這裏插入圖片描述
這段代碼是可以刪掉的,因爲不管有沒有設定入口函數,系統都會把DoFile設置的lua文件從頭到尾來讀,而之所以作者這樣寫,感覺是爲了讓Lua代碼寫得更好看而已,因爲你一開始就調用Main函數的話,那麼你就可以把你要運行的lua代碼通通寫到這個Main函數中,這樣的話,看起來lua代碼不會那麼散亂吧!但是不管是不是自己定義lua入口文件,最好都放在Assets/LuaFramework/Lua下,不要再另外加文件夾,因爲放在Assets/LuaFramework/Lua這路勁下的所有lua文件都會直接一同打包在lua.unity3d這麼一個資源包中,而程序設置好就是去這個包裏讀取lua的入口文件,除非你會改動lua入口文件的讀取路徑,不然就安分一些!

注意5:可以讀取多個lua文件
在這裏插入圖片描述
創建新的AssetBundle包的步驟:

LuaFramework/Build XXX Resources的功能全都寫在了Assets/LuaFramework/Editor/Packager.cs這個C#類中,以及跟隨打包生成的StreamingAssets/files這個MD5校驗碼文件是怎麼生成的,也是寫在這個Packager.cs文件中,所以,以後你如果想打包一些這個框架沒提供的平臺資源的話,你可以到這個Packager模仿着去增加對應的打包方法

4.x : 在定義了打包函數的腳本 Assets/LuaFramework/Editor/Packager.cs 添加新增資源包的信息

5.x : 在Inspector設置資源包名,在Packager.cs添加5.x的打包函數調用

因爲這個文檔是更新於2018/4/27的,所以這裏講的是這個日期所對應的最版本的新framework的打包:
注意1:
打包函數的主體代碼在Packager.cs中的BuildAssetResource,HandleExampleBundle,AddBuildMap,HandleLuaBundle,HandleLuaFile這五個方法
作用:
BuildAssetResource是進行資源文件夾的刷新,並且根據AppConst這個類裏面的靜態布爾屬性的設置的情況的不同,分別調用HandleExampleBundle,HandleLuaBundle,HandleLuaFile函數
HandleExampleBundle,他的作用是告訴使用者怎麼打包美術素材,他的框架格式是什麼,如果你有想打包的美術資源,你可以根據這個格式自定義一個例如叫(HandleMyWorkBundle)的方法,來進行打包,這個AddBuildMap方法裏面的參數意思:
第一個參數:打包出來的資源叫什麼名字,這個名字是用AppConst.ExtName(值爲unity3D)作爲後綴名
第二個參數:你要打包的這個資源本來是什麼格式的資源,*.XXX代表所有這種格式的資源
第三個參數:這個框架是對指定路徑的文件夾進行整體打包操作的,所以,第三個參數是,你要打包的資源位於項目哪個文件夾中

在這裏插入圖片描述
所以綜上所述,如果你要打包美術資源,請先在項目中創建一個專門存放你自己的美術資源的文件夾,然後在Packager.cs中新建一個函數,裏面的代碼請複製這個HandleExampleBundle的,然後修改AddBuildMap參數,在完成上述步驟後,因爲你的項目打包出來之前,目測是會刪掉那些框架提供的事例場景的,所以要把AppConst中的ExampleMode設置爲false,最後在Packager.cs這裏加上拉黑的代碼,調用你的自定義打包函數
在這裏插入圖片描述

HandleLuaBundle,HandleLuaFile這兩個函數是告訴用戶怎麼將Lua文件打包成AssetBundle的,通常狀況下不建議修改,因爲功能已經很齊全了,當然,如果你想將這種功能實現應用到如Xlua中,可以去看看這兩個函數是怎麼寫的。
因爲在我看來,所謂的熱更新主要由三部分組成:
1:C#與Lua的互相調用機制
2:Lua文件的打包
3:網絡傳輸,校驗

所謂的XLua,ToLua,ULua…只是提供了C#與Lua的互相調用機制,並沒有提供其餘兩者的功能實現,所以如果自己想開發個基於如Xlua這樣的熱更新框架,可以參照這個基於ToLua的框架

打包的額外小知識:

在這裏插入圖片描述
在這裏插入圖片描述
1:打包出來可以發現會有個files的文件,這個文件記錄了所有lua資源包和美術素材資源包的MD5碼,客戶端的files的MD5碼會與這個每次打包一次都會更新的MD5碼進行比對,發現有不同的MD5碼就會自動進行對這個MD5碼所對應的資源進行更新操作

2:每個美術素材資源包都會有一個對應的依賴信息文件,這個依賴信息文件記錄的是這個美術素材包的共用材質/貼圖在哪個美術素材包中(所謂的共用美術素材,指代的是,例如兩個prefab,他們共用一個材質,所以你不但要打包兩個prefab,還要打包他們所共用的美術素材,而這個共用的美術素材打包出來後就是一個共用美術素材包)

例如:在上面的截圖中可以看到,我的Cube和Sphere共用的材質是ShareMaterial,而材質所用的貼圖是MyTexture

因爲這個框架是對文件夾整體打包的,所以打包出來的結果分別爲myterials/mymaterials.unity3d,myprefabs/ myprefabs.unity3d和myprefabs/myprefabs.unity3d這三組結果,“/“左邊是記錄素材包依賴信息的文本文件(可以用文本編輯器打開看),“/”右邊是真正的美術資源包
依賴信息的文本文件如圖:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
圖中的Assets代表的是,你這打包出來的東西的來源
Dependecies代表的是,你這打包出來的東西又依賴於哪個打包出來的東西

使用框架對下載的資源進行加載:

在此之前,你要明白爲何這個框架可以讓你的lua腳本訪問到C#的類的,當你按下Lua/Clear wrap Files的時候,會彈出這麼個框框
在這裏插入圖片描述

此時,你必須要按下確定,那麼這個框架就會自動給你生成一堆Wrap結尾的C#文件,如下圖所示例如LuaFramework_AppConstWrap,那麼這個自動生成的文件所對應的就是一個叫AppConst的類,如此類推,而這個框架就是讓Lua通過訪問這些自動生成的wrap的類來達到訪問C#類的目的(注意:這些自動生成的wrap類不要去更改)

在這裏插入圖片描述

接下來我們講一下資源的加載和生成,在這裏我會講述三種加載方法

1:自定義加載函數,供Lua訪問
步驟1:首先在ResourceManager文件下創建截圖中的東西
在這裏插入圖片描述
在這裏插入圖片描述
(註釋已經說明了這些我自己寫的代碼的作用)

步驟2:因爲你修改了C#代碼,所以你要按下Lua/Generate All或者Clear Wrap Files-確定,讓框架重新編譯出新的wrap文件,然後因爲你修改的是ResourceManager,所以你在搜索欄搜索

在這裏插入圖片描述
此時,你會搜索出一組C#類,然後打開ResourceManager所對應的自動生成的Wrap文件(也就是拉黑的第一個C#文件)
在這裏插入圖片描述

請注意這部分代碼,可以發現,你在ResourceManager新增的LoadPrefab方法已經存在於這個L.RegFunction中了,這意味着,你可以在Lua中調用你這個自定義的加載方法了,如果想更詳細地知道,Lua所調用的實質是啥,可以看看這段代碼:

在這裏插入圖片描述
在我看來,這個框架將你C#的方法,以Lua能夠讀懂的形式又重新弄成對應的代碼,如上圖,然後放在對應的Wrap中同時也在Wrap中用L.RegFunction去註冊讓Lua能夠訪問,所以Lua真正要訪問的,其實是這個重新生成的方法

現在我們已經更改了ResourceManager並且也生成了與其對應的供Lua調用的Wrap包,那麼接下來,我們就在Lua中用ResourceManager中的我們自定義的LoadPrefab方法去從指定的下載下來的AssetBundle包中把指定的美術素材生成在Scene視圖中,Lua代碼如下:

在這裏插入圖片描述
在這裏,我們的C#代碼調用方式是“命名空間.類名”+如果是實例方法,就“:方法名(參數列表)”,如果是靜態方法或構造方法就“.方法名(參數列表)/.New(參數列表)”,當然,考慮到我們的自定義C#腳本有些是沒有命名空間的,所以沒有命名空間的C#類就不用把命名空間加上(後面會說怎麼利用這框架使得lua也能使用我們的自定義C#腳本),在這裏我們要使用到框架提供的一個C#類,叫LuaHelper,他可以讓我們快速獲得C#的類的實例,其中包括各種繼承了Mono的類(如這些框架提供的XXXManager)

接着,我們看到,在把Cube遊戲對象從myprefabs.u3d的AssetBundle包中解壓出來之前,首先要解壓它所依賴的美術素材,因爲Cube依賴於ShareMaterial,ShareMaterial依賴於MyTexture。所以加載的順序是MyTexture->ShareMaterial->Cube,這樣的順序加載纔不會讓Cube的材質丟失

最後我們來看看效果:
在這裏插入圖片描述

2:直接利用框架的加載函數,用Lua訪問
第一種方法其實是舊版框架的做法,起碼2017年剛學這框架就是這樣做的,當然在最新版的框架,這做法還是能行得通的,但是,現在是2018/4/27的最新版的框架,所以這裏介紹另外一種做法:
同樣的,也是在ResourceManager中,框架提供了3個重載的LoadPrefab方法

在這裏插入圖片描述

第一個參數:你要加載的AssetBundle包的名字
第二個參數:你要加載的是這個AssetBundle包中的哪些美術素材
第三個參數:回調方法(這個方法的參數列表有一個UnityEngine.Object[]類型的變量的,這個數組變量存的就是你所加載的美術資源)

Lua中的調用方式:
在這裏插入圖片描述
注意,這裏的go是userdata類型,遍歷的時候必須用Length去取得go的長度纔行,不然會報錯
在這裏插入圖片描述
最終結果:

3.與第一種加載方式的代碼一樣,只不過,我們不把加載函數寫在ResourceManager中,而是新建一個C#文件,把加載方法寫在這個C#文件中,然後通過CunstomSetting去使得框架生成對應的Wrap文件,然後用Lua去調用

步驟1:創建腳本,這裏我創建了一個叫MyCSharp的腳本
在這裏插入圖片描述
在這裏插入圖片描述
步驟2:找到CustomSetting這個框架提供的類,把你自定義的MyCSharp註冊到這裏:
在這裏插入圖片描述

步驟3:按下Lua/Clear wrap files -> 確定 或者Lua Generate All生成wrap文件,生成wrap文件後,搜索MyCSharp,你會發現,搜索結果多了一個與MyCSharp文件對應的Wrap
在這裏插入圖片描述

打開這個wrap,看看Lua能夠調用的方法

在這裏插入圖片描述
可以發現,這裏有個New方法也是可以供Lua調用的,這個New方法是讓Lua新建對象用的,可以理解爲Lua的構造方法

接着,我們看看Lua代碼應該怎麼寫,如圖:
在這裏插入圖片描述

結果:
在這裏插入圖片描述
使用NetBox在本地搭建一個服務器程序,然後利用這個框架,本地資源更新到本地,模擬整套熱更新流程:

步驟1:下載NetBox
在這裏插入圖片描述
然後,你這個Netbox所在的文件夾就會成爲默認的服務器資源文件夾,客戶端是會從這服務器資源文件夾下載資源來更新的

步驟2:開啓NetBox,直接雙擊
在這裏插入圖片描述
就可以開啓,當開啓NetBox後,這裏會有黑色箭頭

在這裏插入圖片描述
步驟3:驗證NetBox真正開啓:
在這裏插入圖片描述
所處的目錄新建一個html後綴的網頁文件
在這裏插入圖片描述
我這裏是個叫index.html,然後用文本編輯器打開這個index.html文件,在裏面寫一些html代碼用以網頁顯示,如:
在這裏插入圖片描述
然後,你開啓NetBox後,瀏覽器會自動打開來到這個index.html
在這裏插入圖片描述
當然,你也可以自己手動在瀏覽器地址欄打上localhost:80來訪問,訪問成功則代表NetBox服務順利開啓

步驟4:更改框架提供的AppConst設置
在這裏插入圖片描述
在這裏插入圖片描述
ExampleMode設置爲false,意思是什麼,前面的關於加載資源的部分已經說過,請仔細閱讀
將UpdateMode設置爲true,意思爲從WebUrl提供的網址進行加載
將LuaBundle設置爲true,意思爲,程序所讀的Lua腳本是從資源包中解壓出來的Lua腳本,
而不是 這裏的腳本直接讀取
在這裏插入圖片描述
WebUrl則填上你的服務器資源文件夾物理路徑(物理路徑指代的是如:C:/XXXX/XXX)所映射成的網址,因爲我使用的是NetBox,所以他會把他所在的這個物理路徑:
在這裏插入圖片描述
自動映射爲http://localhost:80/,所以我在這裏填上了這網址

步驟5:因爲你修改了框架的AppConst,所以你要按下Lua/Clear wraps Files->確定,爲了安全起見,在編譯完成後,再按下Lua/Generate All

步驟6:爲了測試熱更新,你必須要有一個原版客戶端,但是又由於你是基於這個框架開發的項目,也就是說,你在項目仍在開發階段就已經把這框架導入了,所以,你在導出原版客戶端之前,先按下LuaFramework/Build XXX Resource,讓框架把你項目中用到的資源打包到StreammingAssets文件夾
在這裏插入圖片描述
然後你再File->BuildSetting,將你的項目導出爲原版客戶端,之所以要先按下LuaFramework/Build XXX Resource,是因爲這個框架所提供的一些代碼資源,和files文檔也是必須要先存在於你的客戶端的,特別是files,你以後的熱更新就是根據這個files文件的MD5碼與服務器資源文件夾的files的MD5碼進行比對,看哪些資源MD5碼不同,就下載更新哪個資源的
做完上述一切後,我Buil出了這麼個客戶端

在這裏插入圖片描述
此時,你留意一下你的C盤的根目錄,你會發現,暫時是不存在一個叫luaframework的文件夾的

現在,我們打開這個Build出來的客戶端,看看有何效果

首先,你會發現C盤根目錄底下會多出個luaframework文件夾,這文件夾是會在客戶端運行的時候,自動生成在客戶端一則的(根據不同平臺而不同),因爲我這個客戶端是PC平臺,所以就自動默認生成在這裏,而他的作用,是先把你的原版客戶端的資源複製一份擱在這裏
在這裏插入圖片描述
然後根據files的MD5碼去和服務器資源文件夾的files的MD5碼進行對比,以此來判斷應該從服務器的資源文件夾下載更新哪些資源到我的客戶端上

然後你又會發現,客戶端打開後
在這裏插入圖片描述
這裏毛都沒有一條,那是因爲,你還沒把原版的StreammingAssets下的打包好的資源放在服務器資源文件夾裏,那就意味着,客戶端的luaframework文件夾中的file的MD5碼不能和服務器的file的MD5碼進行比對了,所以纔會出現這情況,解決方法是
在這裏插入圖片描述
把拉黑部分,通通複製到你的服務端資源文件夾

在這裏插入圖片描述
此時,重新打開你的客戶端,你會發現,你的客戶端又可以正常運行了
在這裏插入圖片描述

步驟7:更改原版Lua代碼,然後熱更新到這個Build出來的原版客戶端上
在這裏,我修改的是項目的Main.lua文件,

在這裏插入圖片描述

本來Lua代碼是這樣的
在這裏插入圖片描述
然後我修改成:
在這裏插入圖片描述

此時,我們按下LuaFramework/Build XXX Resoure
此時,你會發現,你新Build出來的資源中的files文件的這個Main.lua所在的資源包和其他Lua資源包所對應的MD5碼,與原版的會有所不同,而關於美術的資源包的對應的MD5碼卻沒有變化,如圖:(左圖爲客戶端MD5碼,右圖爲新打包的MD5碼)

拉黑部分和其下方的是Lua資源包的MD5碼,會發現都改變了,拉黑部分上方是美術資源包的MD5碼
在這裏插入圖片描述
然後,我們再把新Build出來的

在這裏插入圖片描述
覆蓋掉,服務器資源文件夾的原版的打包資源

在這裏插入圖片描述
最後,重新打開客戶端看效果,可以發現,熱更新成功:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章