一、打AB包
1、编排打包资源的路径
2、使用脚本打包
打包之后会在ab包的目录生成一个与父目录相同的主清单文件。用来获取ab包的依赖关系。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using Net.Realmoon.Config;
public class ABBuilder
{
[MenuItem("realmoon/Build Asset Bundle")]
public static void BuildAsserBundles()
{
string dir = GameConfig.ABROOTPATH;
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);
}
}
二、使用AB包
1、加载AB包的流程
- 获取加载主清单文件:AB根路径/主文件名
- 加载AB包的所有依赖包
- 加载目标AB包:AB根路径[/子文件]/AB包文件(含拓展名)
2、加载AB包资源的流程
- 加载AB包
- 从AB包中加载资源
三、代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Net.Realmoon.Singleton;
using Net.Realmoon.Mono;
using Net.Realmoon.IO.Files;
using Net.Realmoon.Config;
using System.IO;
namespace Net.Realmoon.IO.AB
{
/// <summary>
/// ab包工具类
/// </summary>
public class AssetBundleTools : SingletonBase<AssetBundleTools>
{
//主包资源
private AssetBundle mainAssetBundle = null;
private AssetBundleManifest mainManifest = null;
//加载过的资源
private Dictionary<string, AssetBundle> assetBundleMap = new Dictionary<string, AssetBundle>();
/// <summary>
/// 获取AB包的路径
/// </summary>
/// <returns></returns>
public string GetABPath()
{
return Application.streamingAssetsPath + "/Android/";
}
#region 同步加载资源
public void LoadAB(string abPath, string abName)
{
AssetBundle ab = null;
//加载主包
if (mainAssetBundle == null)
{
//加载主包
mainAssetBundle = AssetBundle.LoadFromFile(GameConfig.ABMAINFASTPATH);
//加载主包配置文件
mainManifest = mainAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}
//获取依赖文件
string[] dependencies = mainManifest.GetAllDependencies(abName);
foreach (var dependency in dependencies)
{
if (!assetBundleMap.ContainsKey(dependency))
{
ab = AssetBundle.LoadFromFile(Path.Join(abPath, dependency));
assetBundleMap.Add(dependency, ab);
}
}
//加载资源包
if (!assetBundleMap.ContainsKey(abName))
{
ab = AssetBundle.LoadFromFile(Path.Join(abPath, abName));
assetBundleMap.Add(abName, ab);
}
}
//加载指定资源
public Object LoadAssetBundle(string abPath, string abName, string resName)
{
LoadAB(abPath, abName);
//获取资源
Object obj = assetBundleMap[abName].LoadAsset(resName);
if (obj is GameObject)
{
return GameObject.Instantiate(obj);
}
return obj;
}
//同步加载指定类型的资源
public Object LoadAssetBundle(string abPath, string abName, string resName, System.Type type)
{
LoadAB(abPath, abName);
Object obj = assetBundleMap[abName].LoadAsset(resName, type);
if (obj is GameObject)
{
return GameObject.Instantiate(obj);
}
return obj;
}
//同步加载指定类型的资源
public T LoadAssetBundle<T>(string abPath, string abName, string resName) where T : Object
{
LoadAB(abPath, abName);
T obj = assetBundleMap[abName].LoadAsset<T>(resName);
if (obj is GameObject)
{
return GameObject.Instantiate(obj);
}
return obj;
}
/// <summary>
/// 从ab包中读取文件
/// </summary>
/// <param name="abPath"></param>
/// <param name="abName"></param>
/// <param name="resName"></param>
/// <returns></returns>
public string LoadAssetBundleText(string abPath, string abName, string resName)
{
LoadAB(abPath, abName);
TextAsset ta = assetBundleMap[abName].LoadAsset<TextAsset>(resName);
if (ta == null)
{
return "";
}
else
{
return ta.text;
}
}
#endregion
#region 异步资源加载
public void LoadAssetBundleAsync(string abPath, string abName, string resName, UnityAction<Object> callback)
{
MonoTools.Instance.StartCoroutine(ReallyLoadAssetBundleAsync(abPath, abName, resName, callback));
}
public IEnumerator ReallyLoadAssetBundleAsync(string abPath, string abName, string resName, UnityAction<Object> callback)
{
LoadAB(abPath, abName);
AssetBundleRequest request = assetBundleMap[abName].LoadAssetAsync(resName);
yield return request;
Object obj = request.asset;
if (obj is GameObject)
{
callback(GameObject.Instantiate(obj));
}
callback(obj);
}
public void LoadAssetBundleAsync(string abPath, string abName, string resName, System.Type type, UnityAction<Object> callback)
{
MonoTools.Instance.StartCoroutine(ReallyLoadAssetBundleAsync(abPath, abName, resName, type, callback));
}
public IEnumerator ReallyLoadAssetBundleAsync(string abPath, string abName, string resName, System.Type type, UnityAction<Object> callback)
{
LoadAB(abPath, abName);
AssetBundleRequest request = assetBundleMap[abName].LoadAssetAsync(resName, type);
yield return request;
Object obj = request.asset;
if (obj is GameObject)
{
callback(GameObject.Instantiate(obj));
}
callback(obj);
}
public void LoadAssetBundleAsync<T>(string abPath, string abName, string resName, UnityAction<T> callback) where T : Object
{
MonoTools.Instance.StartCoroutine(ReallyLoadAssetBundleAsync(abPath, abName, resName, callback));
}
public IEnumerator ReallyLoadAssetBundleAsync<T>(string abPath, string abName, string resName, UnityAction<T> callback) where T : Object
{
LoadAB(abPath, abName);
AssetBundleRequest request = assetBundleMap[abName].LoadAssetAsync<T>(resName);
yield return request;
T obj = request.asset as T;
if (obj is GameObject)
{
callback(GameObject.Instantiate(obj));
}
callback(obj);
}
#endregion
#region 资源释放
//释放单个ab包
public void UnloadAssetBundle(string abName)
{
if (assetBundleMap.ContainsKey(abName))
{
assetBundleMap[abName].Unload(true);
assetBundleMap.Remove(abName);
}
}
//释放所有ab包
public void Clear()
{
AssetBundle.UnloadAllAssetBundles(true);
assetBundleMap.Clear();
mainAssetBundle = null;
mainManifest = null;
}
#endregion
#region 判断
/// <summary>
/// ab文件是否存在
/// </summary>
/// <param name="abPath"></param>
/// <param name="abName"></param>
/// <returns></returns>
public bool IsAbFileConains(string abPath, string abName)
{
if (abPath == null || abName == null || abPath.Equals("") || abName.Equals(""))
{
return false;
}
if (FileTools.Instance.IsFileExist(abPath + "/" + abName))
{
return true;
}
else
{
return false;
}
}
#endregion
}
}
留言