Lua作為Unity首選的熱更新方式,現在基本上成了商業游戲的標配(iOS的機制)。同時不得不說的是,使用Lua,可以避開大型項目中長時間編譯的問題(其實這個問題在新版本的Unity中已經解決)。還有一個好處是,服務器可以推送一段Lua代碼到客戶端,相當於做實時Patch,維護非常高效。但是又不得不提,Lua是一個坑,開發效率和游戲運行性能都會受到一定的影響。所以使用者一定要在適當的環境下使用,莫要一概而全。
回到正題,這里處於個人習慣,使用tolua#(簡稱tolua)。tolua打包lua代碼時有個流程,十分不友好。它會將.lua文件復制到temp文件夾下,並改名為.byte文件,然后將這些.byte文件打包成AssetBundle。但是如果我們開發了很多文件,就會在項目中生成大量的無用的.byte文件。究其原因,是因為unity無法識別.lua文件,所以無法打包到Assetbundle中。
所以我們要做的是借助ScriptedImporter幫助Unity識別.lua文件。
ScriptedImporter是Unity2017.1引入的功能,使用它,我們可以讓Unity識別很多它無法識別的文件,比如Excel(.xlsx)文件,自定義的一些后綴的文件。見《Unity插件開發:ScriptedImporter和AssetImporter》
根據上文中提到的造成tolua生成的原因,我們只要把.lua文件識別為一個TextAsset就能解決問題,因為.byte文件本身就被Unity識別為TextAsset。所以我們可以寫一個LuaImporter,繼承於ScriptedImporter,讀取文件的文本生成一個TextAsset作為被識別的物體即可
LuaImporter.cs
using System.IO; using UnityEditor; using UnityEditor.Experimental.AssetImporters; using UnityEngine; [ScriptedImporter(1, "lua")] public class LuaImporter : ScriptedImporter { public override void OnImportAsset(AssetImportContext ctx) { var text = File.ReadAllText(ctx.assetPath); var asset = new TextAsset(text); ctx.AddObjectToAsset("main obj", asset); ctx.SetMainObject(asset); } }
將LuaImporter.cs放在工程的Editor文件夾下,編譯完成后,項目會自動重新導入所有的.lua文件。通過下圖我們可以看到無法識別.lua文件的樣子
通過LuaImporter之后Unity將.lua文件識別為TextAsset,不僅圖標變了,右側還顯示出了代碼。
但是我們看C#代碼的時候,細心的可以看到是這樣的情況
那么我們是否也能實現的,答案是肯定的。Unity提供ScriptedImporterEditor來繪制自定義Importer的Import面板展現。
[CustomEditor(typeof(LuaImporter))] public class LuaImporterEditor : ScriptedImporterEditor { public override void OnInspectorGUI() { } }
其本質還是一個Editor,所以也可以按照自己的需求自定義Import面板。這里什么都不寫,就是什么都不要。所以結果如下圖所示
OK至此就完成了.lua的識別工作。
至於打包的方法就很簡單了,直接打包這些.lua文件即可。
如果你項目中有那些需要識別但是Unity無法識別的文件的話,使用ScriptedImporter吧。
參考文檔
https://docs.unity3d.com/Manual/ScriptedImporters.html
https://docs.unity3d.com/ScriptReference/Experimental.AssetImporters.ScriptedImporter.html
https://docs.unity3d.com/ScriptReference/Experimental.AssetImporters.ScriptedImporterEditor.html
tolua#開源庫