转载地址:http://blog.csdn.net/yxingyeyouyu/article/details/42921499
前段时间做了一个项目,刚好使用到了AssetBundle资源打包的东西,于是花了点时间研究了一下AssetBundle.
AssetBundle 打包
我用NGUI插件加载了一张图片,并且把它拖拽为预制名为Texture3.prefab 和 Texture4.prefab .下面是我的打包函数
- [MenuItem("Assets/Build AssetBundle From Selection - Track dependencies")]
- static void ExportResource () {
-
- string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
- if (path.Length != 0) {
-
- Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
-
- BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets,BuildTarget.StandaloneWindows);
-
-
- EditorUtility.DisplayDialog("", "Build Completed", "OK");
-
- AssetDatabase.Refresh();
- }
- }
说明一下:
1.我们打包的资源的后缀格式可以是 ".assetbundle" 或者 ".unity3d" 。笔者这里使用的是后者
2. 解释一下打包函数的参数,第一个参数 Selection.activeObject 是我们打包的mainAsset ,
第二个参数 selection 是我们选择的对象过滤后的物体,可以为空,第三个参数 path 是 打包的资源的
保存路径 ,第四个参数是打包选项 ,我这里选用的两个选项 分别代表 打包所有有关联的对象和强制
打包全部的资源,详情请查找API文档 第五个参数是打包的平台。
AssetBundle加载
下面是我写的加载函数:
- public string[] textureName;
-
- void Start () {
- for (int i = 0; i < textureName.Length; i++)
- {
- StartCoroutine(LoadAssetBundle(PlatflamPath() + textureName[i] + ".unity3d", textureName[i]));
- }
- }
-
- static public IEnumerator LoadAssetBundle(string filepath,string assetName) {
- WWW www = new WWW(filepath);
- yield return www;
-
- if (www == null) {
- Debug.Log(" www is null ");
- }
- else if (www.error != null) {
- Debug.Log("error " + www.error);
- }
- else if (www.isDone) {
- AssetBundle assetBundle = www.assetBundle;
-
- AssetBundleRequest requet = assetBundle.LoadAsync(assetName, typeof(GameObject));
- yield return requet;
-
- if (requet.isDone) {
- GameObject obj = Instantiate(requet.asset) as GameObject;
- }
- }
- www.Dispose();
- www = null;
- }
- static public string PlatflamPath()
- {
- return string.Format("file://{0}", Application.streamingAssetsPath) + "/";
- }
AssetBundle依赖资源\共享资源打包
上面的两个预制都是用了同一张图片,我们可以将这张图片打到没一个包里面去,我们上面将的就是这种情况。这样子做的话有些弊端,比如内存有点让费,并且当这张图片有所改变的时候,两个包需要重新打包。当然,我们也可以使用AssetBundle的依赖资源\共享资源进行打包。主要会使用到下面两个函数,
BuildPipeline.PushAssetDependencies():依赖资源压栈;
BuildPipeline.PopAssetDependencies():依赖资源出栈。
笔者将上表面的Texture3.prefab复制了两份,改为Texture1.prefab 和 Texture2.prefab。还准备好预制的图片
下面是我的打包函数:
- [MenuItem("Assets/Build Rely AssetBundle")]
- static public void ExportRelyAssetBundle() {
- string filePath = Application.streamingAssetsPath+"/";
- if (filePath.Length <= 0) {
- return;
- }
-
- BuildAssetBundleOptions buildOp = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets
- | BuildAssetBundleOptions.DeterministicAssetBundle;
-
- BuildPipeline.PushAssetDependencies();
-
- Object shared = AssetDatabase.LoadMainAssetAtPath("Assets/Textures/rainDrop.png");
- BuildPipeline.BuildAssetBundle(shared, null, filePath + shared.name + ".unity3d", buildOp, BuildTarget.StandaloneWindows);
-
- BuildPipeline.PushAssetDependencies();
- Object tex1 = AssetDatabase.LoadMainAssetAtPath("Assets/Textures/Texture1.prefab");
- BuildPipeline.BuildAssetBundle(tex1, null, filePath + tex1.name + ".unity3d", buildOp, BuildTarget.StandaloneWindows);
- BuildPipeline.PopAssetDependencies();
-
- BuildPipeline.PushAssetDependencies();
- Object tex2 = AssetDatabase.LoadMainAssetAtPath("Assets/Textures/Texture2.prefab");
- BuildPipeline.BuildAssetBundle(tex2, null, filePath + tex2.name + ".unity3d", buildOp, BuildTarget.StandaloneWindows);
- BuildPipeline.PopAssetDependencies();
-
- BuildPipeline.PopAssetDependencies();
-
- EditorUtility.DisplayDialog("", "Build Completed", "OK");
- AssetDatabase.Refresh();
- }
AssetBundle依赖资源\共享资源加载
- public string[] textureName;
- public string picName;
-
- void Start () {
- if (picName.Length > 0)
- {
- StartCoroutine(LoadAssetTexture(PlatflamPath() + picName + ".unity3d", picName));
- }
-
- for (int i = 0; i < textureName.Length; i++)
- {
- StartCoroutine(LoadAssetBundle(PlatflamPath() + textureName[i] + ".unity3d", textureName[i]));
- }
- }
-
- static public IEnumerator LoadAssetBundle(string filepath,string assetName) {
- WWW www = new WWW(filepath);
- yield return www;
-
- if (www == null) {
- Debug.Log(" www is null ");
- }
- else if (www.error != null) {
- Debug.Log("error " + www.error);
- }
- else if (www.isDone) {
- AssetBundle assetBundle = www.assetBundle;
-
- AssetBundleRequest requet = assetBundle.LoadAsync(assetName, typeof(GameObject));
- yield return requet;
-
- if (requet.isDone) {
- GameObject obj = Instantiate(requet.asset) as GameObject;
- }
- }
-
- www.Dispose();
- www = null;
- }
-
- static public string PlatflamPath()
- {
- return string.Format("file://{0}", Application.streamingAssetsPath) + "/";
- }
-
- static public IEnumerator LoadAssetTexture(string filepath, string assetName)
- {
- WWW www = new WWW(filepath);
- yield return www;
-
- if (www == null)
- {
- Debug.Log(" www is null ");
- }
- else if (www.error != null)
- {
- Debug.Log("error " + www.error);
- }
- else if (www.isDone)
- {
- AssetBundle assetBundle = www.assetBundle;
- }
-
- www.Dispose();
- www = null;
- }
注意事项:
加载的时候需要加载图片,再加载跟它有关联的对象,笔者试过先加载后者,图片资源会丢失。
另外,Push和Pos都是成对使用。
相比之下,后者打包的方式前者节省空间。具体使用情况还是视个人情况而定。