【HybirdCLR】入门记录-Unity2021 + WebGL

news2024/11/15 9:05:08

目录

  • 前言
  • 环境
  • 案例学习
    • 先PC平台试一下
    • 转为WebGL平台
  • 动手做一个demo
    • 功能
    • 基本工作流程
      • 搭建环境
      • 构建项目
    • 补充
  • 致谢
  • 参考资料


前言

之前一直有听说热更新技术,于是找点时间来研究一下热更新技术的使用。热更新的实现方式有很多种,这里笔者记录一下自己学习HybirdCLR的过程。


环境

unity2021.3.10f1c2,visual studio 2019

案例学习

先PC平台试一下

下载官方示例后,按照readme文档说的进行操作:

  1. 打开Installer,点击安装,等待安装完成
  2. HybirdCLR/Generate/All点击一下
  3. HybirdCLR/Build/Win64点击一下,生成exe
  4. 然后可以打开 hybridclr_trial-main\Release-Win64\HybridCLRTrial.exe 会看到打出 hello, HybridCLR.prefab

转为WebGL平台

  1. build setting更改到WebGL平台
  2. 因为是WebGL,按照官方文档的说法,需要勾选UseGlobal II2CPP,并且把hybridclr_trial-main\HybridCLRData\LocalIl2CppData-WindowsEditor\il2cpp,覆盖到编辑器的相似路径——unityEditor\2021.3.10f1c2\Editor\Data\il2cpp
  3. 运行菜单 HybridCLR/Generate/All 一键执行必要的生成操作
  4. Build Settings里打包游戏
  5. 运行菜单 HybridCLR/Build/BuildAssetsAndCopyToStreamingAssets 打包热更新资源及dll
  6. Assets/StreamingAssets下的所有文件复制到你刚才打包的游戏的StreamingAssets目录(如果是直接打android apk包,则再次Build即可)
  7. 运行刚刚打包成功的游戏,应该会出现Script Missing的警告,因为目前HybirdCLR还不支持unity2021的WebGL在AB包上直接挂载脚本,或许以后大佬们会支持吧。所以说要改用反射的方式去调用:
    官方-使用反射来使用热更新代码

动手做一个demo

功能

有个UGUI的text,显示热更新程序集的脚本中方法返回的字符串

基本工作流程

搭建环境

  1. 新建项目,切换为webgl
  2. 包管理器从git获取,https://gitee.com/focus-creative-games/hybridclr_unity.git
  3. 在installer中选择安装
  4. 修改playerSetting—— Api改成 .NET Framework
  5. 发现在WebGL平台,GC选项是关闭的。所以去到PC平台,关闭增量式GC(Use Incremental GC) 选项
  6. 打包一下,确认WebGL可以在本机IIS上运行
  7. HybirdCLR/Settings打开设置,勾选UseGlobal II2CPP。因为用的同一个版本的unity编辑器,所以就不用再覆盖了。然后在热更新DLLS填写Assembly-CSharp,表示将Assembly-CSharp程序集作为热更新程序集。

构建项目

  1. 官方推荐新手将Assembly-CSharp作为热更新程序集,那么笔者这里也创建一个新的程序集作为热更新的入口——Main.asmdef
  2. 新建文件夹A(任意名称)来放主入口程序集,把Main.asmdef放进来
  3. 模仿官方案例的设置,在Main.asmdef中添加对HybirdRuntime的引用
  4. 在A中新建脚本LoadDll.cs,模仿官方案例即可,就改了一小段:
  void StartGame()
    {
        LoadMetadataForAOTAssemblies();

        ass = System.Reflection.Assembly.Load(GetAssetData("Assembly-CSharp.dll"));

        var klass = ass.GetType("SaySth");
        var method = klass.GetMethod("SayHello");
        string str =  (string)method.Invoke(null, null);
        textMeshPro.text = str;

    }

当然你得在Assembly-CSharp中先创建个脚本:

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

public class SaySth : MonoBehaviour
{
    public static string SayHello()
    {
         string tes = "hello,world";
        //string tes = "---------hello,world";

        //Debug.Log(tes);
        return tes;
    }

}

  1. 然后把官方案例的Editor文件夹的脚本BuildAssetsCommand.cs拷过来用。因为没有使用预制体打包,所以稍微裁剪一下:
using HybridCLR.Editor.Commands;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;

namespace HybridCLR.Editor
{
    public static class BuildAssetsCommand
    {
       
        [MenuItem("HybridCLR/Build/BuildAndCopyAOTHotUpdateDllsToStreamingAssets")]
        public static void BuildAndCopyAOTHotUpdateDlls()
        {
            BuildTarget target = EditorUserBuildSettings.activeBuildTarget;

            CompileDllCommand.CompileDll(target);

            CopyAOTHotUpdateDlls(target);
        }

        public static void CopyAOTHotUpdateDlls(BuildTarget target)
        {

            CopyAOTAssembliesToStreamingAssets();
            CopyHotUpdateAssembliesToStreamingAssets();
        }

        /// <summary>
        /// 元数据dll名称,为了解决AOT泛型问题
        /// </summary>
        public static List<string> AOTMetaAssemblyNames { get; } = new List<string>()
        {
            "mscorlib.dll",
            "System.dll",
            "System.Core.dll",
        };

        /// <summary>
        /// 把AOT元数据丢到streamingasset
        /// </summary>
        public static void CopyAOTAssembliesToStreamingAssets()
        {
            var target = EditorUserBuildSettings.activeBuildTarget;
            string aotAssembliesSrcDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
            string aotAssembliesDstDir = Application.streamingAssetsPath;

            foreach (var dll in AOTMetaAssemblyNames)
            {
                string srcDllPath = $"{aotAssembliesSrcDir}/{dll}";
                if (!File.Exists(srcDllPath))
                {
                    Debug.LogError($"ab中添加AOT补充元数据dll:{srcDllPath} 时发生错误,文件不存在。裁剪后的AOT dll在BuildPlayer时才能生成,因此需要你先构建一次游戏App后再打包。");
                    continue;
                }
                string dllBytesPath = $"{aotAssembliesDstDir}/{dll}.bytes";
                File.Copy(srcDllPath, dllBytesPath, true);
                Debug.Log($"[CopyAOTAssembliesToStreamingAssets] copy AOT dll {srcDllPath} -> {dllBytesPath}");
            }
        }

        /// <summary>
        /// 将热更新dll改名,丢到streamingasset
        /// </summary>
        public static void CopyHotUpdateAssembliesToStreamingAssets()
        {
            var target = EditorUserBuildSettings.activeBuildTarget;

            string hotfixDllSrcDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
            string hotfixAssembliesDstDir = Application.streamingAssetsPath;
            foreach (var dll in SettingsUtil.HotUpdateAssemblyFiles)
            {
                string dllPath = $"{hotfixDllSrcDir}/{dll}";
                string dllBytesPath = $"{hotfixAssembliesDstDir}/{dll}.bytes";
                File.Copy(dllPath, dllBytesPath, true);
                Debug.Log($"[CopyHotUpdateAssembliesToStreamingAssets] copy hotfix dll {dllPath} -> {dllBytesPath}");
            }
        }


    }
}

  1. 然后可以点击HybirdCLR/Build/BuildAndCopyAOTHotUpdateDllsToStreamingAssets,将热更新程序集和3个AOT用到的元数据补充程序集改名打包到StreamingAssets中
  2. 点击Build打包即可
  3. 现在可以修改SayHello方法中的逻辑,来查看热更新的效果。修改后再次点击HybirdCLR/Build/BuildAndCopyAOTHotUpdateDllsToStreamingAssets来更新Assembly-CSharp.dll.bytes文件的内容,然后简单替换这个文件即可。可以看到笔者这里分别输出了不同的字符串,改变了文本;

请添加图片描述

请添加图片描述

补充

来回切换Assembly-CSharp.dll.bytes时,笔者发现有时候文本没有更新。查看IIS缓存配置,然后修改了IIS如下,这样切换bytes文件后,可以及时更新了。

在这里插入图片描述


致谢

最后要感谢一下群里大佬们的耐心教导,这个群非常的好,人多说话又好听,新手群号

428404198

有时间的话建议再看看官方文档里面对原理的描述,深刻理解一下与其他主流热更新框架的区别。

参考资料

热更新的基础知识,以及一些主流热更新框架介绍
HybridCLR/huatuo,GitHub
unity中的AOT、JIT、IL2CPP、Mono
unity程序集——类似DLL,能够把unity工程中的脚本划分到不同的程序集
HybridCLR官方文档

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

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

相关文章

基于开源体系的云原生微服务治理实践与探索

作者&#xff1a;董艺荃&#xff5c;携程服务框架负责人 携程微服务产品的发展历程 携程微服务产品起步于 2013 年。最初&#xff0c;公司基于开源项目 ServiceStack 进行二次开发&#xff0c;推出 .Net 平台下的微服务框架 CServiceStack。 2014 年&#xff0c;公司推出 Jav…

【PhD Debate —11】矛与盾的对决——神经网络后门攻防

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;2022年7月9日&#xff0c;AI TIME组织了Ph.D. Debate第十一期&#xff0c;题为“矛与盾的对决——神经网络后门攻防”的研讨活动&#xff0c;特别邀请了宾夕法尼亚州州立大学电子工程系博士生向臻、清华大学博士生…

区块链基础知识(一)

参考书籍《区块链原理、设计与应用》 基本原理 比特币网络工作流程 技术的演化与分类 分布式共识 交易性能 扩展性问题 数据库和存储系统 数据库也是区块链中重要的一环 分布式系统核心问题 单节点结构演变为分布式系统&#xff0c;首先遇到的问题就是一致性的保障。 一致性问…

小程序开发经验分享(5)-全屏展示小程序

小程序的 navigationBar,有APP开发经验的同学应该知道,navigationBar也就是程序最顶部的一条,我们同常的开发页面,也都是在navigationBar下方的主体区用标签开发UI部分 如下面两个图片,左边的翻译君官方小程序中上面就有这样一个navigationBar用于展示自己的title和菜单按…

K8s 认证工程师 CKA 考题分析和题库练习(下)

目录 10、考核知识&#xff1a;检查可用节点数量 题目内容 题目内容中文解释 做题解答 11、考核知识&#xff1a;一个 Pod 封装多个容器 题目内容 题目内容中文解释 官方文档搜索关键字&#xff1a;pod ​编辑做题解答 12、考核知识&#xff1a;持久卷 PersistentV…

Mac M1芯片 搭建RocketMQ

Mac M1芯片 搭建RocketMQ RocketMQ需要启动三个组件 1、nameserver 路由中心,为整个MQ集群提供服务协调与治理 2、broker 提供消息的转发和存储功能 3、console 控制台面板工具 1、下载RocketMQ https://rocketmq.apache.org/dowloading/releases/ 选择 Binary: rocketmq-all-4…

对外投资追踪汇率数据金融开放指数

一、2005-2020年中国全球投资追踪数据 “中国全球投资跟踪”&#xff08;China Global Investment Tracker&#xff09;数据库&#xff0c;由美国企业研究所于1月28日发布。该数据库是唯一一套涵盖中国全球投资和建设的综合数据集&#xff0c;同时使用分别记录和汇总记录两种方…

这几个算法可视化网站,太牛了!

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/Tyson0314/Java-…

深入 Android 底层服务(service)

前言 我们都知道&#xff0c;字节最近发布了PICO&#xff14;VR眼镜&#xff0c;我买了一个&#xff0c;体验还行。因为我也是做VR眼镜的Android应用层开发的&#xff0c;所以想把自己项目中遇到的一些Android技术分享给读者。近些年随着VR眼镜的兴起&#xff0c;Android的的服…

项目经理跨部门沟通,如何避免踢皮球?

软件项目干系人越多&#xff0c;沟通成本也就越高&#xff0c;非常容易出现相互提皮球的现象。那么如何高效沟通&#xff1f; 1、划分干系人 不同干系人不同策略 软件项目涉及干系人众多&#xff0c;项目不经理不可能对每一个人进行详细沟通&#xff0c;那么我们需要将干系人的…

如何把优化Docker镜像大小

什么是Docker Docker是一个开源的虚拟化平台&#xff0c;可以让开发人员将应用程序和依赖项打包在轻量级容器中&#xff0c;然后可以轻松地在任何环境中运行。这样&#xff0c;开发人员可以将容器作为独立的可移植单元在不同的环境中部署和运行应用程序&#xff0c;而不用担心环…

系统学习ElasticSearch

1.1 、ElasticSearch&#xff08;简称ES&#xff09; Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。 能够达到实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。 客户端支持Java、.NET&#xff08;C#&#xff09;、…

SAP FICO财务月结-外币评估

月末操作-外币评估 —文章整理自高林旭老师的《由浅入深学习SAP财务》一书&#xff0c;SAP相关从业人员值得一读。 企业的外币业务在记账的时候一般都是使用期初的汇率或者即时汇率&#xff0c;但是在月末&#xff0c;需要按照月末汇率对外币的余额或者未清项进行重估&#xf…

c语言入门-3-打印复杂类型

打印复杂类型前言上代码字符整形浮点型打印超长小数向内存中申请空间局部变量&#xff0c;全局变量使用输入函数 scanf作用域生命周期深度解析1 c语言中数据类型2 这些字段类型的大小又是多少呢3 计算机的大小单位4 scanf 报错下一篇前言 语言本身的学习&#xff0c;有两点比较…

【前端】Vue项目:旅游App-(7)city:搜索框search和标签页Tabs

文章目录目标过程与代码搜索框初步自己实现取消功能样式修改标签页效果总代码修改的文件common.csscity.vuemain.js目标 过程与代码 搜索框 初步 在Vant文档中找到搜索框&#xff1a;Search搜索 按照文档要求引入&#xff08;如果以插件的形式安装vant就不用这样引入&#x…

c语言 动态内存分配 柔性数组

常见的动态内存错误 对null指针的解引用操作 int main()//错误1 因为没有判断 {int* p (int*)malloc(10000);int i 0;for (i 0; i < 10; i){*(p i) i;}return 0; }对动态开辟空间的越界访问 int main() {int* p malloc(10 * sizeof(int));if (p NULL){return 1;}…

5G NR标准: 第16章 初始接入

第16章 初始接入 在 NR 中&#xff0c;初始接入功能包括&#xff1a; • 设备在进入系统覆盖区域时最初找到小区的功能和过程。 • 处于空闲/非活动状态的设备访问网络的功能和程序&#xff0c;通常是请求建立连接&#xff0c;通常称为随机访问。 在相当大的程度上&#xff0…

ORA-27102:out of memory Linux-x86_64 Error: 12: Cannot allocate memory

一 问题描述 无法启动数据库&#xff0c;报错&#xff1a; 二 排查思路 1.确保sga_target,sga_max_size比可用物理内存小 2.检查kernel.shmmax&#xff0c;kernel.shmall是否设置得太小 一般出现ORA-27102&#xff1a;out of memory&#xff0c;是/etc/sysctl.conf种内核参…

Apache Tomcat 存在 JsonErrorReportValve 注入漏洞(CVE-2022-45143)

漏洞描述 Apache Zeppelin是一款基于 Web 可实现交互式数据分析的notebook产品。 在Apache Zeppelin 0.10.1及以前的版本中“Move folder to Trash”功能存在路径遍历漏洞&#xff0c;由于未对InterpreterSettingManager类remove方法中id参数进行正确校验&#xff0c;攻击者可…

看完这篇文章,我再也不用担心线上出现 CPU 性能问题了(上)

目录CPU 使用率平均负载进程上下文切换总结生产环境上出现 CPU 性能问题是非常典型的一类问题&#xff0c;往往这个时候就比较考验相关人员排查问题的能力我相信不少小伙伴在工作当中多多少少都会碰到 CPU 出现性能瓶颈 不知道小伙伴们有没有跟我一样的感受——当 CPU 出现性能…