U3D热更新技术

news2024/11/29 7:41:16

请添加图片描述

@作者 : SYFStrive

@博客首页 : HomePage

📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗

🤷‍♀️:创作不易转发需经作者同意😈

💃:程序员每天坚持锻炼💪

请添加图片描述
在这里插入图片描述
相关专栏

👉 U3D热更新技术(🔥)

目录

  • 理论知识
  •   冷更新及热更新
  •      1、什么是冷更新
  •      2、什么是热更新
  •      3、为何要热更新
  •      4、不同平台的热更新技术
  •      5、常见的Unity热更新插件
  •      6、Lua的加载器规则
  •   热更新Lua语法
  •      0、环境安装
  •      1、Lua面向对象
  •   热更新AssetBundel
  •      0、AB是什么
  •      1、AB包思维导图
  •      2、了解AB包有什么作用
  •      3、生成AB包资源文件
  •      4、UnityAB包
  • 最后

理论知识

  冷更新及热更新

     1、什么是冷更新

🕐:开发者将测试好的代码,发布到应用商店的审核平台,平台方会进行稳定性及性能测试。👉 测试成功后,用户即可在 👉 如苹果的AppStore看到应用的更新信息,用户点击应用更新后,需要先关闭应用,再进行更新。 👉 人话:重装

     2、什么是热更新

🕐:什么是热更新❓

请添加图片描述
🤷‍♂️广义:无需关闭应用,不停机状态下修复漏洞,指软件不通过运营商店的软件版本更新审核,直接通过应用自行下载的软件数据更新资源的行为,重点是更新逻辑代码。
🤷‍♂️狭义:( iOS热更新为例)👉 无需将代码重新打包提交至AppStore,即可更新客户端的执行代码,即不用下载App而自动更新程序。
🤷‍♂️现状:苹果禁止了C#的部分反射操作,禁止JIT(即时编译,程序运行时创建并运行新代码),不允许逻辑热更新,只允许使用AssetBundle进行资源热更新。

注意:2017年6月1日,苹果更新了热更新政策说明,上线后的项目,一旦发现使用热更新,一样会以下架处理

     3、为何要热更新

🧨缩短用户获取新版应用的客户端的流程,改善用户体验具体到iOS平台的应用上,有以下几个原因

  1. AppStore的审核周期难控制 👉 需要5-7天时间甚至更久
  2. 手机应用更新频繁
  3. 对于大型应用,更新成本太大
  4. 终极目标 👉 不重新下载、不停机状态下完全变换一个应用的内容

     4、不同平台的热更新技术

🔥 Android,PC(C#)

  1. 将执行代码预编译为AssemblyDLL
  2. 将代码作为TextAsset打包进AssetBundle
  3. 运行时调用AssemblyDLL代码
  4. 更新相应的AssetBundle即可实现热更新

🔥 iOS(Lua)
苹果官方禁止iOS下的程序热更新;JIT在iOS下无效热更新方案:Unity + Lua插件

请添加图片描述

     5、常见的Unity热更新插件

  1. sLua:最快的Lua插件
  2. toLua:由uLua发展而来的,第三代Lua热更新方案
  3. xLua:特性最先进的Lua插件
  4. ILRuntime:纯C#实现的热更新插件

请添加图片描述

     6、Lua的加载器规则

流程如👇

  1. xLua的单例运行环境
  2. xLua解析器创建销毁
  3. xLua加载器编写
  4. xLua中Lua调用C#代码
  5. xLua中C#调用Lua代码

  热更新Lua语法

基础思维导入如:在这里插入图片描述

请添加图片描述

     0、环境安装

环境搭载 👉 https://github.com/rjpcomputing/luaforwindows/

安装 👉 无脑下一步即可
Windows+R 👉 Lua 如👇(安装成功)

在这里插入图片描述

     1、Lua面向对象

继承、封装、多态演示如 👇

--万物之父
Object={}

print("====封装====")
function Object:new()
	local obj={} 
	self.__index=self
	setmetatable(obj,self)
	return obj
end

print("====继承====")
function Object:SubClass( className )
	_G[className]={}
	local  obj = _G[className]
	obj.base=self
	self.__index=self
	setmetatable(obj,self)
end

--新的类
Object:SubClass("Person")

Person.age=18
Person.sex="男"
function Person:Like()
	self.age=self.age+1
	self.sex="男女不分"
end

local obj = Person:new()
print(obj.age)
print(obj:Like())
print(obj.age)
print(obj.sex)	


print("====多态====")
Person:SubClass("Player")
local obj = Player:new()
print(obj.age)

function Player:Like()
	self.base.Like(self)
	self.age=self.age+100
	self.sex="女"
end

local X = Player:new()
print(X:Like())
print(X.age)
print(X.sex)

  热更新AssetBundel

AssetBundel简称AB包孢子🍚🍚

基础思维导入如:在这里插入图片描述

请添加图片描述

     0、AB是什么

  1. 特定于平台的资产压缩包,有点类似压缩文件
  2. 资产包括:模型、贴图、预设体、音效、材质球等等

     1、AB包思维导图

请添加图片描述

     2、了解AB包有什么作用

  • 相对Resources下的资源AB包更好管理资源
  • 减小包体大小Resources和AB包区别
    1、Resources(打包时定死只读无法修改)
    2、AB包 👉 存储位置可自定义压缩方式自定义后期可以动态更新
    3、减少初始包大小 如:下载游戏后再慢慢更新
  • 热更新
    1、资源热更新
    2、脚本热更新
    3、热更新基本规则
        客户端、自带很少默认资源、资源对比文件
        第一步→ 向服务器获取资源服务器地址
        第二步→ 通过资源对比文件,检查哪些要下载,下载AB包
        服务器 👉 资源服务器、资源对比文件、最新的各种AB包

     3、生成AB包资源文件

在这里插入图片描述

     4、UnityAB包

代码如👇

using System.Collections;
using UnityEngine;

public class AB : MonoBehaviour
{
    private void Start()
    {
        //同步加载===============
        //第一步 加载AB包
        AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + "cube");
        //第二部 加载AB包中的资源
        //GameObject obj = ab.LoadAsset<GameObject>("cube");
        GameObject obj1 = ab.LoadAsset("cube", typeof(GameObject)) as GameObject;
        Instantiate(obj1);

        //异步加载===============
        StartCoroutine(AsyLoadAB("aa", "Capsule"));

        //卸载场景中的AB包===============
        AssetBundle.UnloadAllAssetBundles(false);
        ab.Unload(false);

        //当对象使用了不同包里面的资源的时候据需要加载对应的依赖包 才能正常===============
        //AssetBundle ab1 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + "......");

        利用依赖包的关键知识点--利用主包 获取依赖信息===============
        //AssetBundle ab1 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + "StandaloneWindows");
        加载主包中的固定信息
        //AssetBundleManifest abMani = ab1.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        从主包文件中 得到依赖信息
        //string[] strs=abMani.GetAllDependencies("......");
        得到依赖包的名字
        //print("Name");
        //AssetBundle ab2 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + strs[1]);
    }

    IEnumerator AsyLoadAB(string ABNamae, string ABNamae1)
    {
        //第一步 加载AB包
        AssetBundleCreateRequest ab =AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + ABNamae);
        yield return ab;
        //第二部 加载AB包中的资源
        AssetBundleRequest AB= ab.assetBundle.LoadAssetAsync(ABNamae1, typeof(GameObject));
        yield return AB;
        Instantiate(AB.asset as GameObject);
    }
}

最后

在这里插入图片描述
本文到这里就结束了,大佬们的支持是我持续更新的最大动力,希望这篇文章能帮到大家💪

 

                 相关专栏连接🔗
在这里插入图片描述

下篇文章再见ヾ( ̄▽ ̄)ByeBye

在这里插入图片描述

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

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

相关文章

适用于 Windows 的企业级 Subversion 服务器

适用于 Windows 的企业级 Subversion 服务器。 Subversion 的 Windows 身份验证 Windows 身份验证是 VisualSVN 服务器的一个关键特性。此功能专为 Active Directory 域环境设计&#xff0c;允许用户使用其 Windows 凭据访问 VisualSVN 服务器。 VisualSVN Server 支持两种不同…

【Linux】基础IO ——中

&#x1f387;Linux&#xff1a;基础IO 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看…

这些Java基础知识,诸佬们都还记得嘛(学习,复习,面试都可)

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇将记录几次面试中经常被问到的知识点以及对学习的知识点总结和面试题的复盘。 本篇文章记录的基础知识&#xff0c;适合在学Java的小白&#xff0c;也适合复习中&…

趣说 Mysql内存篇 Buffer Pool

讲解顺序 先说 Mysql InnoDB 内存结构 Buffer PoolPage 管理机制Change BufferLog Buffer Buffer Pool 接上回 说到了 LRU 算法对内存的数据 进行淘汰 LRU 算法本身是 最近最少使用的&#xff0c;但是这样就会出现 分不清楚 哪些是真正多次使用的数据 LRU缺点&#xff1a…

软考重点10 知识产权

软考重点10 知识产权一、著作权1. 著作权的理解&#xff08;1&#xff09;版权&#xff1a;&#xff08;2&#xff09;人身权与财产权2. 知识产权的归属判定3. 知识产权的归属判定&#xff08;1&#xff09;委托创作&#xff08;2&#xff09;合作开发4. 著作权保护对象及范围5…

为什么要有包装类,顺便说一说基本数据类型、包装类、String类该如何转换?

一、前言 开门见山&#xff0c;首先看看八种基本数据类型对应的包装类&#xff1a; 基本数据类型包装类charCharacterbyteByteshortShortintIntegerlongLongfloatFloatdoubleDoublebooleanBoolean 其中Character 、Boolean的父类是Object&#xff0c;其余的父类是Number 二、装…

【软件测试】毕业打工两年,辞职一年后转行月薪18K,软件测试让我发起了第一春......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 小徐&#xff1a; 毕…

C++ 类和对象 日期类的实现

作者&#xff1a;小萌新 专栏&#xff1a;初阶C 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客目标&#xff1a; 完成Date类的实现 梳理剩下两个默认函数 好困 跑个步去 睡醒啦&#xff01; 继续肝 日期类的实现本章目标一. 日期类的实现1.1 Getmonthday的实现…

CNN的实现与可视化

CNN的实现 我们已经实现了卷积层和池化层&#xff0c;现在来组合这些层&#xff0c;搭建进行手写数字识别的CNN。如下图所示&#xff0c;网络的构成是“Convolution - ReLU - Pooling -Affine - ReLU - Affine - Softmax”&#xff0c;我们将它实现为名为SimpleConvNet的类。 …

R语言—向量

向量&#xff08;vector&#xff09; R 语言最基本的数据结构是向量。类似于数学上的集合的概念&#xff0c;由一个或多个元素构成。向量其实是用于存储数值型、字符型、或逻辑型数据的一维数组。 创建向量 c()函数 > a <- 1 #给a赋值1 > a #显示a的值 [1] 1 …

【C++初阶】类和对象终极篇

文章目录一.加const修饰this指针二.cout<<自定义类型的对象的实现1.深入理解cout和<<2流插入和流提取3.友元函数的来源a.作为ostream成员函数b.作为全局函数c.作为Date类的成员函数d.作为Date类的友元函数三.再谈构造函数之初始化列表四.隐式类型转换&explicit…

Linux命令从入门到实战----文件目录类

文章目录pwd显示当前工作路径的绝对路径ls列出目录的内容cd切换目录mkdir 创建一个新的目录删除一个空的目录touch创建新文件cp复制文件或目rm删除文件或目录mv移动文件与目录&#xff0c;重命名文件cat查看文件内容&#xff0c;创建新文件more文件内容分屏查看less分屏显示文件…

【C语言】字符串、字符数组

目录 写在开头 正文 一、字符串的本质 二、输入函数scanf和gets 三、输出函数printf和puts 四、字符串的长度——strlen 五、字符串的复制——strcpy 六、字符串的比较函数 七、实战练习 八、二维字符数组——字符串数组 写在最后 写在开头 看了标题&#xff0c;是…

Kotlin编程实战——类与对象(05)

一 概述 类与继承属性和字段接口(interface )函数式&#xff08;SAM&#xff09;接口可见性修饰符扩展数据类(data class)密封类泛型嵌套类与内部类枚举类对象表达式与对象声明类型别名内联类(inline class)委托委托属性 二 类与继承 类继承(open override )抽象类(abstract)…

MySQL去重中 distinct 和 group by 的区别

今天在写业务需要对数据库重复字段进行去重时&#xff0c;因为是去重&#xff0c;首先想到的是distinct关键字。于是一小时过去了。。。。&#xff08;菜鸟一个&#xff0c;大家轻点骂&#xff09; 我把问题的过程用sql语句演示给大家演示一下 首先我使用的是mybatis-plus&am…

数据结构之哈希表

文章目录 一、概念二、哈希冲突三、如何解决哈希冲突&#xff1f; 1.哈希函数设计2.负载因子调节3.闭散列4.开散列&#xff08;哈希桶&#xff09;四、模拟实现哈希桶总结一、概念 顺序结构以及平衡树中&#xff0c;元素与其存储位置之间没有对应的关系&#xff0c;因此在查找一…

C++多态学习笔记

C多态学习笔记一、多态概述二、多态的作用三、多态发生的三个条件四、多态实现的原理五、接口的定义六、模板方法模式七、虚析构函数和纯虚析构函数7.1 虚析构函数7.2 纯虚析构函数八、重写重载重定义九、父类引用子类对象一、多态概述 同一个操作作用于不同的对象&#xff0c;…

2014年848数据结构真题复习

求k频度K0; for&#xff08;i1;i<n;i&#xff09; 假如是1——8&#xff0c;执行了9次&#xff0c;8次有效&#xff0c;最后一次无效for&#xff08;ji;j<n;j&#xff09;k 我的理解&#xff1a;假设n为8我们看k频度实际上就是看内圈for的有效循环次数第一轮是1——8 八次…

基础算法 第七课——归并排序

文章目录导言归并排序的概念步骤说明逐步分析STEP1STEP2STEP3STEP4STEP5STEP6STEP0总结导言 这&#xff0c;是一篇现学现卖的文章。因为&#xff0c;我根本没学过归并排序。所以&#xff0c;这篇文章&#xff0c;绝对能让您学懂归并。如果不懂&#xff0c;那我就再学一遍&…

KVM Forum 2022应该关注的话题

1. QEMU 和 KVM 自动性能基准测试 QEMU & KVM Automated Performance Benchmarking SUSE - Dario Faggioli, SUSE SUSE正在开发一个框架&#xff0c;用于对虚拟化工作负载进行自动性能基准测试。它是围绕着MMTests&#xff08;已经在Linux内核社区使用了几年&#xff09;建…