1 定义
Unity中的一种特殊资源包格式,用于存储和分发游戏资源。这些资源可以包括模型、纹理、音频文件、预制体、场景等。
AssetBundle允许开发者在游戏运行时动态加载和卸载资源,从而实现灵活的资源管理。
2 使用场景
1、资源管理
有效管理游戏中的资源,按需下载需要的资源,减少内存消耗,提高游戏加载速度和响应时间。
2、游戏热更新
实现游戏热更新的重要手段。开发者可以在游戏发布后,通过服务器更新AssetBundle,从而更新或替换游戏中的资源,而无需重新发布整个游戏。可以快速修复bug,添加新内容或更新现有内容。
3、DLC(下载内容)
大型游戏通过DLC增加游戏内容。这些DLC通常包含新的关卡、角色、武器等。
3 使用
1、标记资源
在Unity编辑器中,选择需要打包的资源设置AssetBundle标签
2、创建和构建AssetBundle
编写并运行一个Editor脚本来构建AssetBundle
3、加载AssetBundle
在游戏运行时通过脚本加载AssetBundle
4、使用资源
加载AssetBundle后通过脚本获取并使用资源
5、卸载AssetBundle
使用完AssetBundle后,即使卸载释放内存
4 代码实现
编辑器脚本------构建AssetBundle
BuildPipeline
UnityEditor命名空间下的一个静态类,提供了构建玩家(Player)、资源包(如AssetBundles)和管理构建过程的功能。
常用方法(构建资源包):
BuildPipeline.BuildAssetBundles:
参数:
outputPath: 输出路径。
assetBundleOptions: 构建选项。
target: 目标平台。
builds: 要构建的 AssetBundle 列表(可选)。
cs
public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget target);
public static AssetBundleManifest BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget target);
AssetBundleBuild
UnityEditor命名空间下的一个结构体,用于描述如何打包AssetBundle的一个数据结构。定义了哪些资源文件应该被打包成AssetBundle及该AssetBundle的名称、
包含以下字段:
· assetBundleName::string 类型。AssetBundle 的名称。
· assetBundleVariant:string 类型。AssetBundle 的变体名称(可选)。
· assetNames:string[] 类型。包含在 AssetBundle 中的资源路径数组。
· addressableNames:string[] 类型。资源在 AssetBundle 中的可寻址名称(可选)。
cs
using UnityEditor;
public class BuildAssetBundles
{
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
// 定义一个 AssetBundleBuild 对象
AssetBundleBuild assetBundleBuild = new AssetBundleBuild();
// 设置 AssetBundle 的名称
assetBundleBuild.assetBundleName = "examplebundle";
// 设置包含在 AssetBundle 中的资源路径数组
assetBundleBuild.assetNames = new string[]
{
"Assets/ExampleFolder/ExampleAsset1.prefab",
"Assets/ExampleFolder/ExampleAsset2.prefab"
};
// 创建打包列表
AssetBundleBuild[] buildMap = new AssetBundleBuild[] { assetBundleBuild };
// 指定输出路径
string outputPath = "Assets/AssetBundles";
// 构建 AssetBundles
BuildPipeline.BuildAssetBundles(outputPath, buildMap, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
}
}
AssetDatabase
Code
cs
static void Build(BuildTarget target)
{
//创建AssetBundleBuild打包列表
List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();
List<string> bundleInfos = new List<string>(); //文件信息列表
//填充列表
string[] files = Directory.GetFiles(PathUtil.BuildResourcesPath, "*", SearchOption.AllDirectories); //获取BuildResourcesPath目录下所有文件
for (int i = 0; i < files.Length; i++) //根据文件构建AssetBundleBuild对象
{
//跳过meta文件
if (files[i].EndsWith(".meta"))
continue;
//处理要打包的文件,根据BundleResources中文件创建AssetBundleBuild对象
AssetBundleBuild assetBundle = new AssetBundleBuild(); //创建一个新的AssetBundleBuild对象
string fileName = PathUtil.GetStandardPath(files[i]); //获取标准化后的文件路径
Debug.Log("files:" + fileName); //Log
string assetName = PathUtil.GetUnityPath(fileName); //获取相对于Assets文件夹的路径
assetBundle.assetNames = new string[] { assetName }; //设置assetBundle的资源名称
string bundleName = fileName.Replace(PathUtil.BuildResourcesPath, "").ToLower();
assetBundle.assetBundleName = bundleName + ".ab"; //设置assetBundle的名称
//将AssetBundleBuild对象加入打包列表
assetBundleBuilds.Add(assetBundle);
//添加文件和依赖信息
List<string> dependenceInfo = GetDependence(assetName);
string bundleInfo = assetName + "|" + bundleName + ".ab";
if (dependenceInfo.Count > 0)
bundleInfo = bundleInfo + "|" + string.Join("|", dependenceInfo);
bundleInfos.Add(bundleInfo);
}
//检查并初始化输出文件夹
if (Directory.Exists(PathUtil.BundleOutPath))
Directory.Delete(PathUtil.BundleOutPath, true);
Directory.CreateDirectory(PathUtil.BundleOutPath);
//构建AssetBundles
BuildPipeline.BuildAssetBundles(PathUtil.BundleOutPath, assetBundleBuilds.ToArray(), BuildAssetBundleOptions.None, target);
File.WriteAllLines(PathUtil.BundleOutPath + "/" + AppConst.FileListName, bundleInfos);
AssetDatabase.Refresh();
}
cs
static List<string> GetDependence(string curFile)
{
List<string> dependence = new List<string>();
string[] files = AssetDatabase.GetDependencies(curFile);
dependence = files.Where(file => !file.EndsWith(".cs") && !file.Equals(curFile)).ToList();
return dependence;
}
运行时脚本------加载和使用AB包
AssetBundle
用于在运行时加载和管理预先打包的资源
常用方法:
AssetBundle.LoadFromFile:从本地文件系统中同步加载
cs
public static AssetBundle LoadFromFile(string path);
public static AssetBundle LoadFromFile(string path, uint crc);
public static AssetBundle LoadFromFile(string path, uint crc, ulong offset);
参数:
· path: AssetBundle 文件的路径。
· crc(可选): 用于校验的 CRC 值。
· offset(可选): 文件偏移量。
返回值:
· 加载的 AssetBundle 实例。
AssetBundle.LoadFromFileaAsync:从本地文件系统异步加载
cs
public static AssetBundleCreateRequest LoadFromFileAsync(string path);
public static AssetBundleCreateRequest LoadFromFileAsync(string path, uint crc);
public static AssetBundleCreateRequest LoadFromFileAsync(string path, uint crc, ulong offset);
参数:
· path: AssetBundle 文件的路径。
· crc(可选): 用于校验的 CRC 值。
· offset(可选): 文件偏移量。
返回值:
· AssetBundleCreateRequest,表示异步加载操作的请求。
AssetBundle.LoadAssetAsync:从已加载的AssetBundle中异步加载指定类型的资源
cs
public AssetBundleRequest LoadAssetAsync<T>(string name) where T : UnityEngine.Object;
public AssetBundleRequest LoadAssetAsync(string name, Type type);
参数:
· name: 资源名称。
· type: 资源类型。
返回值:
· AssetBundleRequest,表示异步加载操作的请求。
AssetBundle.Unload:卸载已经加载的AssetBundle
cs
public void Unload(bool unloadAllLoadedObjects);
参数:
unloadAllLoadedObject:是否卸载所有已加载的资源对象