版权声明:本文为博主原创文章,遵循 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依赖的更多相关文章

  1. Unity5.X 新版AssetBundle打包控制

    一.什么是AssetBundle 估计很多人只知道Unity的模型之类的东西可以导出成一种叫做AssetBundle的文件,然后打包后可以在Unity程序运行的时候再加载出来用.那么AssetBund ...

  2. Unity5.x版本AssetBundle加载研究

    之前说了 “Unity5.x版本AssetBundle打包研究”,没看过的请先看一下:http://www.shihuanjue.com/?p=57 再来看本文,有一定的连接性. 先梳理一下思路: 要 ...

  3. 处理Assetbundle依赖关系时想到的一道题

    在处理unit3d的assetbundle依赖关系的时候,想到了一道有趣的题目: 给定一堆数据,例如{A = {1, 3, 4}, B = {3, 4}, C = {5, 6}, D = {6, 7, ...

  4. 【Unity3D技术文档翻译】第1.4篇 AssetBundle 依赖关系

    上一章:[Unity3D技术文档翻译]第1.3篇 创建 AssetBundles 本章原文所在章节:[Unity Manual]→[Working in Unity]→[Advanced Develo ...

  5. 转:深入浅出spring IOC中四种依赖注入方式

    转:https://blog.csdn.net/u010800201/article/details/72674420 深入浅出spring IOC中四种依赖注入方式 PS:前三种是我转载的,第四种是 ...

  6. spark 源码分析之一 -- RDD的四种依赖关系

    RDD的四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和OneToOneDependency四种依赖关系.如 ...

  7. spring四种依赖注入方式(转)

    spring四种依赖注入方式!! 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提 ...

  8. Unity5.x版本AssetBundle打包研究

    Unity5的AssetBundle打包机制和以前版本不太一样.简单的说就是,只要给你要打包的资源设置一个AssetBundleName ,Unity自身会对这些设置了名字的资源进行打包,如果一个资源 ...

  9. 细数Javascript技术栈中的四种依赖注入

    作为面向对象编程中实现控制反转(Inversion of Control,下文称IoC)最常见的技术手段之一,依赖注入(Dependency Injection,下文称DI)可谓在OOP编程中大行其道 ...

随机推荐

  1. java @postconstruct初始化注解使用

    1.从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion):@PostConstruct和@PreDestroy.这两个注解被用来修饰一个非静态的 ...

  2. KD-tree学习笔记(超全!)

    目录 K-D树 更新信息 建树 插入 查询 k远/近询问 重构 K-D 树优化建边 后记 因为之前找不到全的博客,唯一的一篇码风比较毒瘤... 所以我就来写了 K-D树 大概是高维二叉树吧 每次按一个 ...

  3. mysql 分页offset过大性能问题解决思路

    在公司干活一般使用sqlserver数据库.rownumber分页贼好用. 但是晚上下班搞自己的事情就不用sqlserver了.原因就是自己的渣渣1核2g的小服务器完全扛不住sqlserver那么大的 ...

  4. 使用golang插入mysql性能提升经验

    前言 golang可以轻易制造高并发,在某些场景很合适,比如爬虫的时候可以爬的更加高效.但是对应某些场景,如文件读写,数据库访问等IO为瓶颈的场合,就没有什么优势了. 前提基础 1.golang数据库 ...

  5. Mr. Rito Post Office

    あなたは離島の郵便局に勤めるプログラマである.あなたの住んでいる地域は,複数の島々からなる.各島には一つ以上の港町がある.それらに加えて他の町や村があるかもしない.ある島から別の島に向かうためには船を ...

  6. mysql启动错误1067进程意外终止的解决方法

    一.环境介绍 1.mysql主从复制中的从服务器 2.Windows Server 2008 R2 Enterprise系统 64位操作系统 3.MySQL数据库版本为5.6.34 二.报错详情 从服 ...

  7. USACO环绕岛屿Surround the Islands 并查集 枚举暴力

    题目描述 Farmer John has bought property in the Caribbean and is going to try to raise dairy cows on a b ...

  8. Controller层的方法访问标志与Spring装配与AspectJ切面处理

    最近在做AspectJ实现的日志模块,在spring配置中加入了<aop:aspectj-autoproxy/>,之后发现,只要有用到自定义注解的类,某些方法经MVC请求时就报空指针错误. ...

  9. java集合之linkedList链表基础

    LinkedList链表: List接口的链接列表实现.允许存储所有元素(包含null).使用频繁增删元素. linkedList方法: void addFirst(E e) 指定元素插入列表的开头 ...

  10. RAW网络编程

    LWIP提供了三种的可以被应用程序直接调用的接口API: (1)       低水平的,基于内核/回调函数的API(后面称 RAW API)    适用于数据量不大,没有os的MCU (2)      ...