[小明爬坑系列]AssetBundle实战
一.创建assetbundle文件
将asset数据进行AssetBundle的代码如下:
1 using UnityEngine; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.IO; 5 using UnityEditor; 6 7 public class AssetBundle : Editor 8 { 9 //将选中目录下以及子目录下的所有的asset文件打包 10 [MenuItem("GameObject/Build AssetBundles From Directory of AssetFiles")] 11 private static void ExportAssetBundles() 12 { 13 //选中的目录 14 string path = AssetDatabase.GetAssetPath(Selection.activeObject); 15 //选中目录中的子文件夹 16 var childPaths = new Stack<string>(); 17 childPaths.Push(path); 18 //待打包链表 19 var waitForBundleList = new List<Object>(); 20 21 while (childPaths.Count != 0) 22 { 23 var curPath = childPaths.Pop(); 24 curPath = curPath.Replace("\\", "/"); 25 //1.获得所有当前目录下的子目录和子文件 26 var fileEntries = Directory.GetFiles(curPath); 27 var pathEntries = Directory.GetDirectories(curPath); 28 //2.子目录加入到stack中 29 foreach (var pathEntry in pathEntries) 30 { 31 childPaths.Push(pathEntry); 32 } 33 //3.子文件,是asset的加入到待打包的链表中 34 foreach (var fileEntry in fileEntries) 35 { 36 //先加载 37 var t = AssetDatabase.LoadMainAssetAtPath(fileEntry); 38 if (t != null) 39 { 40 waitForBundleList.Add(t); 41 } 42 } 43 } 44 45 //打包 46 if (BuildPipeline.BuildAssetBundle(waitForBundleList[0], waitForBundleList.ToArray(), 47 Application.streamingAssetsPath + "/" + "name.assetbundle", BuildAssetBundleOptions.CollectDependencies, 48 BuildTarget.Android)) 49 { 50 AssetDatabase.Refresh(); 51 } 52 } 53 }
创建时,Projection面板下选择了所定义的Asset数据的文件夹,将文件夹中所包含的所有子文件以及Asset都打包到了StreamingAssets的name.assetbundle文件中.
二.读取assetbundle文件
存储的是技能asset数据,读取代码如下:
1 public static readonly string PathURL = 2 #if UNITY_ANDROID 3 "jar:file://" + Application.dataPath + "!/assets/"; 4 #elif UNITY_IPHONE 5 Application.dataPath + "/Raw/"; 6 #elif UNITY_ANDROID||UNITY_STANDALONE_WIN || UNITY_EDITOR 7 "file://" + Application.dataPath + "/StreamingAssets/"; 8 #else 9 string.Empty; 10 #endif 11 private void Start() 12 { 13 //初始化所有技能 14 StartCoroutine(InitAllSkill()); 15 //初始化玩家技能 16 InitPlayerSkill(); 17 } 18 19 /// <summary> 20 /// 根据序列化初始化当前的所有技能 21 /// </summary> 22 private IEnumerator InitAllSkill() 23 { 24 WWW bundle = null; 25 26 bundle = new WWW(PathURL + "name.unity3D"); 27 MessageUiManger.Instance.Print("Path:" + PathURL + "name.unity3D"); 28 MessageUiManger.Instance.Print("Bundle.error:" + bundle.error); 29 MessageUiManger.Instance.Print("bundle.assetBundle" + bundle.assetBundle); 30 yield return bundle; 31 32 try 33 { 34 var player = GameObject.FindGameObjectWithTag(Tags.Player); 35 var skill = bundle.assetBundle.LoadAll(typeof (Skill)); 36 foreach (var o in skill) 37 { 38 var s = o as Skill; 39 MessageUiManger.Instance.Print(s.ToString()); 40 PlayerSkills.Add(s.Id, s); 41 s.Init(player); 42 } 43 } 44 catch (Exception e) 45 { 46 MessageUiManger.Instance.Print(e.Message); 47 } 48 }
不同的平台需要不同的读取路径,通过c#的宏定义,将在目标平台变更时,编译不同的代码而改变读取路径.而用来指定编译宏定义的几个名称应该是写到了一些特殊文件里,但我还不知道写在了哪里.
在读取了Asset文件时,其中的关联关系不会改变,虽然不知道是如何实现的,但是用起来很方便.