Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享

        

一入热更深似海啊,没有热更是真恼火啊,干啥啥不方便,动不动就得重新发包;说实在的,也是工作之余研究这个,在原有框架基础上接入这个热更,既要保持原有功能,还要支持热更,实实在在、断断续续搞了这么久,终于是接入并测通了,这一路是坎坎坷坷,下面把走过的弯弯绕绕记录下,希望对后来想接入的小伙伴有帮助吧。

        其实之前早就有动热更新的心,无奈现在没做游戏了,项目这块基本都是定制开发,所以这块一直搁置,不过之前有考虑过lua和xlua也看过ILRuntime,但是一直耿耿于怀,要用另外一种语言去搞,而且咱又是一直干C#的,而且这几个实现机制都是需要一个独立的vm,编译完在解释一套,而且有的还不能直接使用,需要特殊处理,看着看着就没心思搞了;这时看到了HybridCLR,说实话,一开始看到的是huatuo,这俩其实到后来了解到是一个东西,看了几天,发现这个的实现机制从根本上解决了独立vm的问题,具体的HybridCLR官网说的更清楚,使用了AOT + Interpreter混合运行方式,HybridCLR使得il2cpp变成一个全功能的runtime,原生(即通过System.Reflection.Assembly.Load)支持动态加载dll,这个就是亮点,在实现热更的路上,它占了绝对的分量。

        看到这里的,默认你已经在接入HybridCLR的路上了,而且已经接入,遇到问题了,如果是还没接入的,可以查看Unity 热更新 之 huatuo(HybridCLR) 和 Unity 热更新 HybridCLR 对接到项目中 了解和接入。

        这里使用的Unity版本是 2021.3.6f1 , HybridCLR是 v2.3.0 , il2cpp_plus版本是v2021-2.2.0一切准备就绪后,开始坎坷之路吧,Lz这里主要测试的平台有PC、Android、WebGL,感觉最明显的就是WebGL限制是真多,所以在这里爬坑也是绞尽脑汁了。

        所有常见的问题HybridCLR常见错误(这里是链接,可以跳过去看)里其实也都有,只是有的指出了方向,但具体怎么解决人家也没细细说明,必经错误千奇百怪,遇到了至少人家有个指引方向,剩下的就得靠自己慢慢爬了。

        别的不多说了,进入主题。

        问题:项目已经进入热更新,可以使用,但是想进一步使用热更新,热更项目中原有的dll。

        正常接入后,打包出来没问题,然后有要求,比如项目之前就有已经引用的dll或则框架要求,把已经统一的功能封装出去,最终形成dll在项目中引用使用,不管什么原因,你想实现已经引用的外部dll的热更新。

        在HybridCLR中,是有这块的功能的,

 这里需要配置外部搜索dll路径和需要热更dll的名称,注意:这里的设置一定是同时设置,这样热更新才能找到需要热更的dll在哪里,而且外部搜索dll路径是以Assets为父级(根目录)去找的,这里Lz直接放在了项目内,如果你放在项目外,就要填写项目外地址了。

 确定配置完成后,真正的问题就从此开始了。

1.报错:Building Library/Bee/artifacts/xxxx failed with output: Fatalerror in Unitiy CIL Linker Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly:'xxx'

这里Lz经历完爬坑后,总结先说下,他这里的配置,是将你选择的dll,在发布时,做了过滤,也就是不会打包到包中(AOT),也就意味着,你的AOT代码中,如果有对他们的引用,将会报错(Building Library/Bee/artifacts/xxxx failed with output: Fatalerror in Unitiy CIL Linker Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly:'xxx'),或者你的AOT中没有引用,但是你外部热更的dll中有引用,同样会报这个错,根本原因是,热更(HybridCLR)把你要外部热更的dll过滤掉了(相当于删除),所以在打包时找不到引用,你说能不报错吗?这里爬坑了好久,希望对你有帮助,一定要冷静分析你要热更的dll中有没有其他地方在引用(如果是AOT那就必须分离掉那块功能,如果是外部dll,要么一起加入热更,要么把那块功能分离掉)。这个错误部分平台,都适用。

2.报错:WebGL平台打包时遇到 undefine symbol: send file 之类的错误

这个就纯属WebGL平台限制问题,一般主要是本地读取的一些问题,比如File操作,这里LZ建议都是用加载(UntyWebRequest)的方式(那个平台都适用,不会有问题),只是在这要注意的是,不同平台在使用网络加载的时候,要加入平台前缀,不然会加载失败 提示错误:Cannotconnect to destination host等(比如Android要加jar:file://   PC要加file://)

3.注意一点,WebGL平台必须使用il2cpp的全局安装,这块官网说的比较明确,而且处理方法也很详细可以按照流程操作.如果还不懂的可以直接看官网这个错误:打包WebGL平台出现 build.js: undefined symbol: RuntimeApi_LoadMetadataForAOTAssembly (referenced by top-level compiled C/C++ code)的解决办法。

4.运行时,报错资源挂在的脚本丢失了ScriptMissing

排除了你版本的问题,最大的可能就是你的热更新程序集没有加载,或者你在加载使用时,程序集还没有加载,要看下逻辑是不是有问题。

5.运行时,遇到Unity: TypeLoadException: Could not load type 'XxxType' from assembly 'yyyAssembly'

一般正常操作,.net必须使用.net4.x,然后最有可能的就是你程序集加载的顺序的问题呢,比如,如果A依赖于B,那你应该先加载B,再加载A,你加载顺序反了也会报这个错,毕竟代码的执行顺序都懂的,有依赖关系,一定是先加载被依赖的。

6.运行时,报错couldn't be loaded because it has not been added to the build settings or the AssetBundle has not been loaded. 或者 couldn’t be loaded because it has not been added to the build settings. 

是因为在加载场景时,没有找到对应的场景文件,第一种时把场景文件打包为ab包加载,第二种则是把场景加入到BuildSetting中,两者看起来都能明白,但是在实际操作时,遇到问题时,肯定首先查过了,这两种都是不在问题发生范围内,那究竟时什么原因呢。其实第二种情况比较好理解,如果你不想热更你的场景,那就把场景直接拖入的的BuildSetting中,打包出来,正常切换场景是没问题的,但是,既然做了热更,你肯定不想这么做,那唯一的办法就是把场景打成ab包,但是打成ab包后,在Editor模式下加载没问题,发布出来了,就找不到场景了,(仅个人推测啊,在Editor模式下,加载可以不区分大小写,但是发布出来以后,是区分大小写的,这点注意下,就是你ab包的名称和场景名称要统一),有个加载方式是加载ab包后,有个ab.GetAllScenePaths()[0];可以读到场景文件的整个路径,在加载场景时,传入这个整个路径是不会出现问题的,而且可以加载成功,(这里lz遇到了,名称一摸一样,但是就是加载不出来,提示not been load,因为一般的做法要么根据id加载,要么跟据场景名称加载,特殊情况,开始要读完整路径加载),这个问题到这里就完结了,希望你这么操作也能加载成功。

猜你喜欢

转载自blog.csdn.net/u013774978/article/details/131565741
今日推荐