Unity 热更新基础HybridCLR:Windows平台使用(HybridCLR手记二)

项目是根据官网的示例工程进行修改的,版本参数如下:

unity:2020.3.30(2023.5.29日更新至wolong最新版,经测试依然有效)

wolong:v2.3.0

官网地址发生了变化更新为:HybridCLR (focus-creative-games.github.io)

相关项目示例仓库地址:wolong2.0版本测试项目: 这是一个学习wolong的测试demo,具体教程操作详见CSDN (gitee.com)

-------------------------------------------------------------

1、安装:参考:第一篇文章Unity 热更新基础HybridCLR:安装部署(HybridCLR手记二)_作孽就得先起床的博客-CSDN博客

2、引入示例工程:

请访问官方的文件仓库:github或者是gitee,这里提供的是它gitee的示例工程网址:

hybridclr_trial: HybridCLR的示例项目 (gitee.com)

下载它

完成后导入项目:

导入到你项目同工程目录下,导入内容为:(图片为下载的示例工程),箭头为导入项目

(1提示的是目录)

步骤1(共2步)

 然后还有

步骤2(共2步)

 这里导进去了一个流文件读取插件,为了保证稳定因为官方用的是通过这个流文件插件读取的方案,但是热更流文件目录是只读目录,为了符合规范,因此依然选择了WWW方案,后面会对他进行修改,这里先导入进去

这样示例工程就导入完成了,进入项目

再次检查这几个选项是否一致:

 

 

 1、这里简单说下是咋回事。简单来说这是选择的热更新程序集,我们更新的就是他。

我这里写的是因为我的脚本是属于这个程序集(如图)

 当然,您也可以自己直接建程序集来进行热更新,如果您要自己建使用上面的就好了,就是这个

 直接拖拽上去就好了,如果手动输入的请去掉后缀

然后来到这重新安装下:

 

 这俩重新走下根据平台我这里是Win64,Generate->ALL

场景选择:main

Generate->ALL:是最容易报错的阶段,官方也有文档,写的也很详尽了,一般我们只需要找个地方先出个包就好了(不管出包是否成功,这里主要是为了Generate),出包一定要选择:

不要使用代码来进行此操作 

然后:出.dll包文件

这时候我们点击运行就好了,示例工程就此完成

但要热更,故此需要调整一些东西来满足热更需要:

1、在工程目录中新建一个文件夹,创建一个代码,这个文件夹下的代码将是我们要热更的脚本代码(大概会是这样)

 (因为wolong是通过.dll文件来进行热更新的)

注:新本的dll程序所属程序集已经发生改变,本示例已经更新为:HotUpdate.dll

2、项目工程中找到代码:LoadDll

接下来要对他进行修改:里面修改后代码如下:(注释版由ChatGPT提供)

请关注下目录,并在相应的文件下创建好目录进行使用(已更新)

using HybridCLR;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

 
public class LoadDll : MonoBehaviour
{
    //记录添加的dll文件名称
   static  List<string> aotMetaAssemblyFiles = new List<string>()
    {
        "mscorlib.dll",
        "System.dll",
        "System.Core.dll",
    };
 
   private List<string> aotFiles = new List<string>();
   private List<string> aotFil= new List<string>();
 
   private Dictionary<string, WWW> _dic = new Dictionary<string, WWW>();

   private static string _path;
    void Start()
    {
        //通过www访问加载
        Loadwww();
        StartGame();
    }
 
    void Loadwww()
    {
        foreach (var aotDllName in aotMetaAssemblyFiles)
        {
            aotFiles.Add(aotDllName);
        }
        //添加额外的dll文件
        aotFiles.Add("HotUpdate.dll");
        aotFiles.Add("Main.dll");
        //循环遍历所有dll文件
        foreach (var item in aotFiles)
        {
            if (item.EndsWith(".dll"))
            {
                //添加后缀,方便热更
                string str = item + ".bytes";
                aotFil.Add(str);
            }
        }
        //将prefabs问价加入
        aotFil.Add("prefabs");
        
        //提取dll
        foreach (var item in aotFil)
        {
            string dllBytes = Application.dataPath;
            Directory.SetCurrentDirectory(Directory.GetParent(dllBytes).FullName);
            dllBytes=Directory.GetCurrentDirectory();
            _path = dllBytes+("/HotUpdate/HotDllFix/");//保存加载的目录
            dllBytes=dllBytes+("/HotUpdate/HotDllFix/" + item);
            
            //进行加载
            WWW www = new WWW("file://"+dllBytes);
            if (www.error!=null)
            {
                
            }
           //放入等待加载
            _dic.Add(item,www);
        }
        
    }
    
 
 
    void StartGame()
    {
        LoadMetadataForAOTAssemblies();
 
#if !UNITY_EDITOR
// //Assembly-CSharp.dll.bytes
        System.Reflection.Assembly.Load(_dic["HotUpdate.dll.bytes"].bytes);
#endif

        AssetBundle prefabAb = AssetBundle.LoadFromMemory(_dic["prefabs"].bytes);
        GameObject testPrefab = Instantiate(prefabAb.LoadAsset<GameObject>("Cube.prefab"));
    }
 
 
    
    
    
 
    /// <summary>
    /// 为aot assembly加载原始metadata, 这个代码放aot或者热更新都行。
    /// 一旦加载后,如果AOT泛型函数对应native实现不存在,则自动替换为解释模式执行
    /// </summary>
    private static void LoadMetadataForAOTAssemblies()
    {
        
        /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
        /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
 
        HomologousImageMode mode = HomologousImageMode.SuperSet;
        foreach (var aotDllName in aotMetaAssemblyFiles)
        {
            //根据路径进行加载
            byte[] dllBytes =
                File.ReadAllBytes(_path + aotDllName + ".bytes");
            // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
            LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
            Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
        }
    }
}

提示:我这里的代码在出更新脚本文件后需要您手动从流目录下移动一下文件到加载的指定目录下,才能够正常运行,具体请自行分析下代码

在修改完代码后请重新执行这三步操作:

热更新wolong模块结束

 这文章都没VIP或收费,给点赞、收藏和关注吧~(嘤嘤~)

猜你喜欢

转载自blog.csdn.net/qq_46043095/article/details/130438113