AssetBundle 点滴

基本介绍:
什么是? 一个assets的集合,打包以用来在运行时加载
在应用中动态的 加载和卸载 新内容。 比如说DLC(downloadable content)

用处?

降低磁盘空间的消耗(第一次发布时) + 热更新资源

AssetBundle 使用LZMA进行压缩,并且相似的Prefabs在打包时能够大大减少空间占用。

创建AssetBundle,使用Editor代码,可以参考官方的manual:

 1 public class ExportAssetBundles
 2 {
 3     [MenuItem("Custom/Build AssetBundle From Selection - Track dependencies")]
 4     public static void ExportResource()
 5     {
 6         string path = EditorUtility.SaveFilePanel("Save Resource","","New Resource","unity3d");
 7         if(path.Length != 0)
 8         {
 9             Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
10             BuildPipeline.BuildAssetBundle(Selection.activeObject,selection,path,
11                 BuildAssetBundleOptions.CollectDependencies|BuildAssetBundleOptions.CompleteAssets);
12             Selection.objects = selection;
13         }
14     }
15
16     [MenuItem("Custom/Build AssetBundle From Selection - No dependency tracking")]
17     public static void ExportResourceNoTrack()
18     {
19         string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
20         if(path.Length != 0)
21         {
22
23             //BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path);
24             BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path);
25         }
26
27     }
28
29 }

下载:

 1 public class LoadAssetBundle : MonoBehaviour
 2 {
 3     public Object obj;
 4
 5     /// <summary>
 6     ///
 7     /// </summary>
 8     /// <typeparam name="T"></typeparam>
 9     /// <param name="asset">bundle的名字</param>
10     /// <param name="url"></param>
11     /// <param name="version"></param>
12     /// <returns></returns>
13     public IEnumerator DownloadAssetBundle<T>(string asset,string url,int version) where T: Object
14     {
15         obj = null;
16 #if UNITY_EDITOR
17
18         //prefab = Resources.LoadAssetAtPath("Assets/Artwork/mymodel.fbx", typeof(GameObject));
19         obj = Resources.LoadAssetAtPath("Assets/" + asset, typeof(T));
20         yield return null;
21 #else
22         while (!Caching.ready)
23             yield return null;
24         using(WWW www = WWW.LoadFromCacheOrDownload(url,version))
25         {
26             if (www.error != null)
27             {
28                 Debug.LogError("WWW download has an error "+www.error );
29             }
30             else
31             {
32                 AssetBundle bundle = www.assetBundle;
33                 obj = bundle.Load(asset, typeof(T));
34                 bundle.Unload(false);
35             }
36         }
37 #endif
38     }
39
40     

最好使用上述方式,但使用new WWW(url) 也是可以的。

上述代码中:Resources.loadAsssetAtPath 避免了重新打包assetbundel,这个函数的用处是 使你想load一个assetbundle一样laod它,它会跳过打包的过程来保证asset始终是最新的(简化操作)

.mainAsset 当制作assetbundle的时候的传递的第一个参数。
用处: 存储一个 textAsset 用来表示所有这个assetbundle中的objects信息。

使用注意:

url 使用本地 之前加 file://

从AssetBundle中加载出来的prefab上的脚本是会执行的,只要本地有这个脚本,不然会出现警告:“The referenced script on this Behaviour is missing!” ,脚本不会执行。

如果想要动态的加载脚本,只能通过编译成dll,然后改为.bytes,再反射加载,再add component。这也是官方推荐的Android下热更新脚本的一种方式。

LodaAll 的问题:

首先,对于所有的load,必须要指定type,不然可能由于重名而出现莫名其妙的错误。具体原因可以参见这篇文章的相关介绍:http://www.cnblogs.com/ybgame/p/3973177.html?utm_source=tuicool
常见错误:
Object[] objects = bundle.LoadAll();///
Foreach(Object obj in Objects)
{
  Instantiate(obj);
}
注意: 每个prefab 会出来 4个clone;

如果是用 Object[] objects = bundle.LoadAll(Typeof(GameObject));
则: 出来2个clone;
原因:prefab 中包含了 model 的meshfilter。即prefab是包含model的。
解决方法:不是将prefab打包,而是仅仅将model打包。这样就只有一个。

但是如果需要的不仅仅是模型,还要通过加入其他组件,那么就只能采用 名字 来做了

bundle.Load(“name”,typepf(Gameobject));
再instantiate 则是一个。
//使用名字能够保证始终是一个。

考虑第一个AssetBundle的第一个 也就是 mainAsset 保存名字。然后再一一实例化。

另一种:

也可以将这一步放在加载的时候,先加载TextAsset,然后获得名字。
AssetBundle bundle = www.assetBundle;
//textAsset 名称为Names
TextAsset file = bundle.Load("Names", typeof(TextAsset)) as TextAsset;
string content = file.text;
string[] names = content.Split(‘,‘);
foreach( string name in names)
{
Instantiate(bundle.Load(name, typeof(GameObject)));
}

关于打包的思路:

尽量把具有相同模型不同脚本的物体做成不同的prefab,然后打包在一起,可以较少空间占用。最后可以直接加载使用。
将大部分 在scene中出现的    存成  prefab。

然后 有些 prefab 只是脚本或者位置 或者其他不一样 ,那么这些放在一起打包 ,大大减小包的大小。

完全不关联的东西放  分开 打包。

基础UI可以打成一个包,重复使用

另外基础的场景背景 或者 公用背景 可以打在一起 ,每个场景不同的可以分开。

场景加载中使用Assetbundle的一些思路:

每次加载对应的场景的时候,需要场景对应的
AssetBundle url,每个 AssetBundle 中要加载哪些东西,这会对应着一个文件。然后去构建场景。
类似于MOMO的将场景保存为XML或者Json 文件。http://www.xuanyusong.com/archives/1919

大部分的场景都是基于同一个场景衍生的,所以可以做一个base场景,然后修改后save as

有效率的打包AssetBundle。
随着项目的增大,手动打包很繁杂,所以考虑程序去将项目中的所有需要打包的全部打包。
比如说 可以有一个 txt文件来map Asset –>Assetbundle。

由于WWW.LoadfromCacheOrDownload
是一个异步的过程,
解决方案:
1: 先优先加载 主角 或者 需要优先显示的部分,
再加载其他部分
2: 使用同步加载,AssetBundle.CreatFromFile
要求打包的时候不压缩,所以自己使用LZMA压缩,解压。
AssetBundle下载下来 并且 保存在 本地路径(比如说application.persistantDataPath),再使用AssetBundle.CreatFromFile 。

一个场景的完整的加载过程可能如下:
场景构成:
一个start脚本;
1:读取配置文件
2:加载公有的assetbundle
3:加载私有的assetbundle

具体还要看不同的情况。需要调节加载的顺序,因为会有相互的依赖性,不然可能会出现错误。

配置文件的示例:
Scene1.bytes:
公用bundle 路径(可以是相对的),公用bundle 路径(可以是相对的)| 私有bundle路径,私有bundle路径
分割符 ‘|’ ‘,’
比如: 公用
Application.persistantDatapath + “/publicBundles”+”/road.assetbunlde”;

采用自己定义的格式就可以。

另外,有一个文件记录所有的assetbundle的当前版本,用来供读取。

时间: 2024-10-24 19:56:05

AssetBundle 点滴的相关文章

Assetbundle 打包加载及服务器加载等(采用unity3d5.0后的新版)

Assetbundle为资源包不是资源 打包1:通过脚本指定打包 AssetBundleBuild ab = new AssetBundleBuild { assetBundleName = PlayerSettings.bundleVersion + "@" + "zhao",//资源包assets的名字 assetNames = new string[1],  //包里的每个资源的名字 }; string outputPath = Path.Combine(Ut

unity 打包AssetBundle

unity提供了assetbunlde机制,下面介绍一种方法将指定目录下的所有文件打包成AssetBundle 先说明步骤,再上代码. 步骤一.选择要打包成assetbundle的目录,本案例使用assetbundle_raw 步骤二.把要打包的资源或者目录都放到assetbundle_raw目录,资源可以是 prefab,png,fbx,font,audio,txt等. 步骤三.给assetbundle_raw目录下所有的资源文件设置assetbundle名称,如果是目录,会递归. 名称格式:

Unity5 打包assetbundle

Assetbundle打包完成后出现的问题 1:Lightmap丢失? LightMap丢失的主要原来是场景中用到的各种系统自带Shader没有打包进去 Edit->Project Setting->Graphics 添加系统级Shader 2:  加载prefab后纹理丢失? 这个主要是加载顺序问题,先加载依赖文件,并调用www.assetbund

Unity3D之AssetBundle学习:Android上运行笔记

路径统一 在Android上加载StreamingAssets文件夹下的AssetBundle文件,首先需要对加载地址进行处理,注意PC.Android和IOS的地址不一致需要针对不同的平台不同的处理,通用代码如下: 1 //统一不同平台下 StreamingAssets 路径 2 public static readonly string STREAMING_ASSETS_PATH = 3 #if UNITY_ANDROID 4 "jar:file:///" + Applicatio

Unity3d 同步加载 Assetbundle 方法 AssetBundle.CreateFromFile

今天在群里问朋友有没有 同步加载 Assetbundle 的方法,同事给我指点 Unity3d 不知道在哪一个版本新增了一个 AssetBundle.CreateFromFile 的接口,这个接口是同步读取Assetbundle的.于是到帮助文档查询相关资料. http://docs.unity3d.com/ScriptReference/AssetBundle.CreateFromFile.html 文章转自http://blog.csdn.net/huutu 星环游戏 http://www.

Unity资源Assetbundle

转  Unity资源打包之Assetbundle 本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.net/janeky/article/details/17652021 如果这篇文章对你有帮助,敬请关注作者<Unity手游之路>系列教程. 在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制成预设Prefab,打包成场景.今天我们来一起学习官方推荐的As

牛腩新闻发布系统总结(四)--知识点滴

紧接上篇博客:牛腩新闻发布系统总结(三)----知识点滴,继续我们的总结: 第五,在回复评论后如何保持滚动条的位置不变: <%@ Page Title="新闻内容-牛腩新闻发布系统" Language="C#" MasterPageFile="~/common.Master" AutoEventWireup="true" CodeBehind="newsContent.aspx.cs" Inherit

java点滴之volatile关键字特性

一 问题引入 JVM把内存分为两层,一层为大的主存,另外一个是工作内存(属于每个线程自己专属的),正常情况下,线程在用到某个变量的值时,都是先取到工作内存中进行处理,然后再写回主存,这样就会带来不同线程变量值不同步的问题. volatile字面意思是易挥发,不稳定,比如100个线程同时访问修改的一个字段值,那么这种值的特性明显和JVM中高速缓存机制不相符,这种值是不适合放在各线程自己的寄存器中的,那会导致100个线程中持有的副本都不一样. 二volatile修饰符作用 当一个变量被声明成 vol

Unity5 AssetBundle系列——资源加载卸载以及AssetBundleManifest的使用

下面代码列出了对于assetbundle资源的常用操作,其中有针对bundle.asset.gameobject三种类型对象的操作,实际使用中尽量保证成对使用. 这一块的操作比较繁琐,但只要使用正确,是可以保证资源完全没有泄露的. using UnityEngine; using System.Collections; public class TestAssetBundle : MonoBehaviour { public string AssetBundleName = "cube1.ass