草庐IT

【Unity基础框架】YooAsset 学习(一)

cyx1144 2023-05-18 原文

YooAsset 学习记录

跟着b站视频+文档学习的

地址:https://github.com/tuyoogame/YooAsset

YooAsset 基于的原理也是来源于Unity的 AssetBundleAddressable
AssetBundle的原理及最佳实践

YooAsset简介

具体的简介项目里都有,就简单截一些了

1.Editor

1.1导入YooAsset

直接看文档。

总共三种,用的是这种

1.2 全局配置


Resources下新建 YooAsset 配置文件

1.3 资源配置

配置直接看文档

1.3.1 AutoCollectShaders

新版已经没有这个选项了。

ShaderVariant Collector 仍在

旧版:

搜集所有Group内的材质球,把它们的shader打入一个包内

这里设置好后打开

为了防止Shader资源荣誉,点击搜集变种生成

点击完毕后,会跳到它给我们的一个所有Shader的材质球展示界面。以及生成了 ShaderVariants 的搜集结果文件

然后在热更资源目录新建一个文件夹,放入这个配置文件

然后在YooAsset打包配置里新建一个它的收集器

专门为它自定义一个打包规则

这里返回的名称和Shader Bundle Name一致

最后给搜集器换成自定义的打包规则类即可

1.4 资源打包


记录一些配(详细配置请看文档,只记录了部分)

  • Build Pipeline 构建管线

    1. BuiltinBuildPipeline: 传统的内置构建管线。
    2. ScriptableBuildPipeline: 可编程构建管线。
  • Build Mode 构建模式

    1. 强制构建模式:会删除指定构建平台下的所有构建记录,重新构建所有资源包。
    2. 增量构建模式:以上一次构建结果为基础,对于发生变化的资源进行增量构建。
    3. 演练构建模式:在不生成AssetBundle文件的前提下,进行演练构建并快速生成构建报告和补丁清单。
    4. 模拟构建模式:在编辑器下配合EditorSimulateMode运行模式,来模拟真实运行的环境。
  • Output Name Style 输出的资源包文件名称样式

    1. HashName:哈希值
    2. HashName_Extension:哈希值+后缀名
    3. HashName_BundleName_Extension:资源包名+哈希值+后缀名
  • Copy Buildin File Option 首包资源文件的拷贝方式

    1. None:不拷贝任何文件
    2. ClearAndCopyAll:先清空已有文件,然后拷贝所有文件
    3. ClearAndCopyByTags:先清空已有文件,然后按照资源标签拷贝文件
    4. OnlyCopyAll:不清空已有文件,直接拷贝所有文件
    5. OnlyCopyByTags:不清空已有文件,直接按照资源标签拷贝文件

重要概念

  • 增量构建
    增量构建是在Unity的帮助下实现的一种快速打包机制。主要是利用资源构建相关的缓存文件来避免二次构建,以此来提高打包效率。
  • 强制构建
    强制构建是每次构建之前,都会清空之前构建的所有缓存文件,以此来重新构建资源包。
  • 首包资源
    在构建应用程序的时候,我们希望将某些资源打进首包里,**首包资源拷贝至StreamingAssets/BuildinFiles/目录下。**首包资源如果发生变化,也可以通过热更新来更新资源。
  • 补丁包
    无论是通过增量构建还是强制构建,在构建完成后都会生成一个以包裹版本(PackageVersion)命名的文件夹,我们把这个文件夹统称为补丁包。补丁包里包含了游戏运行需要的所有资源,我们可以无脑的将补丁包内容覆盖到CDN目录下,也可以通过编写差异分析工具,来筛选出和线上最新版本之间的差异文件,然后将差异文件上传到CDN目录里。

    不勾就是增量,勾选就是重出包了。

1.4.1 自定义加密


  • Check 检查哪些文件要加密,比如配置表。路径是相对应于Assets下的(“Assets/xxx/xxx”)
  • Encrypt 就是具体的加密算法了。demo里提供了一个简单的数据偏移算法。

1.4.2 Buildin Tags


Buildin Tags 里填的是Group 的 Grouper Asset Tags。就是表示你这次想把哪些 Group 打包。

多个 Tag 用 ; 隔开。 
buildin;level;other

1.4.3 补丁清单

  1. AssetList
    所有通过Grouper搜集器搜到的通过代码加载的资源。

    • AssetPath Asset下的相对路径
    • BundleID 主BundleID
    • DependIDs 以来的BundleID们
  2. BundleList
    根据YooAsset配置生成的所有Bundle了

    上面的BundleID指的就是这个列表下的Bundle

    • Hash 它的hash值
    • CRC 验证完整性
    • SizeBytes 大小
    • Tags 包含了Grouper Asset Tags 和 搜集器上填的 tag
    • Flag 一些附加数据全部存在这里(= =没搞懂)
  3. YooAsset的不同之处

    1. 记录AssetPath对应的资源对象依赖了哪些Bundle。
    2. 记录 AssetPath对应的资源对象的Bundle 依赖了哪些 Bundle

而大部分其他的框架是用 2. 的方式。

而 2. 的方式有个问题。比如有 A、B、C、D 三个 Bundle,对象 X 在 A 、C Bundle 里

X in A Depend A、C
A depend B
B depend C、D

方法 2.
会导入 ABCD
X -> A -> B -> C、D  result ABCD

方法 1. 
直接导入A、C即可。
因为经过计算,这里的依赖是展开的,不是树形,不需要再查每个Bundle下层的依赖了
X in A Depend A、C
X -> A ,X -> C	result A、C

1.5 资源部署


增量更新直接替换就可以了。记得用类似Beyonce Compare比对一线,不用上传没改变的文件。

1.6 构建报告




这个构建报告,在生成的文件下面都有。导入的就是这个东西。

AssetView


Grouper里搜集的,所有通过代码加载的资源对象。

  • Size 大小
  • Main Bundle 位于哪个Bundle里


原生数据其实不是AB包的格式。并且每份都有一个资源包。

BundleView


以Bundle视角的视图。下面可以看到这个Bundle里可以用代码加载的资源列表。

2.代码部分

这部分代码具体请看文档。仅会贴出部分

2.1 初始化

2.1.1初始化资源系统

// 初始化资源系统
YooAssets.Initialize();

// 创建默认的资源包
var package = YooAssets.CreateAssetsPackage("DefaultPackage");

// 设置该资源包为默认的资源包,可以使用YooAssets相关加载接口加载该资源包内容。
YooAssets.SetDefaultAssetsPackage(package);
资源系统的运行模式支持三种:编辑器模拟模式,单机运行模式,联机运行模式。

编辑器模拟模式

	在编辑器下,不需要构建资源包,来模拟运行游戏。
	
	注意:该模式只在编辑器下起效
	
	private IEnumerator InitializeYooAsset()
	{
	    var initParameters = new EditorSimulateModeParameters();
	    initParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage");
	    yield return defaultPackage.InitializeAsync(initParameters);
	}

联机运行模式

对于需要热更新资源的游戏,可以使用联机运行模式,该模式下初始化参数会很多。

注意:该模式需要构建资源包

  • DecryptionServices : 如果资源包在构建的时候有加密,需要提供实现IDecryptionServices接口的实例类。
  • QueryServices:内置资源查询服务接口。
  • DefaultHostServer : 默认的资源服务器IP地址。
  • FallbackHostServer : 备用的资源服务器IP地址。

如果只有一个CDN地址那就都填一样的

	private IEnumerator InitializeYooAsset()
	{
	    var initParameters = new HostPlayModeParameters();
	    initParameters.QueryServices = new QueryStreamingAssetsFileServices();
	    initParameters.DefaultHostServer = "http://127.0.0.1/CDN1/Android/v1.0";
	    initParameters.FallbackHostServer = "http://127.0.0.1/CDN2/Android/v1.0";
	    yield return defaultPackage.InitializeAsync(initParameters);
	}
	
	// 内置文件查询服务类
	private class QueryStreamingAssetsFileServices : IQueryServices
	{
	    public bool QueryStreamingAssets(string fileName)
	    {
	        // 注意:使用了BetterStreamingAssets插件,使用前需要初始化该插件!
	        string buildinFolderName = YooAssets.GetStreamingAssetBuildinFolderName();
	        return BetterStreamingAssets.FileExists($"{buildinFolderName}/{fileName}");
	    }
	}

老版本和新版本差异有点大啊

源代码解析

编辑器模拟模式

每次启动调用EditorSimulateModeHelper.SimulateBuild()方法,都会在底层执行一次模拟构建(Simulate Build)。

如果参与构建的资源对象数量级很大的话则会有卡顿现象,可以通过直接指定已有的清单路径来避免每次都重复执行模拟构建。

单机运行模式

在初始化的时候,会直接读取内置清单文件(StreamingAssets文件夹里的文件),最后根据加载的清单去验证沙盒里缓存的文件。

联机运行模式

在初始化的时候,会优先从沙盒里加载清单,如果沙盒里不存在,则会尝试加载内置清单并将其拷贝到沙盒里。最后根据加载的清单去验证沙盒里缓存的文件。

注意:如果沙盒清单和内置清单都不存在,初始化也会被判定为成功!

2.2 资源更新


demo里实现了一个状态机,咱们可以直接拿来用。

文档和视频内容有差异,这里只好直接用视频的文档截图了


也可以自己写HTTP逻辑来访问。


这里的 tags 就是对于的 Grouper Asset Tags ,表示你想下载那个 Grouper。

不太理解这么做的原因= =。

2.2.1 路径

内置文件


重新强制出包的时候,把生成的内容放到如图目录下。

沙盒

在PC上的地址和Asset同级,应该就是可写目录了。也就是热更新文件的存放位置。

2.2.2 下载器


补丁下载目前只有两种,传入单/多 个Grouper Asset Tag 。

这样可以实现按需下载,比如我可以在进入关卡的时候再下载这个关卡的资源(进入关卡Loading的时候下载)。

3.补充部分

3.1 Sample 改造

我直接拿Sample里的Sapce Shooter的热更流程来改了



大致保留这些就行了。

还有提供的UniFramework系类的挺好用的,要是不想自己写事件系统之类的,可以直接拿来用。

3.2 UniTask接入

4.AssetBundle 学习笔记(简略)

Unity学习—AssetBundle

以下内容为此博客的笔记。

详细介绍请看博客,这里只记简略。

4.1 AssetBundle 作用

  • AssetBundle 是外部资产的集合,可独立于 Unity 构建过程外,是 Unity 更新非代码内容的主要工具;
  • AssetBundle 使开发者可以提交更小的应用包,最小化运行时内存压力,使终端可以选择性加载优化内容

4.2AssetBundle 组成

AssetBundle 主要由两部分组成:文件头和数据段

文件头包含了id、压缩类型、索引清单,该索引清单是与 Resources 相同的记录了序列化文件中的字节偏移量的查找表。对于大部分平台该表为平衡搜索树,对 Windows 和 OSX 系列(包括 iOS)则为红黑树,随着 AssetBundle 中对象的增加,构造清单所需时间的增长速度将超过线形增长速度

数据段包含了 Asset 经过序列化的原始数据,数据还可选择是否压缩,

  • 若使用 LZMA 压缩,则将所有 Asset 的字节数组整体压缩;
  • 若使用 LZ4 压缩,则将每个 Asset 单独压缩;
  • 若不压缩,则数据保持原始字节流

4.3AssetBundle 加载

有四种不同的 API 用于加载 AssetBundle,但每个 API 的行为随压缩算法和平台而不同

  • AssetBundle.LoadFromMemoryAsync
  • AssetBundle.LoadFromFile
    该方法可高效地从硬盘加载未压缩或 LZ4 压缩的 Assetbundle,加载 LZMA 压缩包时会先解压再加载到内存
  • WWW.LoadfromCacheOrDownload(5.6 及以前版本)旧方法,已抛弃
  • UnityWebRequestAssetBundle (5.3 及以后版本)

官方推荐尽量使用 AssetBundle.LoadFromFile,该 API 在速度、磁盘使用和运行时内存使用方面都最高效;需要下载则使用 UnityWebRequest

注:Web平台都用 UnityWebRequest 来加载,web平台没有本地存储数据

4.4 AssetBundle Asset 加载

同步异步加载 Asset 一共有六种 API 可使用

  • LoadAssets (LoadAssetsAsync)

  • LoadAssetWithSubAssets (LoadAssetWithSubAssetsAsync)
    适合需要加载的对象内嵌了其他对象的情况,若加载对象均来自于一个 Asset 且包中有许多其他无关对象,则使用该 API

  • LoadAllAsset (LoadAllAssetAsync)
    其他情况均用LoadAsset (LoadAssetAsync)

4.5 AssetBundle 依赖

当一个对象所在的 AssetBundle 被加载时,该对象就被分配了一个唯一的有效实例 ID。Unity 不会自动加载子 AssetBundle。就是不会加载你的依赖,咱们必须自己处理加载依赖的AssetBundle。

在构建 AssetBundle 时,Unity 创建一个包含每一个 AssetBundle 依赖信息的类型为 AssetBundleManifest 的序列化对象,该文件存在一个与其他 AssetBundle 在同一打包路径下的单独的 AssetBundle 中,且与父层文件夹名相同。

有两种 API 查询依赖

  • AssetBundleManifest.GetAllDependencies 获取 AssetBundle 的所有依赖层级
  • AssetBundleManifest.GetDirectDependencies 获取 AssetBundle 直接依赖

因该 API 会生成字符串数组,所以应尽量少用,且避免性能高峰时使用

官方建议
大部分场合下,在进入性能需求高的场景前,尽可能多地加载对象,尤其对于移动平台这种,访问本地存储慢,加载卸载对象引起内存流失会触发垃圾回收的平台

4.6 AssetBundle 使用

这个问题和资源卸载有关。

不适当地卸载 AssetBundle 会导致对象缺失或者在内存中重复。

调用AssetBundle.Unload可卸载 AssetBundle 的头信息,传入参数 true 或 false 决定是否同时卸载该包下所有已加载对象。

  1. 由此诞生一个问题,当卸载了 AssetBundle 未卸载已加载对象时,此时这些对象与 AssetBundle 便失去关联了,重新加载 AssetBundle 并重新加载同一对象时,只会产生一个新的关联对象,而旧对象则无法使用AssetBundle.Unload卸载了,这就导致了内存中同时存在两个一样的对象。

  2. 另外还可能出现的问题是,在 AssetBundle 卸载之后加载 AssetBundle 中的对象时,会出现对象缺失的问题。出现该问题大部分原因为 Unity 丢失又重新获得对图形上下文的控制,如移动设备 App 挂起,PC 锁定等场景

4.7 AssetBundle 发布


也就是说,AssetBundle.LoadFromFile只能在无压缩的apk获取AssetBundle???

4.8 自定义下载器

这部分看博客

4.9 Asset 分包策略

  • 逻辑实体分包
  • 对象类型分包
  • 并发内容分包

    AssetBundle变体是什么意思?

4.10 常见问题

只贴出原因,解决方案请看博客。或者这部分直接到博客里看

4.10.1 资产重复

若有一个未分配资产被多个不同 AssetBundle 中的已分配资产引用,则在构建 AssetBundle 时,该引用对象会被拷贝到每个 AssetBundle 中,造成空间和内存浪费

4.10.2 精灵图集重复

任何自动生成的图集会被分配到其包含精灵所在的 AssetBundle,若精灵对象被分配到多个包,则图集会被复制,因此需确保同一图集的精灵对象被分配到同一 AssetBundle 中

4.10.3 Android 纹理

由于 Android 生态的碎片化,经常需要使用不同格式压缩纹理。

为了适配支持不同纹理格式的android机器。使用AssetBundle变体

5.AssetBundle 变体

AssetBundle Variants 的主要作用在于使 AssetBundle 随运行时环境调整其内容配置。

AssetBundle Variants 使不同 AssetBundle 中的不同对对象在加载时公用一个实例 ID,使其看起来为同一个对象。

个人觉得多渠道多语言也可以用这个。

6.其他

5.问题&解答

Q:自己使用的时候,收集器里只有原生类型的文件,然后报错“No AssetBundle has been set for this build.”

A:
意思就是你的AssetBundle根本没东西啊,没东西用什么AssetBundle。
然后添加了一个Scene到收集器里,就不报错了
。。。服了,原生类型不配算资源呗?

有关【Unity基础框架】YooAsset 学习(一)的更多相关文章

  1. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  2. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  3. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  4. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  5. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  6. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  9. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  10. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

随机推荐