【Unity3D技术文档翻译】第1.8篇 AssetBundles 问题及解决方法

上一章:【Unity3D技术文档翻译】第1.7篇 AssetBundles 补丁更新

本章原文所在章节:【Unity Manual】→【Working in Unity】→【Advanced Development】→【AssetBundles】→【Troubleshooting】

AssetBundles 问题及解决方法

本章节涉及一些使用 AssetBundles 的项目的常见问题。

资源重复(Asset Duplication)

从 Unity5 开始的 AssetBundle 系统会在 Object 被打包进 AssetBundle 的时候,查找所有它的依赖。这是基于资源数据库(Asset Database)实现的。依赖信息用于确定将要被包含进 AssetBundle 的 Objects 集合。

被明确指派了 AssetBundle 的 Objects 将只被打包进该 AssetBundle。一个 Object “被明确指派”的意思是:Object 的 assetBundleName 不为空。

如果 Object 没有被明确指派给一个 AssetBundle,那么该 Object 将会被包含进所有引用了该 Object 的 AssetBundles 中,无论 AssetBundle 中有一个还是多个 Objects 引用了它。

如果有两个不同的 Objects 被分别指派给两个不同的 AssetBundles,并且这两个 Objects 都对另一个 Object 有引用,那么该 Object 将被拷贝进两个 AssetBundles。重复的依赖同样会被实例化,这意味着被依赖的 Object 的两份拷贝会被认为是两个不同的 Objects,且拥有各自的 id。这将增加应用 AssetBundles 的大小。如果应用加载了这两个 AssetBundles,那么就会导致内存中加载了两份 Object 的拷贝。

这里有些方法可以解决这样的问题:

  1. 确保被打包进不同 AssetBundles 的 Objects 没有共同的依赖。把任何有共同依赖的 Objects 打包进同一个 AssetBundle ,避免重复依赖。
  • 这个方法通常不适用于那些有很多共同依赖的项目。并且这个方法会导致作为整体的 AssetBundles 被频繁地重新构建和重新下载,造成不方便和不高效。
  1. 分割 AssetBundles,使得拥有共同依赖的 AssetBundles 不会同时被加载。
  • 这个方法对于特定类型的项目可能有效,比如以关卡为基础的游戏。然而,这会增加项目的 AssetBundles 大小,并且增加构建的次数和加载的次数。
  1. 确保所有被依赖的资源被打包进它们自己的 AssetBundles。这就完全排除了重复资源的风险,但是同样的这会使情况变的复杂。应用必须追踪 AssetBundles 间的依赖关系,并且确保在调用任何 AssetBundle.LoadAsset 方法之前,正确的 AssetBundle 已经被加载好。

在 Unity5 中是通过 UnityEditor 命名空间下的 AssetDatabase 方法来追踪 Object 的依赖。正如命名空间表明的,这个方法只能在 Unity 编辑器中使用,而不是在运行时。AssetDatabase.GetDependencies 方法可被用于定位一个 Object 或者资源的所有直接依赖。注意,这些依赖可能各自也有依赖。此外,AssetImporter 方法可用于查询某个 AssetBundle 中包含的 Object。

组合使用 AssetDatabaseAssetImporter 的方法,就可以编写编辑器脚本,确保一个 AssetBundle 所有的直接或者间接依赖都被打包进一个或者各自的 AssetBundle 中;或者任意两个有共同依赖的 AssetBundles,被打包进同一个 AssetBundle。考虑到重复资源造成的内存开销,建议所有项目都有一个这样的脚本。

Sprite 图集重复(Sprite Atlas Duplication)

当 Unity5 中资源依赖的计算代码,和自动生成 Sprite Atlas 结合使用的时候,会出一点奇异的问题,下面的部分将描述这一点。

任何自动生成的 Sprite 图集,都会和图集生成的 Sprite Objects 一起打包到 AssetBundle 中。如果 Sprite Objects 被分配给多个 AssetBundles,那么 Sprite Atlas 就不会被打包为一个 AssetBundle,并且出现资源重复;如果 Sprite Objects 没有指明 AssetBundle,Sprite Atlas 同样不会被打包为一个 AssetBundle。

想要确保 Sprite Atlas 不重复,需要检查划分到同一个 Sprite Atlas 的 sprites (Tag 相同)要被指明为相同的 AssetBundle。

(Unity 5.2.2p3 会有额外的图集问题,在 Unity 5.2.2p4 已修复,建议用尽可能新的版本,这里不再赘述)

Android 纹理相关问题

由于 Android 生态系统严重的设备碎片化,经常需要将纹理压缩为不同的格式。所有 Android 设备都支持 ETC1 格式图片,然而 ETC1 格式不支持透明通道。如果应用不需要 OpenGL ES 2 的支持,解决问题最简洁的方法就是使用 ETC2 格式,该格式需要 OpenGL ES 3 的支持。

然而大多数应用都需要适配老旧设备,因此 ETC2 格式可能无法使用。解决这个问题的一个办法是使用 Unity5 的 AssetBundle 版本变量。(你还可以查看 Unity 安卓优化指南,来了解更多其他解决方案的细节)

使用 AssetBundle 版本变量,所有不使用 ETC1 格式压缩的纹理必须分配到只包含纹理(texture-only)的 AssetBundles 中。接着,为不支持 ETC2 格式的安卓生态系统创建合适的版本变量,使用特定的纹理压缩格式,比如:DXT5、PVRTC、ATITC。针对每一个版本变量,改变纹理的 TextureImporter 设置,使其与版本变量一致。

在运行时,使用 SystemInfo.SupportsTextureFormat 方法可以检测支持的纹理压缩格式。你可以使用这个信息,根据所支持的格式纹理,选择和加载相应的 AssetBundle 版本变量。

更多关于 Android 纹理压缩格式的信息,可以点击这里查看。

iOS 文件句柄溢出

这个问题在 Unity 5.3.2p2 就已经解决了。

(这个问题简言之就是:iOS 在加载一个 AssetBundle 时会产生一个文件句柄,iOS 的句柄数上限是255个,超过这个上限就会加载失败并报错。这里不再赘述。)

如果本文对你有帮助的话,点个赞或者评论一下吧!

下一章:【Unity3D技术文档翻译】第1.9篇 Unity AssetBundle 浏览管理工具 (终章)

原文地址:https://www.cnblogs.com/hearthstone/p/8478513.html

时间: 2024-10-06 18:35:44

【Unity3D技术文档翻译】第1.8篇 AssetBundles 问题及解决方法的相关文章

unity3d游戏无法部署到windows phone8手机上的解决方法

今天搞了个unity3d游戏,准备部署到自己的lumia 920上,数据线连接正常,操作正常,但是"build"以后,始终无法部署到手机上,也没有在选择的目录下生产任何相关文件. 但是提示有一个错误: Error building Player: Exception: Error: method `System.Byte[] System.IO.File::ReadAllBytes(System.String)` doesn't exist in target framework. I

普元EOS开发积累第一篇(常见错误解决方法) 持续更新

普元启动服务失败的解决方法 当多个人同时使用一个数据库的时候,启动普元控制台会一直停留在rcall,然后显示一个超时的警告,那样就需要修改一下普元的一个定时器配置项. 安装目录下\Primeton\Platform\apps_config\default\config 中的一个user-config.xml文件 将下列代码中高亮字段中的true改为false即可  <module name="Schedule">          <group name="

【Unity3D技术文档翻译】第1.1篇 AssetBundle 工作流

译者前言:本章是关于从创建到加载,再到使用 AssetBundle 的整个流程的概述.阅读本章将对 AssetBundle 的工作流程有个简单而全面的了解. 本章原文所在章节:[Unity Manual]→[Working in Unity]→[Advanced Development]→[AssetBundles]→[AssetBundle Workflow] AssetBundle 工作流 可以按照下面的这些步骤来学习 AssetBundle.关于每个步骤的详细内容,可以在本文档的其他章节中

C++技术问题总结-第15篇 内存泄露有哪些方法定位,崩溃有哪些方法定位

Visual C++内存泄露检测,可采用VLD工具. VLD:Visual Leak Detector.VLD是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号:可以得到泄露内存的完整数据:可以设置内存泄露报告的级别:并且是开源免费的. 官方网址:http://vld.codeplex.com/releases/view/82311 使用步骤: 1)官网下载VLD工具包. 2)解压后得到vld.h, vlda

普元EOS开发积累第二篇(常见错误解决方法) 持续更新

第一步:出现如下图所示的应用名称默认为空.或者下拉框中无default应用可选(下拉框出现的workspace是流程管理应用,非项目应用). 第二部:到安装目录下看看\apache-tomcat-5.5.20\webapps下是否存在default文件夹.如果不存在,就到其他电脑上复制相同版本的default复制到此目录下即可, 第三部:返回第一步去勾选default应用. Ps: 关于多应用部署请看另外一篇博客.

分布式事务(第05篇)分布式事务解决方法-TCC

一 什么是TCC TCC将每个分支事务都分成三个部分(Try.Confirm.Cancel): Try:业务检查及资源预留. Confirm:真正执行业务,不做任何业务检查.使用Try阶段预留的资源. Cancel:实现回滚操作,释放资源. 二 TCC实现分布式事务的流程 第一阶段:全局事务管理器分别调用所有分支事务,所有分支事务进行Try操作,当所有分支事务的Try操作都成功,或者某部分分支事务的Try操作失败,都进入第二阶段. 第二阶段:如果第一阶段所有分支事务Try都成功执行,则全局事务管

分布式事务(第04篇)分布式事务解决方法-3PC

一 什么三阶段提交协议(3PC) 3PC是2PC的改进版本.主要有以下改进: 增加了一个询问阶段,询问阶段可以确保尽可能早的发现无法执行操作而需要中止的行为,但是它并不能发现所有的这种行为,只会减少这种情况的发生. 增加了等待超时的处理逻辑,如果在询问阶段等待超时,则自动中止:如果在准备阶段之后等待超时,则自动提交.这也是根据概率统计上的正确性最大. 二 3PC工作流程 询问阶段:协调者询问参与者是否可以完成指令,协调者只需要回答是还是不是,而不需要做真正的操作,这个阶段参与者在等待超时后会自动

Android官方技术文档翻译——Gradle 插件用户指南(6)

没想到翻译这篇<Gradle 插件用户指南>拖了差不多一个月,还跨年了.不好还好,在2号时终于一口气把剩下的给翻译完了(其实那天剩下的也就不到一章). 今天先发一下第六章,明天再发第七章. 本文译自Android官方技术文档<Gradle Plugin User Guide>,原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide. 翻译不易,转载请注明CSDN博客上的出处: http://blog.c

【浅墨Unity3D Shader编程】之四 热带雨林篇: 剔除、深度测试、Alpha测试以及基本雾效合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/163.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文介绍了Unity中Shader书写中会用到的剔除.深度测试.Alpha测试以及基