# AssetBundle 创建与加载
- AssetBundle 只能用代码创建和加载
- 在创建前需要先为资源分配资源包,如图:
# AssetBundle 的创建
- 区分平台(Windows、OSX、Linux 等)
- 区分创建方式(是否压缩、压缩方式等)
using System.IO; | |
using UnityEditor; | |
namespace Common | |
{ | |
/// <summary> | |
/// CreateAssetBundles | |
/// </summary> | |
public class CreateAssetBundles | |
{ | |
//[MenuItem("Assets/Build AssetBundles")] | |
[MenuItem("Build/Build AssetBundles")] | |
private static void BuildAllAssetBundles() | |
{ | |
string assetBundleDirectory = "Assets/StreamingAssets/AssetBundles"; | |
BuildAssetBundleOptions assetBundleOptions; | |
BuildTarget targetPlatform; | |
#if UNITY_EDITOR | |
assetBundleOptions = BuildAssetBundleOptions.UncompressedAssetBundle; | |
targetPlatform = BuildTarget.StandaloneWindows64; | |
#elif UNITY_STANDALONE_WIN //Windows 独立平台应用程序 | |
assetBundleOptions = BuildAssetBundleOptions.UncompressedAssetBundle; | |
targetPlatform = BuildTarget.StandaloneWindows64; | |
#elif UNITY_STANDALONE_OSX //Mac OS X(包括 Universal、PPC 和 Intel 架构) | |
assetBundleOptions = BuildAssetBundleOptions.UncompressedAssetBundle; | |
targetPlatform = BuildTarget.StandaloneOSX; | |
#elif UNITY_STANDALONE_LINUX //Linux | |
assetBundleOptions = BuildAssetBundleOptions.UncompressedAssetBundle; | |
targetPlatform = BuildTarget.StandaloneLinux; | |
#elif UNITY_ANDROID | |
assetBundleOptions = BuildAssetBundleOptions.ChunkBasedCompression; | |
targetPlatform = BuildTarget.Android; | |
#elif UNITY_IOS | |
assetBundleOptions = BuildAssetBundleOptions.ChunkBasedCompression; | |
targetPlatform = BuildTarget.iOS; | |
#elif UNITY_WEBGL | |
assetBundleOptions = BuildAssetBundleOptions.ChunkBasedCompression; | |
targetPlatform = BuildTarget.WebGL; | |
#endif | |
if (!Directory.Exists(assetBundleDirectory)) | |
{ | |
Directory.CreateDirectory(assetBundleDirectory); | |
} | |
else | |
{ | |
Directory.Delete(assetBundleDirectory, true); | |
Directory.CreateDirectory(assetBundleDirectory); | |
} | |
BuildPipeline.BuildAssetBundles(assetBundleDirectory, assetBundleOptions, targetPlatform); | |
} | |
} | |
} |
# AssetBundle 的加载
- 两种加载方式:通过网络请求加载(UnityWebRequest)、通过本地存储加载(AssetBundle.LoadFromFile ())
- 本工具类中使用网络请求加载方式,目的是为了适配更多的设备
- 同一个 ab 包中如果有多个同名文件,则只会加载第一个匹配的文件
- 加载目标 ab 包前,需要先加载它的依赖 ab 包(如果存在)
- 加载目标 ab 包后,调用委托处理其他逻辑
- 加载的 ab 包在使用完后需要要卸载,防止占用内存
using System; | |
using System.Collections; | |
using UnityEngine; | |
using UnityEngine.Networking; | |
namespace Common | |
{ | |
/// <summary> | |
///ab 包管理器 | |
/// </summary> | |
public class AssetBundleManager | |
{ | |
/// <summary> | |
/// 加载资源包 | |
/// </summary> | |
/// <param name="path"> 路径 & lt;/param> | |
/// <param name="action"> 委托 & lt;/param> | |
/// <returns></returns> | |
public static IEnumerator LoadAssetBundle(string path, Action<AssetBundle> action) | |
{ | |
string assetBundleName = path.Split('/')[^1]; | |
string startPath = path.Substring(0, path.LastIndexOf('/')); | |
// 获取 AssetBundles 文件 | |
UnityWebRequest request_0 = UnityWebRequestAssetBundle.GetAssetBundle(startPath + "/AssetBundles", 0); | |
yield return request_0.SendWebRequest(); | |
if (request_0.result != UnityWebRequest.Result.Success) | |
{ | |
Debug.LogError("Failed to load AssetBundle:" + request_0.error); | |
} | |
else | |
{ | |
AssetBundle bundle_0 = DownloadHandlerAssetBundle.GetContent(request_0); | |
// 获取 manifest 文件 | |
AssetBundleManifest manifest_0 = bundle_0.LoadAsset("AssetBundleManifest") as AssetBundleManifest; | |
bundle_0.Unload(false); | |
// 查找并加载依赖文件 | |
string[] dependencies = manifest_0.GetAllDependencies(assetBundleName); | |
AssetBundle[] bundles = new AssetBundle[dependencies.Length]; | |
for (int i = 0; i < dependencies.Length; i++) | |
{ | |
string dependenciesPath = startPath + '/' + dependencies[i]; | |
UnityWebRequest requests = UnityWebRequestAssetBundle.GetAssetBundle(dependenciesPath, 0); | |
yield return requests.SendWebRequest(); | |
if (requests.result != UnityWebRequest.Result.Success) | |
{ | |
Debug.LogError("Failed to load AssetBundle:" + requests.error); | |
} | |
else | |
{ | |
bundles[i] = DownloadHandlerAssetBundle.GetContent(requests); | |
} | |
} | |
// 取出资源 | |
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(path, 0); | |
yield return request.SendWebRequest(); | |
if (request.result != UnityWebRequest.Result.Success) | |
{ | |
Debug.LogError("Failed to load AssetBundle:" + request.error); | |
} | |
else | |
{ | |
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request); | |
action(bundle); | |
bundle.Unload(false); | |
} | |
foreach (AssetBundle item in bundles) | |
{ | |
item.Unload(false); | |
} | |
} | |
} | |
} | |
} |
# 使用方法
创建
点击按钮创建 ab 包,如图:
加载
private void OnGUI() | |
{ | |
if (GUILayout.Button("LoadAssetBundle")) | |
{ | |
this.StartCoroutine(AssetBundleManager.LoadAssetBundle(Application.streamingAssetsPath + "/AssetBundles/model.model", TestAction)); | |
} | |
} | |
private void TestAction(AssetBundle bundle) | |
{ | |
GameObject receive = bundle.LoadAsset<GameObject>("Cube_1"); | |
Instantiate(receive, Vector3.zero, Quaternion.identity); | |
} |