Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World
  v5bEezpf7PPs 2023年11月02日 49 0

@[TOC](Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World)


前言

最近又新接触了一种unity热更的解决方案——HybridCLR,自称是:特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更方案。 接下来我们就来一起学习下。 下面是官方文档的链接,一切以官方为主:HybridCLR


一、HybridCLR是什么?

HybridCLR扩充了il2cpp的代码,使它由纯AOT runtime变成AOT+Interpreter 混合runtime,进而原生支持动态加载assembly,使得基于il2cpp backend打包的游戏不仅能在Android平台,也能在IOS、Consoles等限制了JIT的平台上高效地以AOT+interpreter混合模式执行,从底层彻底支持了热更新。

HybridCLR不仅支持传统的全解释执行模式,还开创性地实现了 Differential Hybrid Execution(DHE) 差分混合执行技术。即可以对AOT dll任意增删改,会智能地让变化或者新增的类和函数以interpreter模式运行,但未改动的类和函数以AOT方式运行,让热更新的游戏逻辑的运行性能基本达到原生AOT的水平。

我自己理解的就是:一种基于C#的热更技术,完美支持C#原生,不需要写额外的适配器啥的,直接就能用,就是把il2cpp改了下。

二、使用步骤

环境配置

unity安装的时候一定要安装IL2cpp部分,Windows Build Support(IL2CPP)或Mac Build Support(IL2CPP)。 现在支持的unity 版本:2019.4.40、2020.3.26+、2021.3.0+

我用的unity 版本是2021.3.23


Windows Win下需要安装visual studio 2019或更高版本。安装时至少要包含 使用Unity的游戏开发 和 使用c++的游戏开发 组件。 安装git Mac 要求MacOS版本 >= 12,xcode版本 >= 13,例如xcode 13.4.1, macos 12.4。 安装 git 安装cmake

创建项目

创建ConsoleToScreen脚本,方便在屏幕上看日志。

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() { Application.logMessageReceived += Log; }
    void OnDisable() { Application.logMessageReceived -= Log; }

    public void Log(string logString, string stackTrace, LogType type)
    {
        foreach (var line in logString.Split('\n'))
        {
            if (line.Length <= maxLineLength)
            {
                _lines.Add(line);
                continue;
            }
            var lineCount = line.Length / maxLineLength + 1;
            for (int i = 0; i < lineCount; i++)
            {
                if ((i + 1) * maxLineLength <= line.Length)
                {
                    _lines.Add(line.Substring(i * maxLineLength, maxLineLength));
                }
                else
                {
                    _lines.Add(line.Substring(i * maxLineLength, line.Length - i * maxLineLength));
                }
            }
        }
        if (_lines.Count > maxLines)
        {
            _lines.RemoveRange(0, _lines.Count - maxLines);
        }
        _logStr = string.Join("\n", _lines);
    }

    void OnGUI()
    {
        GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity,
           new Vector3(Screen.width / 1200.0f, Screen.height / 800.0f, 1.0f));
        GUI.Label(new Rect(10, 10, 800, 370), _logStr, new GUIStyle() { fontSize = Math.Max(10, fontSize) });
    }
}

把这个脚本挂载到空场景的空物体上,在Build Settings中添加这个场景到打包场景列表

创建 HotUpdate 热更新模块

创建 Assets/HotUpdate 目录 在目录下 右键 Create/Assembly Definition,创建一个名为HotUpdate的程序集模块

安装和配置HybridCLR

Windows——>Package Manager,打开包管理器,

Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World_System

填入https://gitee.com/focus-creative-games/hybridclr_unity.git或https://github.com/focus-creative-games/hybridclr_unity.git

安装包成功后,打开HybridCLR——>Installer

配置HybridCLR

Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World_热更新_02

PlayerSettings的配置

Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World_加载_03

创建热更脚本

Assets/HotUpdate/Hello.cs这个脚本内容是需要热更的,代码如下:

using System.Collections;
using UnityEngine;

public class Hello
{
    public static void Run()
    {
        Debug.Log("Hello, HybridCLR");
    }
}

加载热更新程序集

创建Assets/LoadDll.cs脚本,然后在main场景中创建一个GameObject对象,挂载LoadDll脚本。

using HybridCLR;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

public class LoadDll : MonoBehaviour
{

    void Start()
    {
      // Editor环境下,HotUpdate.dll.bytes已经被自动加载,不需要加载,重复加载反而会出问题。
#if !UNITY_EDITOR
        Assembly hotUpdateAss = Assembly.Load(File.ReadAllBytes($"{Application.streamingAssetsPath}/HotUpdate.dll.bytes"));
#else
      // Editor下无需加载,直接查找获得HotUpdate程序集
        Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
#endif
 Type type = hotUpdateAss.GetType("Hello");
        type.GetMethod("Run").Invoke(null, null);
    }
}

运行菜单 HybridCLR/Generate/All 进行必要的生成操作这是用来生成要热更的脚本的dll文件的将{proj}/HybridCLRData/HotUpdateDlls/StandaloneWindows64(MacOS下为StandaloneMacXxx)目录下的HotUpdate.dll复制到Assets/StreamingAssets/HotUpdate.dll.bytes,注意,要加.bytes后缀!!

然后就可以打包了,运行之后的结果是这样的

Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World_热更新_04

测试热更新

修改Assets/HotUpdate/Hello.cs的Run函数中Debug.Log("Hello, HybridCLR");代码,改成Debug.Log("Hello, World");。运行菜单命令HybridCLR/CompileDll/ActiveBulidTarget重新编译热更新代码。将{proj}/HybridCLRData/HotUpdateDlls/StandaloneWindows64(MacOS下为StandaloneMacXxx)目录下的HotUpdate.dll复制为刚才的打包输出目录的 XXX_Data/StreamingAssets/HotUpdate.dll.bytes。

重新运行程序 结果如下

Unity + HybridCLR,近乎完美的新热更方案,从零开始(一)——Hello World_System_05

热更成功!


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

v5bEezpf7PPs