[Unity3d]打包Assetbundle并加载

因为咱们要将模型资源放在远程的服务器端,但若是直接放fbx模型是不能够加载的,因此咱们能够将fbx作成预设或者是直接将其打包成assetbundle格式的,而后经过www来加载获取。html


说下使用方法:web

一、把附件脚本放到工程文件夹下的...\Assets\Editor文件夹下。windows

二、在工程的Project视图里点击想要保存的资源,网络上推荐的是Prefab,右键点击,选择菜单里最下面的两个选项任意一个均可以,第一个选项对应的自定义属性有一个过时了,可是不影响使用。缓存

三、指定文件的构建路径和文件后缀,后缀无所谓。服务器

四、推荐制造作法:网络

任何形式的资源均可以,包括集合资源,好比建立一个空的GameObject,把全部想要关联的其余GameObject都拖进去,而后在project视图里建立一个prefab,将这个集合资源GameObject拖进去做为一个prefab。执行上面的第二、3步骤。编辑器


官方的讲解:http://game.ceeger.com/Script/BuildPipeline/BuildPipeline.BuildAssetBundle.htmlide


1.首先要讲一下不一样平台下的一个StreamingAssets路径,这是不一样的。学习

	    //不一样平台下StreamingAssets的路径是不一样的,这里须要注意一下。 	    public static readonly string PathURL = #if UNITY_ANDROID   //安卓 		"jar:file://" + Application.dataPath + "!/assets/"; #elif UNITY_IPHONE  //iPhone 		Application.dataPath + "/Raw/"; #elif UNITY_STANDALONE_WIN || UNITY_EDITOR  //windows平台和web平台 	"file://" + Application.dataPath + "/StreamingAssets/"; #else         string.Empty; #endif

这就获取到了不一样平台的一个路径,咱们能够将打包的文件放在这些路径下,而后再从这路径去读取资源。测试

2.关于打包assetbundle的脚本

using UnityEngine; using System.Collections; using UnityEditor;  public class Test : Editor { 	//打包单个 	[MenuItem("Custom Editor/Create AssetBunldes Main")] 	static void CreateAssetBunldesMain () 	{         //获取在Project视图中选择的全部游戏对象 		Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);           //遍历全部的游戏对象 		foreach (Object obj in SelectedAsset)  		{ 			//本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,若是没有就建立一个,由于移动平台下只能读取这个路径 			//StreamingAssets是只读路径,不能写入 			//服务器下载:就不须要放在这里,服务器上客户端用www类进行下载。 			string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle"; 			if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) {   				Debug.Log(obj.name +"资源打包成功"); 			}  			else  			{  				Debug.Log(obj.name +"资源打包失败"); 			} 		} 		//刷新编辑器 		AssetDatabase.Refresh ();	 		 	} 	 	[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 (); 		} else { 			 		} 	} 	 	[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 (); 	} 	 } 

前提要新手动建立一个StreamingAssets文件夹

3.读取资源,这里只举例从本地读取,跟从网络读取是同样的,能够参考官方文档:

http://game.ceeger.com/Script/WWW/WWW.html

using UnityEngine; using System.Collections;  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/"; #else         string.Empty; #endif 	 	void OnGUI() 	{ 		if(GUILayout.Button("Main Assetbundle")) 		{ 			//StartCoroutine(LoadMainGameObject(PathURL + "Prefab0.assetbundle")); 			//StartCoroutine(LoadMainGameObject(PathURL +  "Prefab1.assetbundle")); 		 			StartCoroutine(LoadMainCacheGameObject(PathURL + "Prefab0.assetbundle")); 			StartCoroutine(LoadMainCacheGameObject(PathURL +  "Prefab1.assetbundle")); 		} 		 		if(GUILayout.Button("ALL Assetbundle")) 		{ 			StartCoroutine(LoadALLGameObject(PathURL + "ALL.assetbundle")); 		} 		 		if(GUILayout.Button("Open Scene")) 		{ 			StartCoroutine(LoadScene()); 		} 		 	} 	 	//读取一个资源 	 	private IEnumerator LoadMainGameObject(string path) 	{ 		 WWW bundle = new WWW(path); 		  		 yield return bundle; 		  		 //加载到游戏中 		 yield return Instantiate(bundle.assetBundle.mainAsset); 		  		 bundle.assetBundle.Unload(false); 	} 	 	//读取所有资源 	 	private IEnumerator LoadALLGameObject(string path) 	{ 		 WWW bundle = new WWW(path); 		  		 yield return bundle; 		  		 //经过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); 	} 	 	private IEnumerator LoadMainCacheGameObject(string path) 	{ 		 WWW bundle = WWW.LoadFromCacheOrDownload(path,5); 		  		 yield return bundle; 		  		 //加载到游戏中 		 yield return Instantiate(bundle.assetBundle.mainAsset); 		  		 bundle.assetBundle.Unload(false); 	} 	 	 	private IEnumerator LoadScene() 	{ 		 WWW download = WWW.LoadFromCacheOrDownload ("file://"+Application.dataPath + "/MyScene.unity3d", 1); 			 		  yield return download; 		  var bundle = download.assetBundle;   		  Application.LoadLevel ("Level"); 	} } 


若是assetbundle文件放在服务器端,直接用www.loadfromcacheordownload()经过版原本控制是否从服务器下载并保存到本地。本人亲自测试,这个方法是能下载到本地的,至于下载在本地哪儿我就不太清楚了,我猜想应该是存在沙盒文件下(移动开发者的朋友应该知道),固然也能够本身来作版本控制,那样更灵活,而且摆脱www.loadfromcacheordownload()方法的束缚,貌似这个方法存贮文件是有空间大小限制的,听说是50M,本人没有亲自考证,后期我会本身作一个版本控制!


==================== 迂者 丁小未 CSDN博客专栏=================

MyBlog:http://blog.csdn.net/dingxiaowei2013             MyQQ:1213250243

Unity QQ群:858550         cocos2dx QQ群:280818155

====================== 相互学习,共同进步 ===================