unity gameframework xlua lua自定义加载,兼容ab包
在GameEntry.Base.EditorResourceMode的情况下,直接通过File来加载
public static byte[] CustomLoader(ref string filepath)
{
var scriptPath = string.Empty;
filepath = filepath.Replace(".", "/") + ".lua.txt";
scriptPath = Path.Combine(Application.dataPath, luaScriptsFolder);
scriptPath = Path.Combine(scriptPath, filepath);
return GameUtility.SafeReadAllBytes(scriptPath);
}
当游戏发布,资源被打成AB包后,File是获取不到对应的文件的
-
ResourceComponent添加方法LoadBytes 方法
public void LoadBytes(string abName, LoadBytesCallbacks callback, object userdata) { if (ResourceMode == ResourceMode.Updatable) { m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(ReadWritePath, abName + ".dat")), callback, userdata); } else if (ResourceMode == ResourceMode.Package) { m_ResourceHelper.LoadBytes(Utility.Path.GetRemotePath(Path.Combine(ReadOnlyPath, abName + ".dat")), callback, userdata); } }
-
创建XLuaComponent,并添加进Game Framework的Customs中
public class XLuaComponent : GameFrameworkComponent { private XLuaManager m_LuaManager; public XLuaManager LuaManager => m_LuaManager; //用来存放lua的代码,同时释放调m_LuaAb private Dictionary<string, string> luaDict; private void Start() { m_LuaManager = new XLuaManager(); } private void Update() { } /// <summary> /// 在GF流程 Proload结束后调用 /// </summary> public void Init() { if (!GameEntry.Base.EditorResourceMode){ LoadLuaAb(); }else{ //lua初始化 这里可能有异步加载 mainlua 的操作 m_LuaManager.Init(); } } private void OnDestroy() { } private void LoadLuaAb() { print("LoadLuaAb"); GameEntry.Resource.LoadBytes("LuaScripts", new LoadBytesCallbacks(OnLoadBytesSuccess, OnLoadBytesFailure), null); } private void OnLoadBytesFailure(string fileUri, string errorMessage, object userData) { Debug.LogErrorFormat("Bytes {0} File Load Failed:" + errorMessage, fileUri); } private void OnLoadBytesSuccess(string binaryAssetName, byte[] binaryBytes, float duration, object userData) { AssetBundle m_LuaAb = AssetBundle.LoadFromMemory(binaryBytes); luaDict = new Dictionary<string, string> (); foreach(var name in m_LuaAb.GetAllAssetNames()){ var fileName = name;//Path.GetFileName(name); var textAsset= m_LuaAb.LoadAsset(name) as TextAsset; luaDict.Add(fileName,textAsset.text); } m_LuaAb.Unload(false); //lua初始化 这里可能有异步加载 mainlua 的操作 m_LuaManager.Init(); } public string LoadAssetSync(string assetName) { string str = null; if (GameEntry.Base.EditorResourceMode) { string path = Application.dataPath.Replace("Assets", "") + assetName; if (!File.Exists(path)) { Debug.LogError("Lua {0} File Load Failed:" + path); return null; } using (StreamReader sr = new StreamReader(path, Encoding.UTF8)) { str = sr.ReadToEnd(); } } else { string asset = assetName.ToLowerInvariant(); string data = luaDict[asset]; if (data != null) { str = data; Debug.Log("LoadAsset "+asset); } else { Debug.LogError("Lua {0} File Load Failed:" + asset); } } return str; } }
-
在XLuaComponent的Init方法中载入luaAb资源,并将lua的源码都放入Dictionary中。见源码
-
重写CustomLoader方法
public static byte[] CustomLoader(ref string fileName) { fileName = fileName.Replace('.', '/'); string assetName = AssetUtility.GetLuaAsset(fileName); string data = string.Empty; data = GameEntry.XLua.LoadAssetSync(assetName); if (string.IsNullOrEmpty(data)) { Log.Error("File content is null. file:{0}", fileName); return null; } return System.Text.Encoding.UTF8.GetBytes(data); }
-
注意,使用gf打AB包的时候,将所有lua文件都打在LuaScripts.bat的文件中,所以加载的时候全加载进来