zl程序教程

您现在的位置是:首页 >  其他

当前栏目

U3D热更新技术

2023-03-14 22:57:12 时间

目录


理论知识

 冷更新及热更新✔

    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、什么是热更新

🕐:什么是热更新❓

3.gif

🤷‍♂️广义:无需关闭应用,不停机状态下修复漏洞,指软件不通过运营商店的软件版本更新审核,直接通过应用自行下载的软件数据更新资源的行为,重点是更新逻辑代码。

🤷‍♂️狭义:( iOS热更新为例)👉 无需将代码重新打包提交至AppStore,即可更新客户端的执行代码,即不用下载App而自动更新程序。

🤷‍♂️现状:苹果禁止了C#的部分反射操作,禁止JIT(即时编译,程序运行时创建并运行新代码),不允许逻辑热更新,只允许使用AssetBundle进行资源热更新。


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

 3、为何要热更新


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

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

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

🔥 Android,PC(C#)

1.将执行代码预编译为AssemblyDLL

2.将代码作为TextAsset打包进AssetBundle

3.运行时调用AssemblyDLL代码

4.更新相应的AssetBundle即可实现热更新

🔥 iOS(Lua)

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

image.png

5、常见的Unity热更新插件

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

image.png

 6、Lua的加载器规则


流程如👇

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

  热更新Lua语法✔


image.png

基础思维导入如:

image.png

   0、环境安装


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

安装 👉 无脑下一步即可

Windows+R 👉 Lua 如👇(安装成功)

image.png

     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包孢子🍚🍚


image.png

基础思维导入如:

image.png

   0、AB是什么


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

  1、AB包思维导图


image.png

 2、了解AB包有什么作用


相对Resources下的资源AB包更好管理资源

减小包体大小Resources和AB包区别

1、Resources(打包时定死只读无法修改)

2、AB包 👉 存储位置可自定义压缩方式自定义后期可以动态更新

3、减少初始包大小 如:下载游戏后再慢慢更新

热更新

1、资源热更新

2、脚本热更新

3、热更新基本规则

   客户端、自带很少默认资源、资源对比文件

   第一步→ 向服务器获取资源服务器地址

   第二步→ 通过资源对比文件,检查哪些要下载,下载AB包

   服务器 👉 资源服务器、资源对比文件、最新的各种AB包

 3、生成AB包资源文件


image.png

   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);
    }
}

最后


image.png

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

image.png