参考链接:
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);
});
}
}