Unity引擎使用HybridCLR(华佗)热更新

  大家好,我是阿赵。
  阿赵我做手机游戏已经有十几年时间了。记得刚开始从做页游的公司转到去做手游的公司,在面试的时候很重要的一个点,就是会不会用Lua。使用Lua的原因很简单,就是为了热更新。
  热更新游戏内容很重要。如果游戏内容需要改动,如果每次都要去平台出新的安装包提审,周期不可控,甚至像iOS这种提审特别麻烦的平台,还有不过审的风险。比如出个春节活动,提审完可能春节都过完了,那么这个内容也就没有意义。 但如果游戏的内容自己可以通过某些方法进行修改,不需要通过平台的审核就能直接改动,那么游戏制作的灵活性就大大增加了。我们使用Unity引擎来开发游戏,游戏资源是可以通过AssetBundle的方式热更新的,但C#代码,以前是不能热更新的,至少在iOS平台是不能的,安卓和pc有办法可以热更新dll。
  Lua作为一个可以通过字符串或者字节资源的形式加载的脚本,在游戏热更新上起到了重要的作用,起码在近十年时间是出于统治地位的。但由于性能问题Lua也一直受到各种诟病,特别是在微信小游戏或者抖音小游戏上面,性能的确不是很好。
  最近和UWA沟通的过程中,听说很多公司已经不用Lua,而改为用了HybridCLR(华佗)热更新。华佗热更新的原理是更新c#的程序集,也就是通过加载dll来实现代码层面的热更新,而且iOS也能用。不过由于公司的项目都是在用Lua开发的,如果换成华佗,等于整个项目要重新用C#写一篇,成本还是很高的。
  学多一点东西肯定是有好处的,说不定以后新项目就能用得上。于是阿赵我也来学习一下华佗热更新的用法,并且记录一下一些使用的问题。

一、 安装

HybridCLR华佗热更新的在线文档地址是:
文档地址
  里面有比较详细的安装说明,可以根据步骤一步步来安装。我只记录一下我遇到的问题。

1、 对应的Unity版本

  在官方文档里面说,华佗支持的Unity版本有这些:
在这里插入图片描述

  由于我有一个项目是使用2019.4.24开发的,一看文档说支持2019.4.x,感觉挺好,但继续看下去,会看到:
在这里插入图片描述

  从文档看,2019只能在2019.4.40上面安装。其实2019.4前面的版本的确挺多问题的,比如我之前发现的URP的SRPBatcher合并问题等,各位如果还在用2019版本开发的朋友,我也挺建议大家都升级到2019.4.40。无奈的是,如果项目已经上线了,再来换版本,可能会导致AssetBundle打包的资源会全部变更,Unity打包AssetBundle的时候会把版本号写在文件开头,所以就算你所有内容都没变,只是换个Unity版本,打出来的AssetBundle文件也会全部改变的……
  不过幸好,华佗的文档里面也有针对这种情况的处理办法,就是先把项目切换到2019.4.40,然后安装华佗,再切换会原来的版本。
在这里插入图片描述

  抛开项目已有版本的问题,其实就无所谓了,因为之后的版本很多都支持, 比如直接安装2022.3.x版本,就没这个问题了。

2、下载代码

  由于代码库是从git下载,所以必须安装git。
  然后通过Unity的PackageManager里面的Add package from git URL来安装
库地址:
https://gitee.com/focus-creative-games/hybridclr_unity.git

https://github.com/focus-creative-games/hybridclr_unity.git

  我自己尝试的结果是没办法通过Add package from git URL来安装,安装了GIT和加了环境变量PATH也不行。我自己用GIT手动克隆,却是没问题的,这一点很神奇。
  于是解决这个问题的方法是,可以手动把地址检出克隆到本地,然后把文件夹改名com.code-philosophy.hybridclr,并复制到项目里面和Assets文件夹同级的Packages文件夹
在这里插入图片描述

  复制后打开项目,会看到有华佗的菜单
在这里插入图片描述

  选择安装器,然后安装
在这里插入图片描述

  按照文档说明基本都可以自动安装成功,但我还是失败了,看报错还是GIT的问题,于是我根据报错,自己检出克隆https://gitee.com/focus-creative-games/hybridclr到项目的HybridCLRData/hybridclr_repo文件夹
在这里插入图片描述

  检出后再次点击Install按钮,就可以安装成功了。
在这里插入图片描述

  HybridCLR菜单下出现了所有的选项子菜单。

二、 浅尝华佗热更新

1、 一些概念

  在使用华佗热更新之前需要先了解一些概念

1. 程序集

  先来操作,最后再说为什么。在项目里面创建一个文件夹,叫做HotUpdate,或者叫其他都行,你自己喜欢:
在这里插入图片描述

  然后在这个文件夹里面,创建一个Assembly Definition文件:
在这里插入图片描述

  帮这个文件起个名字,比如我这里就叫做HotUpdate:
在这里插入图片描述

  注意要把Auto Referenced的勾选去掉。
  然后在这个文件夹里面创建一个C#脚本,我这里随便命名为Hello:
在这里插入图片描述

  创建完之后,点选这个Hello脚本,会看到里面多了一个Assembly信息,里面说明了,这个Hello的脚本,是属于HotUpdate.dll的。
在这里插入图片描述

  操作到此结束,下面解释一下:
  这个创建文件夹和Assembly Definition文件的过程,是Unity引擎的程序集功能,其实就是指定了某个文件夹作为一个程序集的范围。只要在这个文件夹下面的所有文件,包括子文件夹里面的文件,都属于当前这个Assembly Definition文件的程序集里面的内容。
  一个程序集,字面意思就是程序的集合了,可以理解成是把里面的代码都打包了,之后需要热更新代码,其实就是热更新这个程序集的dll文件了。

2. AOT程序集和热更新程序集

  使用Unity引擎制作游戏,各位肯定应该都会写C#。在项目里面所写的C#代码,就算我们不特意的打程序集,它们也会出现在一个程序集里面,就是Assembly-CSharp.dll,然后我们又可以根据自己的需要,创建一些程序集,所以最后打包的时候,除了Assembly-CSharp.dll,还会有一些自己的dll。这些多个程序集,之后会用于华佗热更新。
  这里有个问题,热更新是以dll为单位的,那些可以热更新的程序集,在使用华佗热更新的时候,是会剥离出去,不会包含在主工程包里面的。而我们需要写代码加载这些dll文件,就必须有一些代码是包含在主工程里面不能热更新的。
  所以在使用华佗热更新的时候,需要把程序集分成2部分,第一部分是包含在游戏主包里面不能热更新的,成为AOT程序集,第二部分是可以热更新的dll,成为热更新程序集。

3. 程序集的规划和程序集之间的引用关系

  由于程序集起码要有AOT和可热更两个,甚至更多,所以在做之前,我们必须先规划一下它们之间的关系。具体来说,就是总共需要多少个程序集才能满足我们需要,既能热更,又可以划分清楚模块,做到分块更新。
  程序集之间的引用,有2种方式,第一种,就是在程序集上面勾上Auto Referenced,这样它自动被其他程序集引用,可以互相调用里面的方法。
  另外一种,就是在程序集上面指定依赖关系,比如我再建一个HotUpdate2的程序集,不勾选Auto Referenced:
在这里插入图片描述

  这个时候如果HotUpdate程序集要访问HotUpdate2程序集,可以选择HotUpdate程序集,然后添加引用关系:
在这里插入图片描述

  只要在HotUpdate程序集的Assembly Definition References里面添加了HotUpdate2的引用,那么HotUpdate就能调用HotUpdate2里面的方法了。
  华佗热更新里面有一个规则,AOT程序集是不能直接引用热更新程序集的,不然在打包的时候会出错。所以,我们在创建自己的可热更程序集的时候,必须把Auto Referenced的勾选去掉,然后自己维护可热更新程序集之间的引用关系。

2、 尝试使用华佗热更新

1. 指定需要热更新的程序集

  在HybridCLR菜单下面选择Settings设置:
在这里插入图片描述

  然后添加可热更新的程序集:
在这里插入图片描述

  在这里设置了的程序集,在打主包的时候,程序集是不会包含在主包里面的。

2. 生成必须的东西

在这里插入图片描述

  在首次使用华佗热更新的时候,必须先选择Generate——All,生成所有必须的文件,其实就是All上面的哪些东西了。在之后的使用中,就不一定要生成All,可以根据实际需要来生成上面的内容。

3. 写热更新的测试代码

  首先,为了打包之后看到控制台的打印,先创建一个脚本:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ConsoleToScreen : MonoBehaviour
{
   
   
    const int maxLines = 50;
    const int maxLineLength = 120;
    private string _logStr = "";

    private readonly List<string> _lines = new List<string>();

    public int fontSize = 15;

    void OnEnable() 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值