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

这篇具有很好参考价值的文章主要介绍了Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享,Unity应用及扩展,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中,是有这块的功能的,Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享,Unity应用及扩展,webgl

 这里需要配置外部搜索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加载,要么跟据场景名称加载,特殊情况,开始要读完整路径加载),这个问题到这里就完结了,希望你这么操作也能加载成功。

7. 找不到引用库 resolve AOT dll:{assemblyName} 失败! 请确保主工程已经引用了该dll并且正确生成了裁剪后的AOT dll。更多请参阅常见错误文档。

如果你是hbyridclr v3.3.0,那么你在执行HybridCLR-》Generat下载Aot或者Bridge时,就是生成aot和建立桥接的时候,汇报这个错误,时因为hybridclr找不到你配置的外部热更新dll,按照官网指示,lz这里主工程里有引用,正常build也是可以的,但就是报这个,一番跟踪源码,才知道他是在aot时,通过dnlib的刷新项目内的程序集(assembly),找到了你的外部引用dll,但是在处理

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

asseblyPathResolver时, 并没有把我们的dll在aot时,放到他能处理的aot目录(HybridCLRData\AssembliesPostIl2CppStrip\StandaloneWindows64),StandaloneWindows64是对应平台的目录,会有Android、WebGL等,这里需要把报错的dll手动给让复制到这个目录下,就ok了 。

修改源码,实现自动拷贝

需要修改HybridCLR.Editor.Commands下的StripAOTDllCommand.cs

第一步,添加方法CopyIDEDllAotAssemblies()

/// <summary>
        /// 拷贝自定义 热更新下的dll到 hybridclr可识别的aot目录下
        /// </summary>
        private static void CopyIDEDllAotAssemblies(BuildTarget target)
        {
            var externalDirs = HybridCLRSettings.Instance.externalHotUpdateAssembliyDirs;
            var dstPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
            List<string> allHotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;

            foreach (var dir in externalDirs)
            {
                DirectoryInfo root = new DirectoryInfo(dir);
                FileInfo[] files = root.GetFiles("*.dll");
                foreach (var fp in files)
                {
                    string fileouExt  = Path.GetFileNameWithoutExtension(fp.FullName);
                    string file = fp.Name;
                    if (allHotUpdateDllNames.Contains(fileouExt))
                    {
                        Debug.Log($"[CopyIDEDllAotAssemblies] 过滤热更新assembly:{file}");
                        continue;
                    }
                    Debug.Log($"[CopyIDEDllAotAssemblies] copy strip dll :{fp.FullName} ===>>> :{dstPath}/{file}");
                    File.Copy($"{fp.FullName}", $"{dstPath}/{file}", true);
                }
            }
        }

第二步,在 GenerateStripedAOTDlls()方法中,添加该方法的引用

public static void GenerateStripedAOTDlls()
        {
            GenerateStripedAOTDlls(EditorUserBuildSettings.activeBuildTarget, EditorUserBuildSettings.selectedBuildTargetGroup);
            CopyIDEDllAotAssemblies(EditorUserBuildSettings.activeBuildTarget);
        }

8. FileNotFoundException: Could not find file 'xxx/HybridCLRData\HotUpdateDlls\StandaloneWindows64\xxx.dll'.

这块是hybridclr处理aot代码库逻辑问题,目前(lz从v2.3.0 到 3.3.0),一直遇到这个问题,就是在hybridclr配置过的程序集,他会处理,但是如果你是想更新原本项目中已有的dll,并不是项目开发中创建的程序集,就会遇到这个问题,hybridclr是没有记录这些外部热更新dll逻辑的,虽然他们在设置界面里留了配置外部更新dll的位置,但是在拷贝到aot目录或者hotfix目录时,没有相应逻辑的.

如果你是hybridclr v2.3.0,而且你想热更项目原有的应用dll,在配置了外部热更新dll后,hybridclr并没有把你配置的热更新dll放到他们能识别的热更新dll目录下,导致你在过滤热更新后,找不到你外部的dll,这里lz翻源码,添加了逻辑,拷贝到他们能识别的目录下

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

修改源码,拷贝我们外部引用的dll到他们可识别的目录下:

第一步:修改HybridCLR.Editor.Link下的Analyzer.cs

添加方法

public void CopyHotAssemblyToHotDllDir(List<string> rootAssemblies)
        {
            using (var assCollector = new AssemblyCache(_resolver))
            {
                var gs = HybridCLRSettings.Instance;
                foreach (string rootAss in rootAssemblies)
                {
                    string dnAssPath = assCollector.GetAssemblyPath(rootAss);
                    if (gs.hotUpdateAssemblies != null && gs.hotUpdateAssemblies.Length> 0)
                    {
                        foreach (string hotupaName in gs.hotUpdateAssemblies)
                        {
                            if(hotupaName == rootAss)
                            {
                                Debug.Log($"热更新中找到了外部dll:{hotupaName} path:{dnAssPath}");
                                string srcPath = dnAssPath;
                                string tarPath = $"{SettingsUtil.GetHotUpdateDllsOutputDirByTarget(EditorUserBuildSettings.activeBuildTarget)}/{hotupaName}.dll";
                                File.Copy(srcPath, tarPath, true);
                            }
                        }
                    }
                }
                assCollector.Dispose();
            }

 第二步,修改HybridCLR.Editor.Meta下的AssemblyCache.cs

添加方法

public string GetAssemblyPath(string assembName)
{
     return _assemblyPathResolver.ResolveAssembly(assembName, true);
}

第三步,修改HybridCLR.Editor.Commands下的LinkGeneratorCommand.cs

在 GenerateLinkXml方法中 添加一句代码analyzer.CopyHotAssemblyToHotDllDir(hotfixAssemblies);

public static void GenerateLinkXml(BuildTarget target)
        {
            var ls = SettingsUtil.HybridCLRSettings;

            List<string> hotfixAssemblies = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;

            var analyzer = new Analyzer(MetaUtil.CreateHotUpdateAndAOTAssemblyResolver(target, hotfixAssemblies));
            var refTypes = analyzer.CollectRefs(hotfixAssemblies);
            analyzer.CopyHotAssemblyToHotDllDir(hotfixAssemblies);

            Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssemblies.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}");
            var linkXmlWriter = new LinkXmlWriter();
            linkXmlWriter.Write($"{Application.dataPath}/{ls.outputLinkFile}", refTypes);
            AssetDatabase.Refresh();
        }

到此ok了,我们外部的dll就可被识别到了,执行一键拷贝时就不会报错了。

9.WebGL平台报错:Could not produce class With ID 81.

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

在PlayerSetting中,要取消勾选 Strip Engine Code Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享,Unity应用及扩展,webgl

 文章来源地址https://www.toymoban.com/news/detail-658788.html

到了这里,关于Unity 接入HybridCLR的点点滴滴,亲测三平台(PC、Android、WebGL)妥妥的。-问题分享的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity之如何接入HybridCLR(代号wolong,原huatuo)热更新框架

    HybridCLR(代号wolong)是一个特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更方案。 官方提供了完整的教程:HybridCLR快速上手 官方还提供了一个简易的小Demo,演示了如何使用HybridCLR实现热更新。hybridclr_trial 官方文档其实已经非常详细了,我写本文目的主要

    2024年02月12日
    浏览(27)
  • Superset的安装(亲测三遍,有效)

    Apache Superset是一个开源的、现代的、轻量级BI分析工具,能够对接多种数据源、拥有丰富的图表展示形式、支持自定义仪表盘,且拥有友好的用户界面,十分易用。 在学习数仓项目的时候,按照教程安装Superset反复重复多次都没能成狗,最后稍微修改之后得以成功安装,现记

    2024年02月07日
    浏览(28)
  • HybridCLR 热更新笔记 GF接入

    官方文档 Unity 版本(国际版): Unity 2020.3.26.f1 hybridclr_unity : https://gitee.com/focus-creative-games/hybridclr_unity.git#v2.0.0-rc 官方安装教程 添加 hybridclr_unity package 方法一: 在 Unity项目/Packages/manifest.json 文件中添加一行( 注意逗号, 末尾行不需要在后面加逗号 ) “com.focus-creative-games.hybrid

    2023年04月14日
    浏览(22)
  • GameFramework 框架详解之 如何接入热更框架HybridCLR

    HybridCLR是一个特性完整、零成本、高性能、低内存的近乎完美的c#热更新方案 GameFramework是一个非常出色完整的基于Unity引擎的游戏框架,里面包含了非常多的模块,封装非常完整。 以前市面上的热更大多数都是Lua为主,后来出了一个ILRuntime的C#热更框架,虽然性能差了点,但

    2024年02月07日
    浏览(35)
  • 【UGF】GameFramework接入HybridCLR(wolong)卧龙C#热更框架

    HybridCLR的推广已经做得相当好了,而且热更领域突然杀出一匹黑马,热度很高,不再多做介绍,可以点击进入HybridCLR开源地址了解详情。 在此之前用过tolua和xlua热更框架, 因为C#开发方式实在太爽,想支持热更又不想使用弱类型语言,于是对ILRuntime和HybridCLR进行了评估,了解

    2023年04月11日
    浏览(72)
  • Unity 热更新基础HybridCLR:安装部署(HybridCLR手记二)

    官方地址:  关于HybridCLR (focus-creative-games.github.io) Win 下 打包时遇到 xxxxil2cpplibil2cpputilsIl2CppHashMap.h(71): error C2039: \\\'hash_compare\\\': is not a member of \\\'stdext\\\' 这是.net 7发布后最新版本vs改动打破了一些向后兼容性引起。你可以回退2022的旧版本或者使用2019之类的版本。 所以建议使用

    2024年02月10日
    浏览(27)
  • Unity 热更新基础HybridCLR:Windows平台使用(HybridCLR手记二)

    【注意:官网教程现已完善,请您访问官网进行学习,此教程现已失效,官网版本已更新至4.0以上,感谢您的观看,官网请访问:快速上手 | HybridCLR (code-philosophy.com)】 项目是根据官网的示例工程进行修改的,版本参数如下: unity:2020.3.30(2023.5.29日更新至wolong最新版,经测试依

    2024年02月01日
    浏览(27)
  • Unity中实现HybridCLR热更新

    一:前言 HybridCLR又称作huatuo(华佗)、wolong(卧龙)热更方案,底层是C++编写的,是一种热更新方案,与Lua、ILRuntime等都是不同的热更方案 HybridCLR扩充了il2cpp的代码,使它由纯AOT runtime变成AOT+Interpreter混合runtime,进而支持动态加载assembly,实现热更新 HybridCLR官网 HybridCLR热更

    2024年02月07日
    浏览(26)
  • Unity热更新HybridCLR+Addressables

    2024年02月13日
    浏览(35)
  • 【Unity实战】HybridCLR热更快速集成

    本文假设你已经通过UPM导入了HybridCLR、Addressables、il2cpp支持并具有一定的C#基础和Unity编辑器操作能力。 由于本文主打快速集成,故将Assembly-CSharp划入到热更新DLL。 理论上成熟的项目应该用Assembly Definition进行精细划分以便于管理和缩短编译时间。但是若掌握不好,划分不明白

    2024年02月03日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包