源码-资源收集模块(AssetBundleCollector)
篇章 :04-源码深度-编辑器模块 阅读时间 :约 30 分钟 前置知识:了解 Editor 端整体架构
一、引言
本章将深入解析 YooAsset 资源收集模块(AssetBundleCollector)的源码实现。AssetBundleCollector 是 YooAsset 编辑器端的核心模块,负责资源的收集、分类和寻址配置。深入理解 AssetBundleCollector 的实现,是掌握 YooAsset 资源管理的基础。
AssetBundleCollector 采用了 Package/Group/Collector 的三级层级结构,提供了灵活的资源组织方式和强大的寻址能力。本章将从源码层面深入解析 AssetBundleCollector 的实现。
二、Package / Group / Collector 层级
2.1 三级层级结构
YooAsset 采用了 Package/Group/Collector 的三级层级结构来组织资源:
sql
三级层级结构
├── Package(资源包)
│ ├── PackageName
│ ├── PackageVersion
│ └── 包含多个 Group
├── Group(资源分组)
│ ├── GroupName
│ ├── GroupDesc
│ └── 包含多个 Collector
└── Collector(资源收集器)
├── CollectPath
├── CollectorType
└── 寻址配置
Package 详解:
Package 是 YooAsset 资源管理的最高层级,代表一个完整的资源包。每个 Package 有自己的名称、版本和清单(Manifest),可以独立打包、更新和加载。
Group 详解:
Group 是 Package 下的分组,将相关的 Collector 组织在一起。Group 用于对资源进行逻辑分组,便于管理。
Collector 详解:
Collector 是最细粒度的资源收集器,定义了具体的资源收集路径和规则。每个 Collector 对应一个或多个资源的收集。
2.2 Package 类实现
Package 类的实现位于 YooAsset/Editor/AssetBundleCollector/AssetBundlePackage.cs:
csharp
public class AssetBundlePackage
{
public string PackageName;
public string PackageVersion;
public string PackageDesc;
public List<AssetBundleCollectorGroup> Groups = new List<AssetBundleCollectorGroup>();
}
PackageName 详解:
PackageName 是 Package 的唯一标识符,运行时通过 PackageName 加载 Package。
PackageVersion 详解:
PackageVersion 是 Package 的版本号,用于热更新时的版本比较。
PackageDesc 详解:
PackageDesc 是 Package 的描述信息,便于开发者理解 Package 的用途。
Groups 详解:
Groups 是 Package 下的所有 Group。每个 Group 包含多个 Collector。
2.3 Group 类实现
Group 类的实现位于 YooAsset/Editor/AssetBundleCollector/AssetBundleCollectorGroup.cs:
csharp
public class AssetBundleCollectorGroup
{
public string GroupName;
public string GroupDesc;
public EGroupPackRuleType PackRuleType = EGroupPackRuleType.CollectorPack;
public AssetBundleCollectorGroupStrategy Strategy;
public List<AssetBundleCollector> Collectors = new List<AssetBundleCollector>();
}
GroupName 详解:
GroupName 是 Group 的唯一标识符,用于在 Package 内唯一标识一个 Group。
PackRuleType 详解:
PackRuleType 决定了 Group 的打包规则:
- CollectorPack:每个 Collector 单独打包
- GroupPack:Group 内所有 Collector 合并打包
- TopDirectoryPack:按顶级目录打包
Strategy 详解:
Strategy 是 Group 的策略,包含了 Group 的高级配置。
Collectors 详解:
Collectors 是 Group 下的所有 Collector。
2.4 Collector 类实现
Collector 类的实现位于 YooAsset/Editor/AssetBundleCollector/AssetBundleCollector.cs:
csharp
public class AssetBundleCollector
{
public ECollectorType CollectorType;
public string CollectPath;
public EAddressRule AddressRule;
public string Address;
public List<string> AssetTags;
public List<IAssetBundleCollectorRule> Rules = new List<IAssetBundleCollectorRule>();
public string UserData;
}
CollectorType 详解:
CollectorType 决定 Collector 的类型:
- MainAssetCollector:主资源收集器
- StaticAssetCollector:静态资源收集器
- DependAssetCollector:依赖资源收集器
CollectPath 详解:
CollectPath 是 Collector 的资源收集路径,可以是文件夹或单个文件。
AddressRule 详解:
AddressRule 决定资源的寻址方式。
Address 详解:
Address 是 Collector 的自定义地址前缀。
Rules 详解:
Rules 是 Collector 的规则列表,包含了过滤规则和打包规则。
三、收集器工作流程
3.1 收集器初始化
收集器的初始化过程如下:
markdown
收集器初始化
1. 加载 PackageScriptableObject
2. 解析 PackageScriptableObject
3. 创建 AssetBundlePackage 对象
4. 创建 AssetBundleCollectorGroup 对象
5. 创建 AssetBundleCollector 对象
6. 准备收集
PackageScriptableObject 详解:
PackageScriptableObject 是 Collector 配置的 ScriptableObject 形式,存储在项目 Asset 目录中。
配置加载详解:
配置加载时需要先读取 ScriptableObject,然后反序列化为内存对象。
3.2 资源扫描
资源扫描是 Collector 的核心工作:
csharp
public class AssetBundleCollector
{
public List<CollectAssetInfo> Scan()
{
List<CollectAssetInfo> result = new List<CollectAssetInfo>();
if (CollectorType == ECollectorType.MainAssetCollector)
{
// 扫描主资源
string[] files = Directory.GetFiles(CollectPath, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
if (IsValidAsset(file))
{
result.Add(CreateCollectAssetInfo(file));
}
}
}
else if (CollectorType == ECollectorType.DependAssetCollector)
{
// 扫描依赖资源
// ...
}
return result;
}
}
主资源扫描详解:
主资源扫描会递归扫描 CollectPath 下的所有资源,并根据 IsValidAsset 方法判断资源是否有效。
依赖资源扫描详解:
依赖资源扫描会分析主资源的依赖关系,提取所有依赖资源。
有效性判断详解:
IsValidAsset 方法会根据过滤规则判断资源是否有效。
3.3 资源过滤
资源过滤是 Collector 的重要工作。YooAsset 提供了多种过滤规则:
文件扩展名过滤:
csharp
public class FileExtensionFilter : IAssetBundleCollectorRule
{
public string[] Extensions;
public bool IsMatch(string assetPath)
{
string ext = Path.GetExtension(assetPath);
return Extensions.Contains(ext);
}
}
目录路径过滤:
csharp
public class DirectoryFilter : IAssetBundleCollectorRule
{
public string[] ExcludeDirectories;
public bool IsMatch(string assetPath)
{
foreach (var dir in ExcludeDirectories)
{
if (assetPath.StartsWith(dir)) return false;
}
return true;
}
}
文件名前缀过滤:
csharp
public class FileNamePrefixFilter : IAssetBundleCollectorRule
{
public string[] Prefixes;
public bool IsMatch(string assetPath)
{
string fileName = Path.GetFileName(assetPath);
foreach (var prefix in Prefixes)
{
if (fileName.StartsWith(prefix)) return true;
}
return false;
}
}
四、寻址规则实现
4.1 String Address 寻址
String Address 是最常用的寻址方式:
csharp
public class StringAddress
{
public static string GetAddress(string assetPath, AssetBundleCollector collector)
{
string address = string.Empty;
if (!string.IsNullOrEmpty(collector.Address))
{
// 使用自定义地址
address = collector.Address + "/" + Path.GetFileNameWithoutExtension(assetPath);
}
else
{
// 使用资源相对路径
string relativePath = assetPath.Substring(collector.CollectPath.Length);
address = relativePath.Replace("\\", "/").TrimStart('/');
}
return address;
}
}
自定义地址详解:
自定义地址使用 Collector 的 Address 作为前缀,加上文件名生成资源地址。
相对路径地址详解:
相对路径地址使用资源相对路径作为地址,去除扩展名。
4.2 GUID Address 寻址
GUID Address 使用资源的 GUID 作为地址:
csharp
public class GuidAddress
{
public static string GetAddress(string assetPath)
{
string guid = AssetDatabase.AssetPathToGUID(assetPath);
return guid;
}
}
GUID 详解:
GUID 是 Unity 为每个资源生成的唯一标识符。使用 GUID 作为地址可以避免地址冲突。
GUID 寻址的优缺点:
- 优点:唯一、不冲突
- 缺点:不可读、难以调试
4.3 Label Address 寻址
Label Address 使用资源的 Tag 作为寻址方式:
csharp
public class LabelAddress
{
public static List<string> GetAddresses(List<string> assetTags)
{
return assetTags;
}
}
Tag 详解:
每个资源可以打多个 Tag。通过 Tag 可以批量访问资源。
Label 寻址的优缺点:
- 优点:批量访问、灵活
- 缺点:需要额外配置
4.4 寻址规则的选择
不同的寻址规则适用于不同的场景:
| 寻址规则 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| String Address | 一般资源 | 易读、易记 | 可能冲突 |
| GUID Address | 重要资源 | 唯一、不冲突 | 不可读 |
| Label Address | 批量资源 | 灵活、批量 | 需要配置 |
选择建议:
- 一般资源:使用 String Address
- 重要资源:使用 GUID Address
- 需要批量访问的资源:使用 Label Address
五、Collector 配置序列化
5.1 序列化为 ScriptableObject
Collector 配置通常存储在 ScriptableObject 中:
csharp
[CreateAssetMenu(fileName = "AssetBundlePackageConfig", menuName = "YooAsset/Package Config")]
public class AssetBundlePackageConfig : ScriptableObject
{
public string PackageName;
public string PackageVersion;
public string PackageDesc;
public List<AssetBundleCollectorGroupConfig> Groups = new List<AssetBundleCollectorGroupConfig>();
}
ScriptableObject 详解:
ScriptableObject 是 Unity 提供的配置存储方式,可以在 Unity Editor 中编辑。
配置结构详解:
配置结构与运行时对象结构对应,便于序列化和反序列化。
5.2 序列化为 JSON
除了 ScriptableObject,Collector 配置也可以序列化为 JSON:
csharp
public class AssetBundlePackageConfig
{
public string ToJson()
{
return JsonUtility.ToJson(this, true);
}
public static AssetBundlePackageConfig FromJson(string json)
{
return JsonUtility.FromJson<AssetBundlePackageConfig>(json);
}
}
JSON 序列化的优势:
- 跨平台:JSON 可以在不同平台之间传输
- 易于管理:可以使用版本控制管理 JSON 文件
- 自动化:可以自动生成 JSON 配置
5.3 配置的版本管理
Collector 配置需要版本管理:
配置迁移:
当 YooAsset 升级时,配置可能需要迁移以适配新版本。
配置兼容性:
新版本的 YooAsset 应该能加载旧版本的配置。
配置升级:
提供配置升级工具,自动升级旧版本配置到新版本。
六、Collector 高级特性
6.1 自定义打包规则
开发者可以自定义打包规则:
csharp
public interface IAssetBundleCollectorRule
{
bool IsMatch(string assetPath);
string GetBundleName(string assetPath, AssetBundleCollector collector);
}
自定义打包规则示例:
csharp
public class CustomPackRule : IAssetBundleCollectorRule
{
public bool IsMatch(string assetPath) => true;
public string GetBundleName(string assetPath, AssetBundleCollector collector)
{
return $"custom_{Path.GetFileNameWithoutExtension(assetPath)}";
}
}
6.2 资源标签
资源可以打标签,便于分类管理:
csharp
public class AssetBundleCollector
{
public List<string> AssetTags;
}
标签的使用:
标签可以用于:
- 分类管理:按标签分类资源
- 批量加载:通过标签批量加载资源
- 资源筛选:按标签筛选资源
6.3 用户数据
Collector 支持用户自定义数据:
csharp
public class AssetBundleCollector
{
public string UserData;
}
用户数据的作用:
- 扩展 Collector 的功能
- 存储自定义信息
- 配合自定义规则使用
七、总结
本章深入解析了 YooAsset 资源收集模块(AssetBundleCollector)的源码实现,包括:
- 三级层级结构:Package、Group、Collector 的实现
- 收集器工作流程:初始化、扫描、过滤的实现
- 寻址规则实现:String、GUID、Label 三种寻址方式
- 配置序列化:ScriptableObject 和 JSON 两种序列化方式
- 高级特性:自定义规则、资源标签、用户数据
通过深入理解 AssetBundleCollector 的源码实现,开发者可以更好地使用和扩展 YooAsset 的资源收集功能。
上一篇 :源码-编辑器总览 下一篇 :构建映射与依赖分析(BuildMap)