http://www.xuanyusong.com/archives/2373算法
Assetbundle 是Unity Pro提供提供的功能,它能够把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供了封装与解包的方法使用起来很便利。json
1.预设数组
Assetbundle能够将Prefab封装起来,这是多么方便啊! 并且我也强烈建议你们将Prefab封装成Assetbundle,由于Prefab能够将游戏对象身上带的游戏游戏组件、游戏脚本、材质都封装在一块儿。当从服务器上将Assetbundle下载之后直接Instantiate就能够放入游戏中。服务器
试想一下,若是只能将原始的二进制资源文件放在服务器上下载,当资源文件下载完毕后,须要动态的建立游戏对象、而后动态的将脚本绑定在游戏对象、动态的将贴图赋予游戏对象等等各类动态的操做。。因此强烈建议使用Prefa,不解释!!!!!app
另外,我在举个例子,由于模型有可能会带不少动画文件,那么这样一组模型资源就多是多个FBX 文件 和 若干png贴图文件 材质文件。这时我只须要把原始模型放入Prefab中,它就会包含这个模型的全部组件、甚至包括它的动画资源、贴图。那么以下图所示,Mode就是模型的Prefab文件,那么我仅仅只须要把Mode这个预设打包成Assetbundle便可。 当我在服务器上下载这个Assetbundle而且载入游戏中就能够直接使用了,切换动画、换贴图均可以。。ide
2.二进制文件工具
也并非Assetbundle中全都要用预设,Assetbundle它也能够将二进制文件直接封装在里面,好比图片、声音、文本信息等等。优化
3.场景文件动画
在Unity中能够将一个场景保存在Scene中,Scene就会包含这个场景中的全部,那能不能把Scene也封装成Assetbundle中?答案是能,可是它不能在移动平台上用,由于移动平台上是不能更新脚本的,换句话来讲就是即便将脚本绑定在Prefab中,而后下载Assetbundle后,全部脚本是不会执行的,后面说另一种巧妙用法。google
4.移动平台
上面MOMO已经将Assetbundle 的使用原理大体介绍了一下 ,咱们在谈谈移动平台。脚本不能更新是移动平台下最大的伤,这就意味着开发者没法绕过App store和 google Play这种在线商店升级应用程序。惟一能作到的就是更新资源、举个例子,游戏中在处理版本升级时,通常会有个大版本号和一个小版本号,大版本号就是 2.0、3.0这种 版本须要在AppStore中更新,大版本主要是升级游戏脚本,而后当小版本号,好比2.0.1 或2.0.2这种只是更新游戏中的资源,经过本身游戏的服务器就能够完成,经过Assetbundle在本身服务器上下载,而后适应在游戏中。若是非要更新脚本,或不得不更新脚本那么只能在Appstore或者google Play去更新大版本。
移动平台上不能更新脚本,那么Prefab上绑定的脚本怎么办?在任何平台上均可以把脚本添加到Prefab上,而后打包成Assetbundle,只有移动平台上有点特殊,好比将Test.cs这条脚本绑定在Prefab中,最后程序经过服务器下载这个Assetbundle ,当载入工程中这条脚本是不会被执行的。
可是若是本地工程有Test.cs这条脚本,那么Unity会自动将这条脚本绑定在下载的Prefab中,而且他们执行的很是好。若是本地工程中没有Test.cs这条脚本,那么Prefab上的脚本是永远都不会执行的。有时咱们会在脚本中写一些Public的变量,有可能不一样的Prefab上绑定的是相同的脚本,只是Inspector 脚本中的public参数不一样。别担忧这一点Assetbundle 中的Prefab也是没问题,因此说只要大版本中的脚本没问题,在小版本中只更新游戏资源是一点问题都么有的。
5.移动优化
以前咱们说过能够将游戏中的某个游戏对象封装成Assetbundle,也能够将游戏中的整个场景也封装成Assetbundle。可是我认为须要巧妙的使用封装场景,由于场景中确定有不少公用的模型,若是打包场景的话那么内存与size就是 公用模型的size * N个场景,想一想其实挺恐怖的。其实咱们能够巧妙的使用,首先把场景中公用的部分和私有的部分通通放入Unity, 而后烘培整个场景。 当场景烘培完毕后把公用的模型部分在拿出去,场景只只保留私有的模型。还能够作一个工具将公用模型在场景中的坐标保存在XML中(每一个场景文件会对应一个公用模型的XML信息),最后在将公用的模型分别封装在别的Assetbundle中。
服务器上提供每一个场景的Assetbundle ,和公用模型的Assetbundle,通常公用模型的Assetbundle能够放在常驻内存中(可能使用频繁、根据项目的不一样而定)场景Assetbundle下载完毕后,现载入场景而后在根据场景对应的XML信息将公用模型部分动态的在添加到场景中,这样就完成了一个场景的构建。
6.总结
对游戏中全部资源进行打包,好比按类型分为五个大部分 界面,模型,特效,声音,场景,脚本。
界面部分:
公用资源包(可复用的资源包)和 每一个界面独有得资源包(不可复用的资源包)统一使用Prefab 打包成.assetbundle 二进制格式。
模型部分:
按角色分类,统一使用Prefab 打包成.assetbundle 二进制格式。 模型部分包括模型文件与动画文件,每个模型文件对应一组动画文件。(若是模型须要换装还需提供对应换装的模型与贴图) ,由于unity4的重定向动画不支持动态加载,因此目前不须要考虑 不一样大小 不一样规格 不一样性别 的模型重定向动画。
特效部分: 统一使用Prefab 打包成.assetbundle 二进制格式。
声音部分: 统一使用Prefab 打包成.assetbundle 二进制格式。
场景部分:场景和前面的有点区别,场景须要导出烘培的光信息而且只能烘培场景之上永远不动的模型,可是这些永远不动的模型有可能会同时在多个场景中使用,因此场景烘培完毕后要把重复使用的对象删除,(运行游戏在动态的加载进来)场景中只保留该场景中永远不会变的模型,以及烘培的光照信息。 打包场景后会生成.unity3D 二进制格式,它和 assetbundle 打包方式是不一样的。(另外,也能够考虑 json xml 二进制 来动态组装场景)。
脚本部分:若是Prefab上是带脚本打包Assetbundle的话 脚本是不会被运行的(移动平台), 可是unity有一个技巧,Prefab上的脚本 若是本地有的话它会把本地的同名脚本绑定在Prefab对象上,它会很好的执行。
Prefab打包技巧: Prefab打包时自身是不占多少空间的 <=1KB 可是Prefab上是能够关联 这五大部分 “界面,模型,特效,声音,场景,脚本”以及在Hierarchy视图中 坐标/缩放/旋转。 关联这些信息之后就会很大,因此为了不资源的浪费尽可能避免Prefab重复关联。
一个prefab下面能够同时关联多个游戏对象 ,这里举个例子若是你的 Prefab下面放了一个模型 它的大小多是500k ,在 Prefab下面放了十个彻底相同模型 它的大小多是501k 。 若是Prefab下面放了两个不一样的模型,它的大小可能就会是 500k x 2 的size ,也就是说Prefab与关联的数量是无关的 。
加密部分: assetbundle 是能够转换成 字节数组 ,客户端与服务器约定一组解密 字节数组的算法就能够实现资源加密。
大版本升级:
unity的版本升级其实主要是升级主程序中的脚本。 由于全部的资源都是assetbundle 和 .unity3d 这些资源放在本地或者服务器 解包的方式是彻底同样,因此理论上咱们的主程序包的大小能够作到很小,能够很好设置把多少资源放在包里 或者把所少资源放在服务器上。在运行的时候服务端应该把全部 assetbundle 和 .unity3d的资源文件的下载地址列表返回给客户端。
小版本升级:
小版本升级也就是更新资源,由于不能更新脚本, 在登录的时候服务端应该把全部 assetbundle 和 .unity3d的资源文件的下载地址列表返回给客户端。
还有个须要考虑的地方,好比如今大版本是2.0.0 ,小版本已是2.0.5 ,用户的手机上是一个1.5.0的包。 此时用户在打开游戏的时候 应当强制它去appstore中去下载大版本2.0.0 ,当用户下载完毕后登录游戏,此时服务器告诉客户端如今已是2.0.5的小版本了,这时候客户端去下载对应小版本的全部 assetbundle 和 .unity3d文件地址列表。
增量更新:理论上增量更新是可行的。由于unity不能更新脚本,因此在处理增量更新的话 须要在代码中作能够兼容增量更新的可能。
由于Assetbundle这块的代码比较多,我仍是决定分红两篇文章来写,这篇文章先说原理、下篇文章说代码。欢迎你们来讨论!
前几天我和Unity鑫哥聊天,他告诉我IOS上是没法运行时更新脚本、可是Android上是能够运行时更新脚本,我回家也试了一下可是没能成功,后来我考虑即便成功了项目中我也不打算那么作,由于这样Android和IOS 作起来的差异就太多了, 另外Unity商店中有一个处理运行时更新脚本的插件 unityLua 你们能够去研究研究。
转载请注明: 雨松MOMO
2013年06月17日于 雨松MOMO程序研究院 发表