> 技术文档 > Unity + HybridCLR热更新 实战篇_untiy addressable+hybridclr

Unity + HybridCLR热更新 实战篇_untiy addressable+hybridclr

本文介绍在Unity中借助Addressable+HybridCLR实现界面和界面逻辑的热更新。

在开始之前,对于Addressable不熟的同学可以先浏览专栏

https://blog.csdn.net/qq_44809934/category_12991790.html?spm=1001.2014.3001.5482

对于HybridCLR不熟的同学可以先浏览文章

Unity + HybridCLR热更新 入门篇_hybirdclr-CSDN博客

准备工作

1、搭建好IIS资源服务器

2、配置好Addressable和HybridCLR环境

3、因为在HotUpdate文件夹中的脚本可能会出现引用某个命名空间失败的情况,需要在配置文件中引用对应的程序集

4、在HotUpdate文件夹下,创建一个界面预制体和对应逻辑脚本,并挂在到该预制体上。

using UnityEngine;using UnityEngine.UI;using UnityEngine.AddressableAssets;public class UITestForm : MonoBehaviour{ [SerializeField] private Text txt_Title; [SerializeField] private Button btn_Switch; [SerializeField] private Image img_Icon; void Start() { txt_Title.text = \"Hello\"; }}

 5、HybridCLR Generate All

 6、新建一个文件夹例如HotUpdateConfig,将HotUpdate.dll改名为HotUpdate.dll.bytes后放入该文件夹。

 

7、新建两个Addressable Group,一个用来存放界面预制体,一个用来存放HotUpdate.dll.bytes.

8、配置Addressable远端加载路径,将7中所述的两个group设置为远端加载

9、开始Build,完成后,将构建的远端资源文件放到服务器的管理文件夹中

 

10、在场景中创建一个Canvas和一个空节点,命名为Root。创建一个启动脚本GameStart,并挂载到Root节点上。

using System;using System.Collections;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class GameStart : MonoBehaviour{ private List keys = new List(); void Start() { keys = new List(); StartCoroutine(AAInit()); } //Addressable初始化+检测更新 IEnumerator AAInit(Action callback = null) { //第一步 Addressable模块初始化 var initialLogic = Addressables.InitializeAsync(false); yield return initialLogic; //第二步 检查Catalog是否有更新 var catalogLogic = Addressables.CheckForCatalogUpdates(false); yield return catalogLogic; if (catalogLogic.Status == AsyncOperationStatus.Succeeded) { var catalogs = catalogLogic.Result; if (catalogs != null && catalogs.Count > 0) { Debug.Log($\"发现{catalogs.Count}个更新 更新内容:{string.Join(\"\\n\", catalogs)}\"); // 更新catalog var updateHandle = Addressables.UpdateCatalogs(catalogs, false); yield return updateHandle; var locatorList = updateHandle.Result; //待下载列表 foreach (var locator in locatorList) {  keys.Clear();  keys.AddRange(locator.Keys);  //获取需要下载的内容大小  var getDownLoadSize = Addressables.GetDownloadSizeAsync(keys);  Debug.Log(getDownLoadSize.Result);  if (getDownLoadSize.Result > 0)  { // 执行资源下载 var downLoadData = Addressables.DownloadDependenciesAsync(keys, Addressables.MergeMode.Union, false); while (!downLoadData.IsDone) { Debug.Log($\"下载进度: {downLoadData.PercentComplete * 100}%\"); yield return null; } yield return downLoadData; if (downLoadData.Status == AsyncOperationStatus.Succeeded) { Debug.Log(\"下载成功!\"); } else { Debug.Log(\"下载失败!\"); } Addressables.Release(downLoadData);  } } Addressables.Release(updateHandle); } else { Debug.Log(\"catalog没有需要更新的数据!\"); } Debug.Log(\"检测完成\"); } else { Debug.Log(\"检测资源失败.....\"); } //最后一步 释放资源 Addressables.Release(initialLogic); //释放操作句柄,避免内存泄漏 Addressables.Release(catalogLogic); LoadHotUpdateDll(); callback?.Invoke(); } //加载热更Dll文件 private async void LoadHotUpdateDll() { // Editor环境下,HotUpdate.dll.bytes已经被自动加载,不需要加载,重复加载反而会出问题。#if !UNITY_EDITOR var dllKey = \"Assets/HotUpdateConfig/HotUpdate.dll.bytes\"; var process = Addressables.LoadAssetAsync(dllKey); await process.Task; Assembly hotUpdateAss = Assembly.Load(process.Result.bytes);#else // Editor下无需加载,直接查找获得HotUpdate程序集 Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == \"HotUpdate\");#endif InitGameRoot(); } private void InitGameRoot() { var template = LoadGameObject(\"Assets/HotUpdate/Prefab/UITestForm.prefab\"); var test = Instantiate(template,transform); } public GameObject LoadGameObject(string key) { var handle = Addressables.LoadAssetAsync(key); return handle.WaitForCompletion(); }}

11、注册当前场景,开始打包。打包完成后双击.exe程序启动,查看是否成功显示测试界面。

测试热更

1、修改测试脚本的逻辑

2、Generate All更新HotUpdate.dll,将HotUpdate.dll改名为HotUpdate.dll.bytes后替换HotUpdateConfig文件夹中的旧文件。

3、重新拖入HotUpdateDlls group中,并进行更新打包

4、将更新后的文件替换服务器中旧的文件,重新运行上一次打包的.exe程序,看脚本是否热更成功。(点击按钮之后,看标题和图标是否有变化)

成功啦!!!

总结

在本热更新解决方案中,Addressable和HybridCLR是两个核心组件,各自承担不同的职责但又相互配合,共同实现完整的资源和代码热更新能力。

功能

说明

Addressable

处理资源热更新

  • 管理所有非代码资源(预制体、纹理、音频等)的更新
  • 提供版本比对和差异下载功能
  • 运行时动态加载更新后的资源
  • 优化资源内存管理

HybridCLR

处理C#代码热更新

  • 实现逻辑代码的热更新
  • 支持修复bug和添加新功能
  • 允许运行时加载新的C#程序集