Unity5-ABSystem(四):AssetBundle依赖
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lodypig/article/details/51873426
AssetBundleExtractor
AssetBundle依赖打包
 打包时收集依赖
 UI打包测试
总结
有依赖的AssetBunlde加载
 预加载依赖AssetBundle
 通过总manifest依赖加载
Shader依赖打包加载
AssetBundleExtractor
  其实前面几章已经介绍完毕了AssetBunlde功能。但AssetBundle稍不注意,就会留下难忘的踩坑回忆。所以先推荐AssetBundleExtractor这个工具,能够查看AssetBundle内到底有哪些资源,让不良资源无所遁形。效果如图:
  
  
 附上下载地址:
 32位下载地址
 64位下载地址
AssetBundle依赖打包
 打包时收集依赖
  在Unity5-ABSystem(二):AssetBundle导出中,我们提到打包有一个BuildAssetBundleOptions,其实它还有藏了一个选项,即BuildAssetBundleOptions.CollectDependencies。在Unity5中这一项是默认开启的,代表会自动收集所选资源的依赖资源。例如一个prefab中引用到了一张图片,Unity5会自动将该图片也一并打包,避免因资源遗漏导致关联丢失的情况出现。
  这个特性十分的方便,我们只需要将所有东西都制成prefab,将prefab作为资源指定给AssetBundle,由Unity自己去收集所用到的资源就好了。但实际项目中仅仅如此是不够的,原因在复用的资源上。
  如果多个prefab使用到了同一个资源,会出现什么情况呢?我们来试验一下。
 UI打包测试
  4个Sprite,从1-4大小分别是1.2M, 104.2K, 59.7K, 2.3K
   
  7个prefab,其中None代表空的canvas,Image代表canvas下有空的Image,其他数字每一位代表canvas下有个对应图片序号的Image。
   
  我们使用不压缩的方式,将每个Prefab单独指定一个同名的AssetBundle,调用一次build接口。即每个AssetBundle只包含prefab资源,由Unity自己去收集prefab依赖的图片。结果如图:
  
  从最终的AssetBundle大小不能猜出,sprite1234.ab、sprite123.ab和sprite1.ab都拥有一份自己的sprite1.png,不然不可能有超过1M的大小,通过AssetBundleExtrator可以验证这一点。也就是说,我们采用这种打包方式,被多次引用到的资源将在每个用到它的AssetBundle独自存在一份。这里的sprite1.png就存在了三份。也就是常常提到的资源冗余。三份Sprite1自然有三份内存占用,传递给显卡时也需要传递三份,cpu也无法对使用不同图的渲染命令进行合并优化,哪怕它们是一模一样的Sprite1.png。
  那如果我将sprite1.png,添加到sprite1.ab的资源列表中,也就是说sprite1.ab中除了包含sprite1.prefab作为资源外,还包含了sprite1.png作为资源,情况会怎么样呢?结果如图:
  
  我们从文件大小或用AssetBundleExtrator查看可以确定,sprite1.png只在sprite1.ab中,其他AssetBundle中不再重复包含sprite1.png资源了。
  如果再仔细点,查看一下sprite1234.ab的manifest文件:
  
  这里它写下了自己是不完整的,需要依赖sprite1.ab,因为它所爱的sprite1.png已经进入了sprite1.ab。
总结
  对于多次引用的资源,必须明确出现在某个AssetBundle的资源列表中,Unity才能形成依赖关系,不重复打包。而且这些AssetBundle必须存在于同一AssetBundleBuild[]列表中,一次调用BuildPipeline.BuildAssetBundles(),分批多次调用build接口也不能形成依赖。
  同时建议公共的资源单独抽出来做一个AssetBundle,而不是合并到某一个依赖者中。
  备注:同理,使用编辑器导出,多次引用的资源也要明确指定其AssetBundle名称,不指定名称仅通过依赖会导致重复打包。
有依赖的AssetBunlde加载
 预加载依赖AssetBundle
  这个时候如果我们单独加载sprite1234.ab,会发现使用sprite1.png的Image对象上的图已经missing,显示也为错误的白色。原因是sprite1234.ab已经不再包含图片sprite1.png,如果我们只加载sprite1234.prefab,明显没有办法找到sprite1.png。一种解决方法是提前加载sprite1.ab(不必从中加载sprite1.png,只需AssetBundle对象在内存即可),再加载sprite1234.prefab就行了。Unity在这里做的很方便,对于有依赖的AssetBundle,只需确保依赖的AssetBundle已经被加载且未被释放,即可正常加载资源。
 通过总manifest依赖加载
  预加载的局限性比较大,如果想自动且灵活地加载依赖AssetBundle,就要用到Unity5-ABSystem(二):AssetBundle导出中提到的总manifest文件。
  总manifest AssetBundle是一个在outputPath下的AssetBundle,每次调用build接口都会自动生成,名称与目录名相同,它包含了总manifest文件。例如build时指定路径为E:\lodypig\test,则会自动在test文件夹下生成一个名为test的AssetBundle,包含了总manifest文件,记录了所有的依赖关系。
  所以如果需要自动加载依赖AssetBundle,我们需要先将包含总manifest文件的AssetBundle加载进来,从中加载出总manifest,通过总manifest查找依赖,再加载依赖的AssetBunlde就好。总manifest资源名一定是AssetBundleManifest。
  这里只给出获取依赖的示例代码,支持依赖的加载接口可以自己据此实现:
static void GetAssetBundleDependencies()
 {
        // 将这个换成对应的outputPath下outputPath路径
        // 这里outputPath = StreamingAssetPath
        string assetbundlePath = Application.streamingAssetsPath + "/StreamingAssets";
AssetBundle manifestAB = AssetBundle.LoadFromFile(outputPath);  // 加载总ManifestAssetBundle
        AssetBundleManifest manifest = (AssetBundleManifest)manifestAB.LoadAsset("AssetBundleManifest");
        string[] dependencies = manifest.GetAllDependencies("sprite1234.ab");  // 结果 sprite1.ab
        manifestAB.Unload(false);  // 释放AssetBundle,暂时不用理解
}
  我们可以在启动时,先加载并缓存总manifest,修改Unity5-ABSystem(二):AssetBundle导出 中的加载AssetBundle接口,在加载AssetBundle时,先递归加载依赖的AssetBundle。
Shader依赖打包加载
  为了使AssetBundle不重复打包shader,按照上面的思路,很自然想到将shader单独打包,但很快就会遇到两个问题:shader加载和内置shader丢失。
  shader最好在启动时加载,加载后调用Shader.WarmupAllShaders()编译,并永不释放,代码如下:
AssetBundle ab = AssetBundle.Load("shader")
ab.LoadAllAssets();
Shader.WarmupAllShaders();  // 如果不想启动时预编译,也可以不加这句
  对于Unity内置的shader,例如UGUI使用的shader,我们无法将其打到AssetBundle并通过上面的方式加载。这里需要将其添加到Always Included Shaders。在Editor->Project Settings->Graphics中可以找到。Unity将在启动时解析这些Shader,避免在此添加大量shader。
  
  另一种方式是从官网下载Unity内置Shader,加入到依赖包中即可。
————————————————
版权声明:本文为CSDN博主「lodypig」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lodypig/article/details/51873426
Unity5-ABSystem(四):AssetBundle依赖的更多相关文章
- Unity5.X 新版AssetBundle打包控制
		
一.什么是AssetBundle 估计很多人只知道Unity的模型之类的东西可以导出成一种叫做AssetBundle的文件,然后打包后可以在Unity程序运行的时候再加载出来用.那么AssetBund ...
 - Unity5.x版本AssetBundle加载研究
		
之前说了 “Unity5.x版本AssetBundle打包研究”,没看过的请先看一下:http://www.shihuanjue.com/?p=57 再来看本文,有一定的连接性. 先梳理一下思路: 要 ...
 - 处理Assetbundle依赖关系时想到的一道题
		
在处理unit3d的assetbundle依赖关系的时候,想到了一道有趣的题目: 给定一堆数据,例如{A = {1, 3, 4}, B = {3, 4}, C = {5, 6}, D = {6, 7, ...
 - 【Unity3D技术文档翻译】第1.4篇 AssetBundle 依赖关系
		
上一章:[Unity3D技术文档翻译]第1.3篇 创建 AssetBundles 本章原文所在章节:[Unity Manual]→[Working in Unity]→[Advanced Develo ...
 - 转:深入浅出spring IOC中四种依赖注入方式
		
转:https://blog.csdn.net/u010800201/article/details/72674420 深入浅出spring IOC中四种依赖注入方式 PS:前三种是我转载的,第四种是 ...
 - spark 源码分析之一 -- RDD的四种依赖关系
		
RDD的四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和OneToOneDependency四种依赖关系.如 ...
 - spring四种依赖注入方式(转)
		
spring四种依赖注入方式!! 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提 ...
 - Unity5.x版本AssetBundle打包研究
		
Unity5的AssetBundle打包机制和以前版本不太一样.简单的说就是,只要给你要打包的资源设置一个AssetBundleName ,Unity自身会对这些设置了名字的资源进行打包,如果一个资源 ...
 - 细数Javascript技术栈中的四种依赖注入
		
作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...
 
随机推荐
- java工作错误总结
			
1.访问接口出现以下错误 com.alibaba.dubbo.rpc.RpcException: Forbid consumer 192.168.200.126 access service com. ...
 - Spark 学习笔记之 MONGODB SPARK CONNECTOR 插入性能测试
			
MONGODB SPARK CONNECTOR 测试数据量: 测试结果: 116万数据通过4个表的join,从SQL Server查出,耗时1分多.MongoSparkConnector插入平均耗时: ...
 - JavaSE----01.Java简介
			
01.Java简介 1.java介绍 Java是于1995年由Sun公司推出的一种跨平台.面向对象的高级程序设计语言.Java最初的名字叫OAK.Java是一种通过解释方式来执行的语言,其语法 ...
 - Senparc.Weixin.MP SDK 微信公众平台开发教程(二十二):在 .NET Core 2.0/3.0 中使用 MessageHandler 中间件
			
概述 在 <Senparc.Weixin.MP SDK 微信公众平台开发教程(六):了解MessageHandler> 中我们已经了解了 MessageHandler 的运行原理和使用方法 ...
 - requests模块(post)请求篇
			
'''利用parse模块模拟post请求分析百度词典分析步骤:1. 打开F122. 尝试输入单词girl,发现每敲一个字母后都有请求3. 请求地址是 http://fanyi.baidu.com/su ...
 - Win10实现多用户同时进行远程桌面连接的解决方案
			
Win10无法实现多用户远程桌面连接的解决方案以下方法解决Win10无法同时多用户登录.推荐:win10正式版下载 以下为必要步骤需先进行组策略设置,完成后再选择方法1或2(推荐方法2): 远程桌面连 ...
 - Django高级实战 开发企业级问答网站 ✌✌
			
Django高级实战 开发企业级问答网站 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 从实际需求分析开始,实现当今主流知识问答应用的功能,包括动态.文章.问 ...
 - Flannel的VXLAN模式工作原理
			
跨主机通信的一个解决方案是Flannel,由CoreOS推出,最早支持的是UDP模式,但是因为性能太差被淘汰了, 过时的UDP模式 相比两台宿主机直接通信,多出了flanneld的处理过程,发出IP包 ...
 - App元素定位
			
1.元素定位(采用Appium-desktop自带的工具) 1.1将初始化参数复制进去校验json格式正确且保存后,点击start session 初始化参数来源如下: # 定义启动设备需要的参数 d ...
 - plSql使用流程
			
1. 下载PLSQL developer.instantclient_11_2, 下载地址:https://pan.baidu.com/s/1_MjmIT4nUzsQ7Hi8MCrs1A, 备注:此安 ...