YooAsset是一款非常实用的Unity资源管理系统,用于帮助研发团队快速部署和交付游戏。
1.下载途径:GitHub – tuyoogame/YooAsset: unity3d resources management system,官网Hello from YooAsset | YooAsset。这里感谢gmhevinci (何冠峰) · GitHub 的开源和分享。
2.操作界面和Setting界面介绍。
目前作者已经更新到了2.3.x版本,但是我的项目一直使用的1.5.x版本,所以以下内容就是关于1.5.x版本的。
导入插件后,在最上方菜单栏可以看到YooAsset,点击显示各个面板:主页、资源包收集器、资源包构建相关、资源包打包报告、资源包运行调试、着色器变体收集器。

1.资源包收集器

首先结合面板说明一下YooAsset对于资源的处理,资源可以分多个包(Package),最左侧就是;每个包可以分多个组(Group),每个组可以有不同的收集器,每个收集器有自己的收集规则,比如类型
- MainAssetCollector 收集参与打包的主资源对象,并写入到资源清单的资源列表里(可以通过代码加载)
- StaticAssetCollector 收集参与打包的主资源对象,但不写入到资源清单的资源列表里(无法通过代码加载)。
- DependAssetCollector 收集参与打包的依赖资源对象,但不写入到资源清单的资源列表里(无法通过代码加载)(当依赖资源没有被任何主资源引用的时候,则会在打包的时候自动剔除)。
打包规则:
- PackSeparately 以文件路径作为资源包名,每个资源文件单独打包。
- PackDirectory 以文件所在的文件夹路径作为资源包名,该文件夹下所有文件打进一个资源包。
- PackTopDirectory 以收集器下顶级文件夹为资源包名,该文件夹下所有文件打进一个资源包。
- PackCollector 以收集器路径作为资源包名,收集的所有文件打进一个资源包。
- PackGroup 以分组名称作为资源包名,收集的所有文件打进一个资源包。
- PackRawFile 目录下的资源文件会被处理为原生资源包。
过滤规则
- CollectAll 收集目录下的所有资源文件
- CollectScene 只收集目录下的场景文件
- CollectPrefab 只收集目录下的预制体文件
- CollectSprite 只收集目录下的精灵类型的文件
以及自定义数据和加资源标签。
举例来说,我在默认包里 加了预制体收集器这个组,用于收集所有用到的UI预制体。又分成两个收集器,2D界面和3D界面。2D界面是MainAssetCollector ,因为需要代码加载,打包成一个资源包。

2.资源包构建相关

分成构建输出目录,构建管线(内置构建管线和可编程构建管线),构建模式(强制模式,增量模式,演练模式,编辑器模拟模式),构建版本,构建的包,构建加密类型,构建压缩方式(不压缩,LZMA模式,LZ4模式),文件名样式(哈希、资源包+哈希),首包资源拷贝方式(不拷贝,清空后拷贝,清空和按标签拷贝,不清空拷贝,不清空按标签拷贝),构建按钮。
3.资源包打包报告

构建后,可以导入构建生成的json文件,查看构建信息:包括基本信息(构建时间、版本、耗时等),资源信息、AB包信息等。
4.资源包运行调试

在游戏运行时,可以查看资源列表信息和资源包信息。
可以用来分析资源泄露,加载、卸载情况。
3.整合打包代码
下面是我自定义整合打包流程的代码
private static void BuildYooBundles(bool isOffline, string version = "", bool IsCopy2Stream = true)
{
BuildParameters buildParameters = new BuildParameters();
buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
EBuildMode eBuildMode = isOffline ? EBuildMode.ForceRebuild : EBuildMode.IncrementalBuild;
buildParameters.BuildMode = eBuildMode;
buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage;
string versionCode = BundleVersion;
if (!string.IsNullOrEmpty(version))
{
versionCode = version;
}
buildParameters.PackageVersion = versionCode;
buildParameters.VerifyBuildingResult = true;
buildParameters.SharedPackRule = new ZeroRedundancySharedPackRule();
buildParameters.EncryptionServices = new GameEncryption();
#if WEIXINMINIGAME
if (BuildPlayerCommand.Platform == BuilderPlatform.WebGL)
buildParameters.EncryptionServices = new EncryptionNone();
#endif
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;
ECopyBuildinFileOption option = ECopyBuildinFileOption.None;
string tag = string.Empty;
buildParameters.CopyBuildinFileOption = option;
buildParameters.CopyBuildinFileTags = tag;
var buildParametersContext = new BuildParametersContext(buildParameters);
var packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
Log($"开始打包 BuildAb:BuildMode [{buildParameters.BuildMode}] CopyBuildinFileOption [{buildParameters.CopyBuildinFileOption}] CopyBuildinFileTags [{buildParameters.CopyBuildinFileTags}]");
if (Directory.Exists(packageOutputDirectory))
{
Log($"本次构建的补丁目录已经存在:{packageOutputDirectory}, 执行删除!");
Directory.Delete(packageOutputDirectory, true);
}
if (AssetBundleBuilderSettingData.Setting.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
buildParameters.SBPParameters.WriteLinkXML = true;
}
var builder = new AssetBundleBuilder();
var buildResult = builder.Run(buildParameters);
if (buildResult.Success)
{
if (IsCopy2Stream)
CopyFilesAsync(buildResult.OutputPackageDirectory);
else
Log($"[{versionCode}]版本 不拷贝到 streamingAssetsPath ");
}
else
{
Log($"AssetBundleBuilder Run error! {buildResult.ErrorInfo}");
throw new Exception($"AssetBundleBuilder Run error! {buildResult.ErrorInfo}");
}
}
public static void CopyFilesAsync(string sourceFolder)
{
string destFolder = XUtility.GetCombinePath(UnityEngine.Application.streamingAssetsPath, StreamingAssetsHelper.RootFolderName, "DefaultPackage");
if (Directory.Exists(destFolder))
{
Directory.Delete(destFolder, true);
}
if (!Directory.Exists(destFolder))
{
Directory.CreateDirectory(destFolder);
}
Log($"sourceFolder {sourceFolder} destFolder{destFolder} ");
//得到原文件根目录下的所有文件
string[] files = System.IO.Directory.GetFiles(sourceFolder);
foreach (string file in files)
{
string name = System.IO.Path.GetFileName(file);
string dest = System.IO.Path.Combine(destFolder, name);
System.IO.File.Copy(file, dest);//复制文件
}
GenerateBuildInFiles();
}