参考链接:
http://liweizhaolili.blog.163.com/blog/static/16230744201541410275298/
http://liweizhaolili.blog.163.com/blog/static/162307442015282017852/
http://itfish.net/article/35172.html
简单的说,unity打包时,会为每个文件创建一个.unity3d文件和.manifest文件。其中.unity3d文件包含了被打包的资源,.manifest文件记录该资源的依赖关系。然后所有.manifest文件汇总到一个总的依赖文件中,在游戏最开始运行的时候需要加载这个总的依赖文件,然后加载assetbundle的时候,从中获取到依赖关系来加载依赖。在操作中,实际操作的还是.unity3d文件,而.manifest文件主要的作用就是查看依赖关系。
总结起来,就是四步:
1.为assetbundle起名字,并打包
2.加载总的依赖文件
3.加载assetbundle的依赖文件
4.加载assetbundle
1.命名并打包
using UnityEngine; using System.Collections; using UnityEditor; using System.IO; public class CreateAssetBundle : Editor { [MenuItem("Tool/SetAssetBundleNameExtension")] static void SetBundleName() { #region 设置资源的AssetBundle的名称和文件扩展名 UnityEngine.Object[] selects = Selection.objects; foreach (UnityEngine.Object selected in selects) { string path = AssetDatabase.GetAssetPath(selected); AssetImporter asset = AssetImporter.GetAtPath(path); asset.assetBundleName = selected.name; //设置Bundle文件的名称 asset.assetBundleVariant = "unity3d";//设置Bundle文件的扩展名 asset.SaveAndReimport(); } AssetDatabase.Refresh(); #endregion } [MenuItem("Tool/BuildAll")] static void Build() { string path = Application.dataPath + "/AB"; if(!Directory.Exists(path)) Directory.CreateDirectory(path); BuildPipeline.BuildAssetBundles(path); AssetDatabase.Refresh(); } }
using UnityEngine; using System.Collections; using UnityEditor; public class AutoSetAssetBundleName : AssetPostprocessor { static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (var str in importedAssets) { //Debug.Log("Reimported Asset: " + str); if(!str.EndsWith(".cs")) { AssetImporter importer = AssetImporter.GetAtPath(str); importer.assetBundleName = str; } } foreach (var str in deletedAssets) { //Debug.Log("Deleted Asset: " + str); if(!str.EndsWith(".cs")) { AssetImporter importer = AssetImporter.GetAtPath(str); importer.assetBundleName = str; } } for (var i=0; i<movedAssets.Length; i++) { //Debug.Log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]); } } }
2.加载
using UnityEngine; using System.Collections; public class AssetbBundleManager : MonoSingletion<AssetbBundleManager> { public delegate void OnLoadAssetbBundleFinish(AssetBundle assetBundle, string nameWithoutExtension); /// <summary> /// /// </summary> /// <param name="assetBundleDir">Assetbundle的文件夹 </param> /// <param name="assetBundleName">要加载的AssetBundle的名字</param> public void Load(string assetBundleDir, string assetBundleName, OnLoadAssetbBundleFinish onLoadFinish) { StartCoroutine(LoadIEnumerator(assetBundleDir, assetBundleName, onLoadFinish)); } private IEnumerator LoadIEnumerator(string assetBundleDir, string assetBundleName, OnLoadAssetbBundleFinish onLoadFinish) { //首先加载总Manifest文件; WWW wwwAll = new WWW(assetBundleDir + "AB"); yield return wwwAll; if (!string.IsNullOrEmpty(wwwAll.error)) { Debug.LogError(wwwAll.error); } else { AssetBundle ab = wwwAll.assetBundle; AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest"); ab.Unload(false); //获取依赖文件列表; string[] depends = manifest.GetAllDependencies(assetBundleName); AssetBundle[] dependsAssetBundle = new AssetBundle[depends.Length]; for (int index = 0; index < depends.Length; index++) { //加载所有的依赖文件; WWW dwww = WWW.LoadFromCacheOrDownload(assetBundleDir + depends[index], 0); yield return dwww; dependsAssetBundle[index] = dwww.assetBundle; } //加载我们需要的文件; WWW www = new WWW(assetBundleDir + assetBundleName); yield return www; if (!string.IsNullOrEmpty(www.error)) { Debug.LogError(www.error); } else { string name = assetBundleName.Substring(0, assetBundleName.IndexOf(".")); AssetBundle assetBundle = www.assetBundle; onLoadFinish(assetBundle, name); assetBundle.Unload(false); } //卸载依赖文件的包 for (int index = 0; index < depends.Length; index++) { dependsAssetBundle[index].Unload(false); } } } public string GetString(AssetBundle assetBundle, string name) { return assetBundle.LoadAsset<TextAsset>(name).ToString(); } public GameObject GetGameObject(AssetBundle assetBundle, string name) { return assetBundle.LoadAsset<GameObject>(name); } }
using UnityEngine; using System.Collections; using LuaInterface; public class LoadAssetbBundle : MonoBehaviour { void Start() { string dir = @"file:///" + Application.persistentDataPath + "/"; //Debug.Log(dir); AssetbBundleManager.Instance.Load(dir, "newuluascript.unity3d", (ab, name) => { string content = AssetbBundleManager.Instance.GetString(ab, name); LuaScriptMgr lua = new LuaScriptMgr(); lua.Start(); lua.DoString(@content); }); } }