[小明爬坑系列]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 }
View Code

 创建时,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         }
View Code

  不同的平台需要不同的读取路径,通过c#的宏定义,将在目标平台变更时,编译不同的代码而改变读取路径.而用来指定编译宏定义的几个名称应该是写到了一些特殊文件里,但我还不知道写在了哪里.

  在读取了Asset文件时,其中的关联关系不会改变,虽然不知道是如何实现的,但是用起来很方便.

原文地址:https://www.cnblogs.com/WongSiuming/p/5089542.html