Lua代码文件的加载不同于unity的资源加载,异步加载机制对Lua文件的加载很不友好,因为代码都是同步加载执行的。
我们项目原来Lua代码就是独立于AAS系统加载的,有一套Lua代码文件管理系统,而Lua代码不走AAS系统的话,就需要单独设计一套Lua代码更新机制,需要更多的工作量,且整体做法上没有全使用AAS系统更统一些。
因此能使用AAS更好,而Lua代码走AAS有三种方案设想:
-
Lua文件走AAS,但是不由AAS包装成bundle,而是保存为Raw文件,直接由原来设计的独立文件加载系统进行读取,而更新则走AAS的更新机制。研究了一段时间,可能通过自定义Provider可以实现,但目前没进展,跳过该方案。
-
直接使用AAS,加载使用异步加载,在游戏启动时先加载全部的Lua代码到内存,后续读取缓存就可以实现正常的Lua同步加载逻辑,这应该是之前大家们使用的最常见的方式。
-
直接使用AAS的同步加载功能,AAS在1.17.4-preview版本提供了同步加载方法:WaitForCompletion()。因此Lua代码的加载可以很顺利的使用该方法实现。
自然而然,我们选用的是第三种方案。我们Lua代码走的是ToLua框架,实现时只需要修改原有的ToLua加载Lua文件的代码即可,修改大概思路如下(首先在Tolua.cs的Loader函数中修改读取方法为下面的ReadFile函数):
public override byte[] ReadFile(string fileName)
{
AsyncOperationHandle<TextAsset> handle = Addressables.LoadAssetAsync<TextAsset>(fileName);
handle.WaitForCompletion();
byte[] bytes = handle.Result.bytes;
Addressables.Release(handle);
return bytes;
}
这样就可以像之前一样无感使用AAS加载Lua代码了。
注:1.18版本后在异步加载回调中使用同步加载方法有地方会报错,具体细节没研究,于是决定使用1.17版本。可参考:1.18同步加载报错。由于1.18.4版本之前即使勾选AddressableAssetSettings配置中的Disable Catalog Update on Startup,在AAS启动时依然会去服务器拉取catalog的hash数据,拉取后会判断缓存文件的hash值跟服务器不一致就不使用缓存文件,导致更新时会跳过中间版本,从而多更新了很多资源,因此还是需要更新AAS版本,不过上述同步加载的报错目前用协程方法替代回调可以解决。