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

news2024/11/28 8:47:00

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

unity:2021.2.20

wolong:v2.1.0

il2cpp_plus:v2021_2.1.0

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

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文件来进行热更新的)

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

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

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

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

public class LoadDll : MonoBehaviour
{
    
   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>();

    void Start()
    {
        // 使用BetterStreamingAssets插件,即使在Android平台也可以直接读取StreamingAssets下内容,简化演示。
     //   BetterStreamingAssets.Initialize();
        
   
        Loadwww();
        
        StartGame();
    }

    void Loadwww()
    {
        foreach (var aotDllName in aotMetaAssemblyFiles)
        {
            aotFiles.Add(aotDllName);
        }

        aotFiles.Add("Assembly-CSharp.dll");
        aotFiles.Add("Main.dll");
        
        foreach (var item in aotFiles)
        {
            if (item.EndsWith(".dll"))
            {
                string str = item + ".bytes";
                aotFil.Add(str);
            }
        }
        
        aotFil.Add("prefabs");
        
        foreach (var item in aotFil)
        {
            string dllBytes =Application.persistentDataPath + ("/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["Assembly-CSharp.dll.bytes"].bytes);
#endif
//prefabs
        AssetBundle prefabAb = AssetBundle.LoadFromMemory(_dic["prefabs"].bytes);
        GameObject testPrefab = Instantiate(prefabAb.LoadAsset<GameObject>("HotUpdatePrefab.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(Application.persistentDataPath + ("/HotUpdate/HotDllFix/" + aotDllName + ".bytes"));
            // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
            LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
            Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
        }
    }
}

//注释版(人工智障他是真的,最后还要自己来)

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

public class LoadDll : MonoBehaviour
{
    //wolong需要的执行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>();

    void Start()
    {
        // 使用BetterStreamingAssets插件,即使在Android平台也可以直接读取StreamingAssets下内容,简化演示。
     //   BetterStreamingAssets.Initialize();
        
   
        Loadwww();
        
        StartGame();
    }

    void Loadwww()
    {
        foreach (var aotDllName in aotMetaAssemblyFiles)
        {
            aotFiles.Add(aotDllName);
        }
        //加入新的.dll库,分别是要跟新的dll,和官方启动项目的dll
        aotFiles.Add("Assembly-CSharp.dll");
        aotFiles.Add("Main.dll");
        //加后缀方便更新
        foreach (var item in aotFiles)
        {
            if (item.EndsWith(".dll"))
            {
                string str = item + ".bytes";
                aotFil.Add(str);
            }
        }
        //加入预制体
        //因为有些用的是预制体上挂载的方式进行的热更
        aotFil.Add("prefabs");
        //设置www加载项目录
        foreach (var item in aotFil)
        {
            string dllBytes =Application.persistentDataPath + ("/HotUpdate/HotDllFix/" + item);
            
            WWW www = new WWW("file://"+dllBytes);
            if (www.error!=null)
            {
                
            }
           //添加进集合准备加载
            _dic.Add(item,www);
        }
        
    }
    


    void StartGame()
    {
        //启动官方的文件,具体参见官方文档
        LoadMetadataForAOTAssemblies();
//依据平台进行运行
#if !UNITY_EDITOR
// 
       //通过www进行加载(具体可参见官方文档)
        System.Reflection.Assembly.Load(_dic["Assembly-CSharp.dll.bytes"].bytes);
#endif
        //通过www进行加载(具体可参见官方文档)
        AssetBundle prefabAb = AssetBundle.LoadFromMemory(_dic["prefabs"].bytes);
        GameObject testPrefab = Instantiate(prefabAb.LoadAsset<GameObject>("HotUpdatePrefab.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)
        {
            //修改了加载的文件目录,原来这里加载的是流文件目录下的东西,这里改到了p目录
            byte[] dllBytes =
                File.ReadAllBytes(Application.persistentDataPath + ("/HotUpdate/HotDllFix/" + aotDllName + ".bytes"));
            // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
            LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
            Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
        }
    }
}

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

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

热更新wolong模块结束

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/474546.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytest - Getting Start

前言 项目开发中有很多的功能&#xff0c;通常开发人员需要对自己编写的代码进行自测&#xff0c;除了借助postman等工具进行测试外&#xff0c;还需要编写单元测试对开发的代码进行测试&#xff0c;通过单元测试来判断代码是否能够实现需求&#xff0c;本文介绍的pytest模块是…

虚幻图文笔记:Substance Painter通过USD格式导入UE5的工作流

什么是USD格式 USD即Universal Scene Description&#xff0c;是著名的Pixar公司研发的一种开源的3D 场景说明和文件格式&#xff0c;如其名所示&#xff0c;相较于传统的FBX、Obj等3D格式&#xff0c;USD的具有更好的通用性和扩展性&#xff0c;现在已被非常多的厂商和平台所…

使用树莓派(zero2w + Camera Module 3 支持自动对焦 1200 万像素)拍照

拍照硬件 Raspberry Pi Camera Module 3Raspberry Pi Zero 2 W 1. 注意排线连接方向 2. 烧录系统 3. 进行系统更新需要联网&#xff0c;注意只支持最新的bullseye系统。每条指令大概需要10 分钟。 sudo apt-get update -y sudo apt-get upgrade -y4. 拍摄一张全像素的JPEG图像…

自己做小程序开个社区团购可行吗?

在如今的社交化时代&#xff0c;随着社区经济的发展&#xff0c;越来越多的人开始探索社区团购的商业模式。而随着小程序的普及&#xff0c;自己开发一个社区团购小程序也成为了一种可能。但是&#xff0c;自己做小程序开个社区团购真的可行吗&#xff1f;我们来一起分析一下。…

Spring整合MybatisJunit单元测试

Spring整合Mybatis&Junit单元测试 1. Spring整合Mybatis【重点】1.1 思路分析问题导入1.1.1 MyBatis程序核心对象分析1.1.2 整合MyBatis 1.2 代码实现【前置工作】【第一步】导入Spring整合Mybatis依赖【第二步】创建JdbcConfig配置DataSource数据源【第三步】创建MybatisC…

【ARMv8 编程】A64 内存访问指令——内存加载指令

与所有先前的 ARM 处理器一样&#xff0c;ARMv8 架构是一种加载/存储架构。这意味着没有数据处理指令直接对内存中的数据进行操作。数据必须首先被加载到寄存器中&#xff0c;修改&#xff0c;然后存储到内存中。该程序必须指定地址、要传输的数据大小以及源或目标寄存器。有额…

《使用深度神经网络对光电容积脉搏图进行归一化,以进行个体和群体比较》阅读笔记

目录 一、论文摘要 二、论文十问 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一…

symfonos 1(smtp注入webshell,配合文件文件包含)

目录 扫描 SMB 提权 扫描 SMB 让我们使用SMBMAP检查这些目录的权限。 smbmap -d workgroup -H www.example.com 可能/匿名帐户可访问。 使用smb尝试连接共享网络以访问/anonymous目录。[smb://192.168.59。129/]

ETL工具 - Kettle 介绍及基本使用

一、Kettle 介绍 在介绍 Kettle 前先了解下什么是 ETL&#xff0c;ETL是 Extract-Transform-Load 的缩写&#xff0c;即数据 抽取、转换、装载 的过程&#xff0c;对于企业或行业应用来说&#xff0c;经常会遇到各种异构数据的处理、转换、迁移等操作&#xff0c;这些操作有可…

java+mysql医院住院挂号缴费病房信息管理系统

手续办理&#xff1a;办理病人入院登记&#xff1b;提供病案首页建立与打印&#xff1b;交纳预交金及日结管理&#xff0c;并打印收据凭证&#xff1b;空床查询与统计&#xff1b;查询患者的住院信息&#xff1b;打印清单&#xff1b;出入院统计。 护士工作站&#xff1a;提供病…

Java每日一练(20230429)

目录 1. 二叉树的后序遍历 &#x1f31f;&#x1f31f; 2. 删除无效的括号 &#x1f31f;&#x1f31f;&#x1f31f; 3. 合并两个有序链表 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每…

【Java笔试强训 1】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f9be;&#x1f9be;&#x1f9be; 目录 一、选择题 二、编程题 &#x1f525;组队竞…

基于虚拟同步发电机的光伏混合储能并网系统MATLAB仿真

资源地址&#xff1a; 主要模块&#xff1a; 光伏电池模型&#xff08;按照数学模型搭建&#xff09;、蓄电池储能模块、超级电容储能模块、双向DC/DC模块、LC滤波器、逆变器VSG控制模块电压电流双环控制模块、光伏MPPT控制模块、储能系统充放电控制模块。 使用MATLAB2021b及…

2023/04/24 ~ 25 刷题记录

A - Sort the Subarray 大致题义&#xff1a;Monocarp有一个包含n个整数的数组a。他决定选择两个整数l和r&#xff0c;使1< 2rn&#xff0c;然后对子数组进行排序。子数组a[1 ..]R]是数组a中包含元素a1, al1, al2&#xff0c;…的部分。&#xff0c; ar-1, ar)按非降序排列。…

【STM32】知识补充 锁相环原理与应用解析

【STM32】知识补充 锁相环原理与应用解析 概述什么是锁相环 (PPL)锁相环的基本组成锁相环的工作原理锁相环应用STM32 中锁相环的应用STM32 配置锁相环总结 概述 锁相环 (Phase-Locked Loop) 在现代电子与通信系统中, 扮演着至关重要的角色. 凭借其独特的同步和频率调整能力, 锁…

大数据Doris(七):BE扩缩容

文章目录 BE扩缩容 一、BE扩容(创建BE与FE关系) 二、BE缩容 三、BE扩缩容注意问题

【操作系统复习】第5章 存储器管理 2

分页存储管理方式 页号P ◆12-31位&#xff1a;20位 ◆地址空间最多允许有1M&#xff08;2 20&#xff09;页 位移量W&#xff08;页内地址&#xff09; ◆0-11&#xff1a;12位 ◆每页大小为4KB &#xff08;2 12&#xff09; 对某特定机器&#xff0c;地址结构是一…

LangChain 2 ONgDB:大模型+知识图谱实现领域知识问答

LangChain 2 ONgDB&#xff1a;大模型知识图谱实现领域知识问答 LangChain 2 ONgDB&#xff1a;大模型知识图谱实现领域知识问答系统截图LangChain代理流程 Here’s the table of contents: LangChain 2 ONgDB&#xff1a;大模型知识图谱实现领域知识问答 LangChain 是一种 LL…

社区团购小程序怎么做,全流程解析

在当前的电商市场中&#xff0c;社区团购已经成为了一股强劲的力量。社区团购小程序作为社区团购的重要组成部分&#xff0c;已经成为了商家和消费者不可或缺的工具。社区团购小程序以其方便、快捷、实惠的特点&#xff0c;受到越来越多的用户的青睐&#xff0c;成为了电商市场…

只需5分钟,深刻理解本地事务状态表方案|分布式事务系列(四)

之前我们已经讲过了最基础的CAP、BASE理论&#xff0c;然后介绍了强一致性方案XA、2PC和3PC&#xff0c;然后详细讲述了TCC在生产中的应用场景和原理。本文继续讲解最终一致性方案——本地事务状态表方案。 点击上方“后端开发技术”&#xff0c;选择“设为星标” &#xff0c;…