unityunity5.x assetbundlee怎么破解

unity3d游戏开发中加密及解密的方法讲解
unity3d游戏开发中加密及解密的方法讲解
浏览次数:2056
浏览次数:170
浏览次数:778
浏览次数:1026
浏览次数:1115
如果你对以下课程意犹未尽,,查看全部课程
HTML5全栈开发
HTML5最新课程
156 人在学
c#编程概述
C#快速入门
简单又好玩
120 人在学
没有账号?
s后重新发送
已有账号?
已有账号?
验证码确认
话题标题:
400-877-8190
登录后反馈Unity3d资源解决方案之AssetBundle
Unity3d资源解决方案之AssetBundle
1、什么是AssetBundleAssetBundle是Unitypro提供的一种用来存储资源的文件格式,它可以存储任意一种Unity引擎能够识别的资源,如Scene、Mesh、Material、Texture、Audio、noxss等等,同时,AssetBundle也可以包含开发者自定义的二进制文件,只需要将自定义文件的扩展名改为.bytes,Unity就可以把它识别为TextAsset,进而就可以被打包到AssetBundle中。Unity引擎所能识别的资源我们称为Asset,AssetBundle就是Asset的一个集合。AssetBundle的特点:压缩(缺省)、动态载入、本地缓存;2、AssetBundle VS ResourceAssetBundle作为Unity官方推崇的资源更新方案,与传统的Resource差异如下:a、Resource放在Resources目录下,resources.assets文件,单个文件有2GB限制,首次必须全部下载;b、AssetBundle创建需要通过Editor脚本创建,支持动态下载,是Unity Web Caching License唯一可以缓存的内容;3、AssetBundle的适用平台与跨平台性AssetBundle适用于多种平台,包括网页应用、移动应用、桌面应用等,可以动态更新,但不同平台所使用的AssetBundle并不相同,在创建离线AssetBundle的时候需要通过参数来指定目标平台,相容关系如表所示:4、AssetBundle的工作流程(与flash加载swf类似)a、创建AssetBundle;b、上传到Server;c、游戏运行时根据需要下载(或者从本地cache中加载)AssetBundle文件;d、解析加载Assets;e、使用完毕后释放;5、创建AssetBundle5.1、如何创建AssetBundleUnity引擎提供了创建AssetBundle的API,通过编译管线BuildPipeline来创建AssetBundle文件,总共有三种方法:a、BuildPipeline.BuildAssetBundle(mainAsset : Object, assets : Object[],pathName : string, options : BuildAssetBundleOptions =BuildAssetBundleOptions.CollectDependencies |<pleteAssets, targetPlatform : BuildTarget =BuildTarget.WebPlayer) : bool该API将编辑器中的任意类型的Assets打包成一个AssetBundle,适用于对单个大规模场景的细分;b、BuildPipeline.BuildStreamedSceneAssetBundle(level : string[], locationPath : string, target : BuildTarget) : String该API将一个或多个场景中的资源及其所有依赖以流加载的方式打包成AssetBundle,一般适用于多单个或多个场景进行集中打包;c、BuildPipeline.BuildAssetBundleExplicitAssetNames(assets : Object[],assetNames : string[],pathName : string, options :BuildAssetBundleOptions = BuildAssetBundleOptions.CollectDependencies |<pleteAssets, targetPlatform : BuildTarget =BuildTarget.WebPlayer) : bool该API功能与a相同,但创建的时候可以为每个Object指定一个自定义的名字。(一般不太常用)5.2、关于BuildAssetBundleOptionsa、CompleteAssets使每个Asset自身完备,包含所有的Components;b、CollectDependencies包含每个Asset依赖的所有其他Asset;c、DisableWriteTypeTree在AssetBundle中不包含类型信息。需要注意的是,如果将AssetBundle发布到web平台上,则不能使用这个选项;d、DeterministricAssetBundle使每个Object具有唯一的、不变的HashID,便于后续查找可以用于增量发布AssetBundle;e、UncompressedAssetBundle不进行数据压缩。如果使用这个选项,因为没有压缩/解压的过程,AssetBundle发布和加载会更快,但是AssetBundle也会更大,导致下载变慢。5.3、AssetBundle之间的依赖如果游戏中的某个资源被多个资源引用(例如游戏中的Material),单独创建AssetBundle会使多个AssetBundle都包含被引用的资源(这里跟flash编译选项中的链接选项有些像),从而导致资源变大,这里可以通过指定AssetBundle之间的依赖关系来减少最终AssetBundle文件的大小(把AssetBundle解耦)。具体方法是在创建AssetBundle之前调用BuildPipeline.PushAssetDependencies和BuildPipeline.PopAssetDependencies来创建AssetBundle之间的依赖关系,它的用法就是一个栈,后压入栈中的元素依赖栈内的元素。(记得要pop!)举个例子:现在游戏内有mat1和mat2两个Material,他们使用了相同的Texture zhuanqiang不使用依赖使用依赖6、远端Server的AssetBundle下载Unity引擎提供了两种方式从服务器下载AssetBundle文件,分别是缓存机制和非缓存机制。6.1、缓存机制通过WWW.LoadFromCacheOrDownload (url : string, version : int)接口来下载AssetBundle,下载后的AssetBundle会自动被保存到Unity引擎的缓存区内,该方法是Unity推荐的AssetBundle下载方式。下载AssetBundle的时候,该接口会先在本地缓存中查找该文件,看其之前是否被下载过,如果下载过,则直接从缓存中加载,如果没有,则从服务器尽享下载。这样做的好处是可以节省AssetBundle文件的下载时间,从而提高游戏资源的载入速度(还可以节省下载流量)。同时开启多个Coroutine进行WWW的LoadFromCacheOrDownload操作(缓存中),经测试开启的WWW现成越多,速度会越快,但是需要考虑时机的机器火平台的承载能力。如果一定要从网上下载资源的话,线程数最好设为5个(别人的经验),很多平台也有自己的限制,例如有的浏览器只能同事加载6个等等。需要注意的是,Unity提供的默认缓存大小是根据发布平台不同而不同的(可以向Unity购买Caching license支持)。目前对于web player的网页游戏,默认缓存大小为50M;对于PC上的客户端或者?上的移动游戏,默认缓存大小为4GB。代码:WWW www = WWW.LoadFromCacheOrDownload (Url, 1);AssetBundle ab = www.assetB6.2、非缓存机制通过创建一个WWW实例来对AssetBundle文件下载,下载后的AssetBundle文件将不会进入Unity的缓存区。使用这种方法每次都会从远端服务器下载。代码:WWW www = new WWW(Url);AssetBundle ab =www.assetB7、载入AssetBundle对象7.1、通过WWW类方法和属性直接通过WWW.assetBundle属性来创建AssetBundle,注意:通过WWW加载的AssetBundle在解析Asset之前一定要先调用WWW.assetB7.2、通过API动态创建AssetBundle.CreateFromFile接口从磁盘创建一个AssetBundle文件的内存对象,该方法仅支持非压缩格式的AssetBundle。7.3通过API动态创建AssetBundle.CreateFromMemory接口可以从内存数据流创建一个AssetBundle内存对象。主要用于对数据的加解密上。例如:WWW www = new WWW(url);byte[] encrypedData =www.byte[] decryptedData = YourDecryptionMethod(encrypedData);//解密函数AssetBundle ab = AssetBundle.CreateFromMemory(decrypedData);8、从AssetBundle中加载Assets8.1、Assets的加载AssetBundle.Load (name : string) : Object 从bundle中加载名为name的对象;AssetBundle.Load (name : string, type : Type) : Object 从bundle中加载被指定类型的名为name的对象;AssetBundle.LoadAsync (name : string, type : Type) : AssetBundleRequest 异步地从bundle中加载被指定类型的名为name的对象(异步加载需要Unity Pro专业版);AssetBundle.LoadAll (type : Type) : Object[] 加载所有包含在asset bundle中且继承自type的对象;AssetBundle.LoadAll () : Object[] 加载所有包含在asset bundle中的对象;AssetBundle.mainAsset主资源在构建资源boundle时指定(只读),该功能可以方便的找到bundle内的主资源。例如,你也许想有一个角色的预制体并包括所有纹理、材质、网格和动画文件。但是完全操纵角色的预设体应该是你的mainAsset并且易于被访问;例如://开始下载WWW www = new WWW(url);//等待下载完成//获取指定的主资源并实例化Instantiate();8.2、AssetBundle中加载LevelApplication.LoadLevel 该接口可以通过名字或者索引载入AssetBundle文件中包含的对应场景,当夹在新场景时,所有之前加载的GameObject都会被销毁;Application.LoadLevelAsync 该接口的作用与Application.LoadLevel相同,不同的是该接口是异步加载,即加载时主线程可以继续执行;Application.LoadLevelAdditive 该接口不同与Application.LoadLevel的是并不销毁之前加载的GameObject;Application.LoadLevelAdditiveAsync 该接口的作用与Application.LoadLevelAdditive相同,不同的是该接口是异步加载,即加载时主线程可以继续执行;例如:WWW www = new WWW(url);AssetBundle ab =www.assetBApplication.loadLevel("Level1");9、AssetBundle与内存内存一直都是开发者关注的一个重点,如果要了解清楚内存的使用情况。9.1、加载AssetBundle对内存的影响Unity引擎在使用WWW方法时会分配一系列的内存空间来存放WWW实例对象、WebStream数据。该数据包括原始的AssetBundle数据、解压后的AssetBundle数据以及一个用于解压的Decompression Buffer。一般情况下,DecompressionBuffer会在原始的AssetBundle解压完成后自动销毁,但需要注意的是,Unity会自动保留一个DecompressionBuffer,不被系统回收,这样做的好处是不用过于频繁的开辟和销毁解压Buffer,从而在一定程度上降低CPU的消耗。当把AssetBundle解压到内存后,开发者可以使用WWW.assetBundle属性来获取AssetBundle对象,从而可以得到各种Assets,进而对这些Assets进行加载或者实例化操作。加载过程中,Unity会将AssetBundle中的数据流转变为引擎可以识别的信息类型(纹理、材质、对象等)。加载完成后,开发者可以对其进行进一步的操作,比如对象的实例化、纹理和材质的复制和替换等。9.2、AssetBundle的卸载1)AssetBundle.Unload(true) 该接口会强制卸载掉所有AssetBundle中加载的Asset,包括AssetBundle的映射结构、自身对Web Stream的引用以及从AssetBundle创建出来的所有资源,该接口不推荐使用。2)AssetBundle.Unload(false) 该接口会释放AssetBundle内的序列化数据,但是任何从这个AssetBundle中实例化的物体都将完好。当然,你不能从这个AssetBundle中加载更多物体。Resources.UnloadUnusedAssets该接口会卸载掉没有使用的Assets,作用范围是整个系统。3)对于实例化出来的GameObject,可以调用GameObject.Destory()接口来卸载。该接口会延后到一个合理的时机进行处理。注意:这是没有处理好的一个环节。在WWW加载资源完毕后,对资源进行instantiate后,对其资源进行unload,这时问题就发生了,instantiate处理渲染需要一定的时间,虽然很短,但也是需要1,2帧的时间。此时进行unload会对资源渲染造成影响,以至于没有贴图或 者等等问题发生。解决办法:自己写个时间等待代码,等待个0.5秒到1秒之后再进行Unload。这样就不会出现instantiate渲染中就运行unload的情况了。10、关于其他10.1、在AssetBundle中嵌入脚本AssetBundle中的资源上如果Attach了脚本,打包的时候该脚本是不会被打到AssetBundle中的,其实这里只是保存了一个类似于指针的关联,如果需要把脚本也动态打到AssetBundle中,还需要做一番工作。首先,将脚本预先编译成assembly,把assembly保存成.bytes文件,这样Unity会把它识别为TextAsset,就可以将这个TextAsset打包到AssetBundle中了,载入后可以通过反射机制使用该脚本,代码如下:AssetBundle bundle = WWWW.assetBTextAsset txt = bundle.load("MyBinaryAsText", typeof(TextAsset)) as TextAbyte[] bytes = txt.var assembly = System.Reflection.Assembly.Load(bytes);需要注意的是,IOS平台不支持动态载入脚本。10.2、AssetBundle的版本控制AssetBundle使用WWW.LoadFromCacheOrDownload(string url, int version, uintcrc)加载,其中的第二个参数-version可以用来做版本控制,该参数强制用户从服务器下载一个更高版本的AssetBundle。我们可以通过第三个参数crc来实现AssetBundle的内容校验,当crc不为0的时候,Unity会校验AssetBundle的CRC码,如果不等,则说明文件损坏,Unity会重新下载该文件。对于crc的获取,(老版本没有提供方法,只能通过LoadFromCacheOrDownload传一个错误的crc,从log中获取),新版本在BuildAssetBundle的时候增加了一个out类型的参数,该参数会返回正确的crc码,打包的时候可以记录下来以供后面使用。10.3、关于Editor和Runtime之间共享资源1)Unity提供了一种可以公用的类——noxssableObject,适用于描述动态划分场景;通过代码划分场景——&打包多个AssetBundle——&将划分信息记录在ScriptableObject中,并保存至Asset——&载入时先载入划分信息,再根据这个划分信息载入AssetBundle。2)使用XML文件。10.4、关于编辑器扩展可以通过事件触发来执行你的编辑器代码,但是我们需要一些编译器参数来告知编译器何时需要触发该段代码。 [MenuItem(XXX)]声明在一个函数上方,告知编译器给Unity3D编辑器添加一个菜单项,并且当点击该菜单项的时候调用该函数。触发函数里可以编写任何合法的代码,可以是一个资源批处理程序,也可以弹出一个编辑器窗口。代码里可以访问到当前选中的内容(通过Selection类),并据此来确定显示视图。与此类似,[ContextMenu("XXX")]可以向你的上下文菜单中添加一个菜单项。 当你编写了一些Component脚本,当它被附属到某个GameObject时,想在编辑视图即可在Scene视图观察到效果,那么你可以把[ExecuteInEditMode]写在类上方来通知编译器,该类的OnGUI和Update等函数在编辑模式也也会被调用。我们还可以使用[AddComponentMenu("XXX/XXX")]来把该脚本关联到Component菜单中,点击相应菜单项即可为GameObject添加该Component脚本。为了避免不必要的包含,Unity3D的运行时和编辑器类分辨存储在不同的Assemblies里(UnityEngine和UnityEditor)。Editor目录下的脚本会在其它脚本之后进行编译,这方便了你去使用那些运行时的内容。而那些目录下的脚本是不能访问到Editor目录下的内容的。所以,你最好把你的编辑器脚本写在Editor目录下。10.5、关于差量发布在5.2中介绍了创建AssetBundle的参数,其中的d选项在选中的时候可以使相同的内容两次发布出来的文件是完全一样的,我们在创建AssetBundle的时候选择上这个参数,那么就可以做差量了。测试数据如下:没有选择该参数:选择了该参数后:10.6、关于项目中应用项目中使用AssetBundle做开发可以使用宏进行隔离,接口封装尽量采用异步接口,通过引用计数cache机制,确定ab的释放时机。大体流程如下:a、确定加载ab次数(资源数)b、加载abc、成功后根据资源url引用计数减去对应资源数d、引用计数为0的时候调用AssetBundle的Unload(false)代码中使用的地方可以通过封装的GetObject获取已经加载的对象,使用完成后可以调用Resources的UnloadUnUsedAssets释放资源。10.7、关于AssetBundle的粒度控制AB的粒度越小,差量更新的冗余就会越小,粒度越大,差量更新的冗余就会越大。但是,并不是说粒度越小就越好,粒度小了,(运行时)加载的时候会增加IO次数、解压次数(AB一般选择压缩格式)和申请内存的次数,导致加载时长变长。因此粒度的控制是一个时间与空间平衡的选择过程。经过实验,大体有一个数据可以用来参考,1M左右的AssetBundle包加载性能最好,冗余也可以接受。10.8、关于AssetBundle的压缩选择AssetBundle压缩与不压缩的差异主要有两方面:a、外存(安装包的大小或者安装后占用磁盘空间的大小)b、加载方式的选择(能否使用同步方法)这里如果一些对性能要求特别高,资源又不大的AB可以采用非压缩方式,通过CreateFromFile加载AB包,性能最高又不会产生大量的内存。对于其他的资源文件,建议压缩处理,压缩与非压缩在磁盘占用上会有4倍左右的大小差别,如果都采用非压缩格式,有可能会导致你的磁盘占用达到一个非常恐怖的量级。10.9、AssetBundle在外存优化中的应用安装后的磁盘构成基本上是资源的内存值(Resources目录下资源),举个粒子,一张真彩色的的图片放到Resources目录下安装后占用的内存为4M(4*)。如果你的游戏是一个2D的,又包含很多的图片资源,这样会使你的安装包在用户机器上安装需要大量的磁盘空间,这里你可以把它们打成AB包放到用户的手机上,这样就磁盘占用就会小很多了。
狗狗,被黑了客户端资源更新AssetBundle打包详解(资源冗余和AssetBundle颗粒大小)
Unity在做资源更新时肯定少不了AssetBundle,AssetBundle有太多太多的坑,需要自己慢慢踩,在这我给大家分享下AssetBundle打包时资源冗余和AssetBundle颗粒大小的权衡方面的内容,希望遇到同样问题的同学们顶起来,把你们的想法和问题发出来大家一起来讨论,我会将最新的内容试试更新上来
726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('/forum/attachment/1510/thread/7_ef1bcde5f693.png');" />
关于这方面不错的一些博文
本部分内容设定了隐藏,需要回复后才能看到
要评论请先&或者&
Thank you for shared!
看看。。。。
看看......
seeeeeeeeeeeeeeeeeeeeedddddddddddddddd
Thank you for shared!
感谢分享~~~~~~~~~
嗯,好资源,感谢分享在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
标签:至少1个,最多5个
最近给项目改造AssetBundle系统,又重新摸起了AssetBundle这块儿。。因为现在使用4.x版本的情况已经越来越少,而在5里面unity3d已经原生支持了依赖分析增量构建等重量级功能,所以我就不再浪费篇幅去讲系统设计相关的话题。我花了一些时间做了一些小实验,可以明确一些unity3d在AssetBundle上的处理细节。希望看到这篇文章的人能够从中获取一些营养。
问:当使用WWW加载AssetBundle时,WWW.Dispose()和AssetBundle.Unload(false)两个释放操作分别会如何影响内存?答:单独调用WWW.Dispose会释放掉一部分内存(并不知道是什么内存,猜测是和网络相关的部分);单独调用AssetBundle.Unload不会带来任何内存变化;同时调用这两个接口可以完全释放内存。
实验过程:打包9个AssetBundle,每个Bundle中有一张的RGBA32格式纹理(16MB)。使用Profiler和任务管理器观察内存变化。
问:重复从同一个AssetBundle中加载资源,会带来怎样的内存变化?答:只会在CPU端占用一份内存,但在GPU部分,每次加载都会额外占用一份内存。
实验过程:打包一张的RGBA32格式纹理(16MB)为AssetBundle。反复进行"加载,取得ResourceObject,卸载Bundle"的操作,使用Profiler观察内存变化。其中,来自Unity的16MB增长是什么呢?从Profiler Detailed里可以看到具体项目。一个叫做GfxClientDevice的项目从8.0MB提升到了24.0MB。至于这个GfxClientDevice项目到底是什么呢? 我日后再调查补充。。。。
问:如果我打包Bundle和运行并不在一个AssetBundle中,可以正确的加载资源吗?答:可以。
问:如果我把Shader随着Bundle一起打包出来,而运行的工程并没有这个Shader,那么Shader可以正常运作吗?答:可以。
问:如果两个Bundle都包含同样的资源(未处理共享依赖),加载Bundle的时候unity3d如何处理引用?答:会各自加载自己包里的资源。
问:在两次不相干的打包过程中,依赖是否可以有效的保持。答:如果使用Deterministic参数,则可以保持。反之则不能,需要重新打包所有相关Bundle。
实验过程: 有资源A,B,C,其中资源B和资源C都依赖于A。每个资源打一个Bundle。
不开启Deterministic。先带依赖打包A和B,不包含C。然后重新带依赖打包A和C,不包含B。在运行时B会丢失对A的引用。
开启Deterministic。同上流程,在运行时B依然可以保持对A的引用。
0 收藏&&|&&1
你可能感兴趣的文章
2 收藏,1.7k
2 收藏,1.1k
1 收藏,1.9k
分享到微博?
我要该,理由是:当前位置: >
Unity游戏开发使用Assetbundle加载场景实战
时间: 12:04 来源:互联网 作者:网络 浏览:
之前有一篇文章中我们相惜讨论了Assetbundle的原理,如果对原理还不太了解的朋友可以看这一篇文章:&本篇文章我们将说说assetbundle是如何实现的。1.创建Assetbundle&&&&&&&& 无论是模型资源还是UI资源,最好是先把他们放在Prefab中,然后在做成Assetbundle。我们以模型来举例,Assetbundle中可以放一个模型、也可以放多个模型,它是非常灵活了那么最需要考虑的就是模型空间占用的问题。比如我们有两个完全一样的模型,但是他们身上绑定的脚本不一样,此时需要把这两个模型放在两个不同Prefab中。如下图所示,我们分别对这两个Prefab打包,我们可以清晰的看到两个相同的Prefab打包在一起只占1M空间,而将他们分别打包会占1 + 1 = 2M空间。 Prefab在打包的同时会把模型身上的所有材质、贴图、组件、脚本全部包含进去。由此可得相同的模型尽量打包在一起,他们会公用一套资源文件。不相同的模型尽量分开打包,相同模型具有不同的脚本、组件的话把他们放在不同的Prefab中,最后把这些Prefab一起打包在一个Assetbundle中。如下图所示,现在Project视图中选择需要打包的Prefab,然后在导航菜单栏中选择Create Assetbundles Main表示分别打包、Create AssetBundles All表示将他们打包在一起。这两个prefab文件都指向了同一个模型,为了让它俩有所区别,我给它俩绑定了相同的脚本,但是脚本中的参数是不同的。在编辑器上给每个Prefab赋值一个不同的名子,然后在Awake方法中进行输出。using&UnityE
using&System.C
public&class&Script&:&MonoBehaviour
public&string&
void&Awake&()
Debug.Log(&my&name&is&&+&name);
}Create Assetbundles Main : 分开打包,会生成两个Assetbundle。&&&&[MenuItem(&Custom&Editor/Create&AssetBunldes&Main&)]
static&void&CreateAssetBunldesMain&()
&&&&&&&&//获取在Project视图中选择的所有游戏对象
Object[]&SelectedAsset&=&Selection.GetFiltered&(typeof(Object),&SelectionMode.DeepAssets);
&&&&&&&&//遍历所有的游戏对象
foreach&(Object&obj&in&SelectedAsset)
string&sourcePath&=&AssetDatabase.GetAssetPath&(obj);
//本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径
//StreamingAssets是只读路径,不能写入
//服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。
string&targetPath&=&Application.dataPath&+&&/StreamingAssets/&&+&obj.name&+&&.assetbundle&;
if&(BuildPipeline.BuildAssetBundle&(obj,&null,&targetPath,&BuildAssetBundleOptions.CollectDependencies))&{
&&&Debug.Log(obj.name&+&资源打包成功&);
Debug.Log(obj.name&+&资源打包失败&);
//刷新编辑器
AssetDatabase.Refresh&();&&&&
}最核心的方法其实就它:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)参数1:它只能放一个对象,因为我们这里是分别打包,所以通过循环将每个对象分别放在了这里。参数2:可以放入一个数组对象。默认情况下打的包只能在电脑上用,如果要在手机上用就要添加一个参数。Android上:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.Android)IOS上:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone)另外,电脑上和手机上打出来的Assetbundle不能混用,不同平台只能用自己的。&Create AssetBundles All:将所有对象打包在一个Assetbundle中。&&&&[MenuItem(&Custom&Editor/Create&AssetBunldes&ALL&)]
static&void&CreateAssetBunldesALL&()
Caching.CleanCache&();
string&Path&=&Application.dataPath&+&&/StreamingAssets/ALL.assetbundle&;
Object[]&SelectedAsset&=&Selection.GetFiltered&(typeof(Object),&SelectionMode.DeepAssets);
foreach&(Object&obj&in&SelectedAsset)
Debug.Log&(&Create&AssetBunldes&name&:&&+&obj);
//这里注意第二个参数就行
if&(BuildPipeline.BuildAssetBundle&(null,&SelectedAsset,&Path,&BuildAssetBundleOptions.CollectDependencies))&{
AssetDatabase.Refresh&();
}两次打包完毕后,在StreamingAssets文件夹中就看到了这三个assetbundle文件。2.读取Assetbundle &&&&&& 然后我们来学习如何运行时读取Assetbundle,Assetbundle是可以同时放在服务器或者本地的,无论放在哪里两种下载读取的方式是完全一样的。所以我建议在做unity项目的时候开始就把资源放在Assetbundle中在本地来做,等做的差不多了直接把Assetbundle放在服务器上,因为两种读取的方式完全一样,这样以后更新资源会方便很多。然后是读取,并且加载到游戏中。using&UnityE
using&System.C
public&class&RunScript&:&MonoBehaviour
&&&&//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。
&&&&public&static&readonly&string&PathURL&=
#if&UNITY_ANDROID
&jar:file://&&+&Application.dataPath&+&&!/assets/&;
#elif&UNITY_IPHONE
Application.dataPath&+&&/Raw/&;
#elif&UNITY_STANDALONE_WIN&||&UNITY_EDITOR
&file://&&+&Application.dataPath&+&&/StreamingAssets/&;
&&&&&&&&string.E
void&OnGUI()
if(GUILayout.Button(&Main&Assetbundle&))
StartCoroutine(LoadMainGameObject(PathURL&+&&Prefab0.assetbundle&));
StartCoroutine(LoadMainGameObject(PathURL&+&&&Prefab1.assetbundle&));
if(GUILayout.Button(&ALL&Assetbundle&))
StartCoroutine(LoadALLGameObject(PathURL&+&&ALL.assetbundle&));
//读取一个资源
private&IEnumerator&LoadMainGameObject(string&path)
WWW&bundle&=&new&WWW(path);
yield&return&
//加载到游戏中
yield&return&Instantiate(bundle.assetBundle.mainAsset);
bundle.assetBundle.Unload(false);
//读取全部资源
private&IEnumerator&LoadALLGameObject(string&path)
WWW&bundle&=&new&WWW(path);
yield&return&
//通过Prefab的名称把他们都读取出来
Object&&obj0&=&&bundle.assetBundle.Load(&Prefab0&);
Object&&obj1&=&&bundle.assetBundle.Load(&Prefab1&);
//加载到游戏中
yield&return&Instantiate(obj0);
yield&return&Instantiate(obj1);
bundle.assetBundle.Unload(false);
}这里我们详细的说说 下载类WWWWWW bundle = new WWW(path);这样的做法是通过一个路径进行下载(无论是服务器路径还是本地路径下载操作都一样)但是bundle只能保存在内存中,也就是退出游戏在进入还得重新下,很显然在游戏中我们不能使用这种方式。&&&&private&IEnumerator&LoadMainCacheGameObject(string&path)
WWW&bundle&=&WWW.LoadFromCacheOrDownload(path,5);
yield&return&
//加载到游戏中
yield&return&Instantiate(bundle.assetBundle.mainAsset);
bundle.assetBundle.Unload(false);
}使用的方法是WWW.LoadFromCacheOrDownload(path,5);参数1:服务器或者本地下载地址参数2:版本号&&&&&&&& Unity会下载Assetbundle本地中,它的工作原理是先通过(版本号和下载地址)先在本地去找看有没有这个Assetbundle,如果有直接返回对象,如果没有的话,在根据这个下载地址重新从服务器或者本地下载。这里版本号起到了很重要的作用,举个例子,同一下载地址版本号为1的时候已经下载到本地,此时将版本号的参数改成2 那么它又会重新下载,如果还保持版本号为1那么它会从本地读取,因为本地已经有版本号为1的这个Assetbundle了。你不用担心你的资源本地下载过多,也不用自己手动删除他们,这一切的一切Unity会帮我们自动完成,它会自动删除掉下载后最不常用的Assetbundle ,如果下次需要使用的话只要提供下载地址和版本后它会重新下载。&&&&&&& 我们在聊聊Assetbundle 中的脚本,在移动平台下Assetbundle里面放的脚本是不会被执行的,还记得我们打包前给两个Prefab挂上了脚本吗?在手机上将Assetbundle下载到本地后,加载进游戏中Prefab会自动在本地找它身上挂着的脚本,他是根据脚本的名来寻找,如果本地有这条脚本的话,Prefab会把这个脚本重新绑定在自身,并且会把打包前的参数传递进来。如果本地没有,身上挂的条脚本永远都不会被执行。&&&&& 在Prefab打包前,我在编辑器上给脚本中的变量 name 赋了不同值,当Prefab重新载入游戏的时候,它身上脚本的参数也会重新输出。如果你的Assetbundle中的Prefab上引用的对象,那么这样做就会出错了,你需要设定他们的依赖关系。或者运行时通过脚本动态的载入对象。&/Documentation/ScriptReference/BuildPipeline.PopAssetDependencies.html&/Documentation/ScriptReference/BuildPipeline.PushAssetDependencies.html像这样重新打包就可以。&3.打包场景&&&& 上面我们说过了打包Prefab,其实我们还可以把整个场景进行打包,因为移动平台不能更新脚本,所以这个功能就会有所限制,我的建议是烘培场景、然后把多个场景可复用的对象移除,场景中只保留独一无二的游戏对象,然后在打包场景,运行游戏时载入场景后,在动态的将之前移除的对象重新添加进来。&&&&[MenuItem(&Custom&Editor/Create&Scene&)]
static&void&CreateSceneALL&()
//清空一下缓存
Caching.CleanCache();
string&Path&=&Application.dataPath&+&&/MyScene.unity3d&;
string&&[]levels&=&{&Assets/Level.unity&};
&&&&&//打包场景
&&&&&BuildPipeline.BuildPlayer(&levels,&Path,BuildTarget.WebPlayer,&BuildOptions.BuildAdditionalStreamedScenes);
AssetDatabase.Refresh&();
}不同平台下需要选择& BuildTarget.Android 和 BuildTarget.iPhone 。 切记这段代码是把Level.unity常见文件打包到MyScene.unity3d文件中,所以在解包的时候也应当是先解开MyScene.unity3d,然后在去加载Level.unity场景,无需在ProjectSetting中注册新场景。&&&&private&IEnumerator&LoadScene()
WWW&download&=&WWW.LoadFromCacheOrDownload&(&file://&+Application.dataPath&+&&/MyScene.unity3d&,&1);
&&yield&return&
&&var&bundle&=&download.assetB
&&&&&Application.LoadLevel&(&Level&);
}&在测试情况下你可能会频繁的打包生成Assetbundle,如果忘记改版本号的话可能会读取之前的缓存,可能就会看不到新的效果,所以我建议在bunild Assetbundle的时候强制清空一下缓存。Caching.CleanCache();最后点击按钮进行加载Assetbundle和 Scene吧。最后是下载地址:欢迎大家一起学习,欢迎给我留言、欢迎一起讨论,祝大家学习愉快 啦啦啦啦。
(责任编辑:脚印)
免责声明:Unity之家部分内容来源于互联网,如有侵权,请联系我们,本站将立即进行处理。
猜你也喜欢看这些 ??????
其他类型的Unity入门 ??????

我要回帖

更多关于 unity3d assetbundle 的文章

 

随机推荐