Unity3d之AssetBundle打包与读取

一、创建Assetbundle

在unity3d开发的游戏中,无论模型,音频,还是图片等,我们都做成Prefab,然后打包成Assetbundle,方便我们后面的使用,来达到资源的更新。

       一个Assetbundle可以打包一个模型(这里的模型不单单指的是预制模型,可以是Project视图下的任何东西),也可以是多个模型,但两种打包方式占用的空间不一样。

      比如我打包三个一样的模型(只不过他们的脚本不一样创建三个空的GameObject(One,Two,Three),分别挂载脚本One,Two,Three)。如果我为每个模型单独打包生成One,Two,Three三个Assetbundle,其所占的空间是A,B,C,但是A+B+C != D.由此可知想通的资源尽可能的打包到一起,他们共用一套资源。不相同的模型尽量分开打包。



二、分开打包(注意这个脚本必须放在Editor文件夹内,Editor文件夹没有的话需自己创建)

	/// 
	/// 将选中的预制分别打包
	/// 
	[MenuItem("AssetBundleDemo/Create AssetBundles By themselves")]
	static void CreateAssetBundleThemelves(){
		//获取要打包的对象(在Project视图中)
		Object[] selects = Selection.GetFiltered (typeof(Object),SelectionMode.DeepAssets);
		//遍历选中的对象
		foreach(Object obj in selects){
			//这里建立一个本地测试
			//注意本地测试中可以是任意的文件,但是到了移动平台只能读取路径StreamingAssets里面的
			//StreamingAssets是只读路径,不能写入
			string targetPath = Application.dataPath + "/AssetBundleLearn/StreamingAssets/" + obj.name + ".assetbundle";//文件的后缀名是assetbundle和unity都可以
			if(BuildPipeline.BuildAssetBundle(obj,null,targetPath,BuildAssetBundleOptions.CollectDependencies)){

				Debug.Log(obj.name + "is packed successfully!");
			}else{
				Debug.Log(obj.name + "is packed failly!");
			}
		}
		//刷新编辑器(不写的话要手动刷新,否则打包的资源不能及时在Project视图内显示)
		AssetDatabase.Refresh ();
	}

SelectionMode.DeepAssets

这个选择模式意味着如果选择中包含多个文件,那么他将包含这个文件视图中的所有资源。

他还有其他的各种选项(以下是官方文档)

SelectionMode

Description

SelectionMode can be used to tweak the selection returned by Selection.GetTransforms.

The default transform selection mode is: SelectionMode.TopLevel | SelectionMode.ExcludePrefab | SelectionMode.Editable.

Unfiltered Return the whole selection.
TopLevel Only return the topmost selected transform. A selected child of another selected transform will be filtered out.
Deep Return the selection and all child transforms of the selection.
ExcludePrefab Excludes any prefabs from the selection.
Editable Excludes any objects which shall not be modified.
Assets Only return objects that are assets in the Asset directory.
DeepAssets If the selection contains folders, also include all assets and subfolders within that folder in the file hierarchy.

最核心的方法:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)

参数1:它只能放一个对象,因为我们这里是分别打包,所以通过循环将每个对象分别放在了这里。

参数2:可以放入一个数组对象。

参数3:要打包到的路径

参数4:默认情况下打的包只能在电脑上用,如果要在手机上用就要添加一个参数。

Android上:

BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.Android)

IOS上:

BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone)

另外,电脑上和手机上打出来的Assetbundle不能混用,不同平台只能用自己的。

三、一起打包

	/// 
	/// 将选中的预制打包到一起
	/// 
	[MenuItem("AssetBundleDemo/Create AssetBundles Together")]
	static void CreateAssetBundleTogether(){
		//要打包的对象
		Object[] selects = Selection.GetFiltered (typeof(Object),SelectionMode.DeepAssets);
		//要打包到的路径
		string targetPath = Application.dataPath + "/AssetBundleLearn/StreamingAssets/Together.assetbundle";
		if(BuildPipeline.BuildAssetBundle(null,selects,targetPath,BuildAssetBundleOptions.CollectDependencies)){
			Debug.Log("Packed successfully!");

		}else{
			Debug.Log("Packed failly!");
		}
		//刷新编辑器(不写的话要手动刷新)
		AssetDatabase.Refresh ();
	}
}


四、读取

using UnityEngine;
using System.Collections;

public class ReanAssetbundle : MonoBehaviour {

	//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。
	public static readonly string m_PathURL =
		#if UNITY_ANDROID
		"jar:file://" + Application.dataPath + "!/assets/";
		#elif UNITY_IPHONE
		Application.dataPath + "/Raw/";
		#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
	    "file://" + Application.dataPath + "/AssetBundleLearn/StreamingAssets/";
		#else
		string.Empty;
		#endif

	void OnGUI(){
		if(GUILayout.Button("加载分开打包的Assetbundle")){
			StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "One.assetbundle"));
			StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL +  "Two.assetbundle"));
			StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "Three.assetbundle"));

		}
		
		if(GUILayout.Button("加载打包在一起的Assetbundle")){
			StartCoroutine(LoadGameObjectPackedTogether(m_PathURL + "Together.assetbundle"));
		}
		
	}
	//单独读取资源
	private IEnumerator LoadGameObjectPackedByThemselves(string path){
		WWW bundle = new WWW (path);
		yield return bundle;

		//加载
		yield return Instantiate (bundle.assetBundle.mainAsset);
		bundle.assetBundle.Unload (false);
	}

	IEnumerator  LoadGameObjectPackedTogether (string path)
	{
		WWW bundle = new WWW (path);
		yield return bundle;

		Object one = bundle.assetBundle.Load ("One");
		Object two = bundle.assetBundle.Load ("Two");
		Object three = bundle.assetBundle.Load ("Three");

		//加载
		yield return Instantiate (one);
		yield return Instantiate (two);
		yield return Instantiate (three);
		bundle.assetBundle.Unload (false);
	}
}



你可能感兴趣的:(Unity3D)