在Unity中,AssetBundle(简称AB包)是一种将多个文件或资源打包到一个文件中的方式,用于优化资源的加载和管理。使用AB包,可以按需加载资源,减少应用的初始加载时间,并可以实现热更新等功能。下面是一个基本的流程,展示如何在Unity中加载AB包并显示其中的资源。
步骤1:创建和构建AssetBundle
-
标记资源:在Unity编辑器中,选择你想打包的资源(如Texture、Prefab等),在Inspector面板中,找到"Asset Bundle"选项,为资源设置一个AssetBundle标签。
-
构建AssetBundle:编写脚本或使用Unity编辑器的AssetBundle Browser工具来构建AssetBundle。构建时可以选择不同的平台作为目标,比如Windows、Android等。
-
构建的AssetBundle会默认放到StreamingAssets文件里
步骤2:将AssetBundle放置到可访问的路径
构建完成后,将生成的AB包放置到项目的StreamingAssets文件夹中,或者上传到Web服务器,以便运行时加载。
步骤3:编写代码加载AssetBundle并使用其中的资源
示例1:加载StreamingAssets文件夹里
假设打包的文件在StreamingAssets文件夹下windows目录里,Asset Name处填入步骤1中设置的AssetBundle标签名称
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
{
public string assetName = "";
private string assetBundleName = "";
private string prefabName = "";
void Start()
{
assetBundleName = assetName + ".unity3d";
string bundleUrl = System.IO.Path.Combine(Application.streamingAssetsPath, "windows", assetBundleName);
print(bundleUrl);
bundleUrl = "file://" + bundleUrl; // 确保路径以file://开头
StartCoroutine(LoadAssetBundleCoroutine(bundleUrl));
}
IEnumerator LoadAssetBundleCoroutine(string bundleUrl)
{
// 使用UnityWebRequest获取AssetBundle
using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(bundleUrl))
{
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success)
{
Debug.LogError("AssetBundle加载失败: " + uwr.error);
}
else
{
// 获取下载的AssetBundle
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
if (bundle != null)
{
Debug.Log("AssetBundle加载成功!");
// 获取并打印所有资源的名称
string[] assetNames = bundle.GetAllAssetNames();
foreach (string assetName in assetNames)
{
Debug.Log("AssetBundle包含资源: " + assetName);
// 加载每个对象
Object asset = bundle.LoadAsset(assetName);
if (asset is GameObject)
{
// 如果对象是GameObject(例如Prefab),则实例化它
Instantiate(asset as GameObject);
}
else
{
// 如果对象不是GameObject,可以在这里处理(例如打印日志)
Debug.Log("非GameObject资源,跳过实例化: " + assetName);
}
}
//实例化Prefab
// 使用完毕后,记得卸载AssetBundle
bundle.Unload(false);
}
else
{
Debug.LogError("AssetBundle加载失败!");
}
}
}
}
}
示例2:加载AssetBundle从网络
把AssetBundle包放到服务器上,再从服务器下载AssetBundle
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundleFromUrl : MonoBehaviour
{
public string assetBundleURL = "";
private string assetBundleName = "";
private string prefabName = "";
void Start()
{
StartCoroutine(LoadAssetBundleCoroutine(assetBundleURL));
}
IEnumerator LoadAssetBundleCoroutine(string bundleUrl)
{
print(bundleUrl);
// 使用UnityWebRequest获取AssetBundle
using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(bundleUrl))
{
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success)
{
Debug.LogError("AssetBundle加载失败: " + uwr.error);
}
else
{
// 获取下载的AssetBundle
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
if (bundle != null)
{
Debug.Log("AssetBundle加载成功!");
// 获取并打印所有资源的名称
string[] assetNames = bundle.GetAllAssetNames();
foreach (string assetName in assetNames)
{
Debug.Log("AssetBundle包含资源: " + assetName);
// 加载每个对象
Object asset = bundle.LoadAsset(assetName);
if (asset is GameObject)
{
// 如果对象是GameObject(例如Prefab),则实例化它
Instantiate(asset as GameObject);
}
else
{
// 如果对象不是GameObject,可以在这里处理(例如打印日志)
Debug.Log("非GameObject资源,跳过实例化: " + assetName);
}
}
//实例化Prefab
// 使用完毕后,记得卸载AssetBundle
bundle.Unload(false);
}
else
{
Debug.LogError("AssetBundle加载失败!");
}
}
}
}
}