05-04-YooAsset源码-Unity资源定位系统
源码-寻址系统
篇章:05-源码深度-运行时核心模块
阅读时间:约 25 分钟
前置知识:了解 ResourcePackage
一、引言
本章将深入解析 YooAsset 寻址系统的源码实现。寻址系统是 YooAsset 资源管理的核心,通过资源地址(Address)定位资源。YooAsset 支持 String Address、GUID Address、Label Address 三种寻址方式。深入理解寻址系统是掌握 YooAsset 资源定位机制的关键。
寻址系统的设计目标是提供灵活、可靠的资源定位能力。本章将从源码层面深入解析寻址系统的实现。
二、寻址系统概述
2.1 寻址的概念
寻址是通过资源地址(Address)定位资源的过程:
资源地址:
资源地址是资源的唯一标识符,可以是字符串、GUID、Tag 等。
资源定位过程:
- 用户传入资源地址
- YooAsset 在 Manifest 中查找地址
- 找到对应的 AssetInfo
- 根据 AssetInfo 加载资源
2.2 寻址方式
YooAsset 支持三种寻址方式:
| 寻址方式 | 地址形式 | 优点 | 缺点 |
|---|---|---|---|
| String Address | 字符串,如 "ui/login" | 易读、易记 | 可能冲突 |
| GUID Address | GUID,如 "a1b2c3d4" | 唯一、不冲突 | 不可读 |
| Label Address | Tag,如 "ui"、"character" | 灵活、批量 | 需要配置 |
2.3 寻址系统的架构
寻址系统架构 ├── AddressRule(寻址规则) │ ├── StringAddress │ ├── GuidAddress │ └── LabelAddress ├── AssetInfo(资源信息) │ ├── Address │ ├── AssetPath │ ├── AssetGUID │ ├── BundleID │ └── DependIDs └── BundleInfo(Bundle 信息) ├── BundleName ├── FileName ├── Dependencies └── ...AddressRule 详解:
AddressRule 定义了不同寻址方式的规则。
AssetInfo 详解:
AssetInfo 是资源的信息类,包含了资源的所有元信息。
BundleInfo 详解:
BundleInfo 是 Bundle 的信息类,包含了 Bundle 的所有元信息。
三、String Address 寻址
3.1 String Address 的概念
String Address 是最常用的寻址方式,使用字符串作为资源地址:
地址形式:
字符串地址,类似于ui/login、characters/hero。
地址生成:
地址在构建时生成,可以基于资源路径或自定义前缀生成。
地址示例:
"ui/login" // UI 登录面板 "characters/hero" // 角色:英雄 "weapons/sword" // 武器:剑3.2 String Address 的实现
public class AssetInfo { public string Address { get; set; } // 资源地址 public string AssetPath { get; set; } // 资源路径 public int BundleID { get; set; } // 所属 Bundle ID public int[] DependIDs { get; set; } // 依赖的 Bundle ID }Address 字段详解:
Address 是资源的地址字符串,运行时通过此地址定位资源。
AssetPath 字段详解:
AssetPath 是资源在 Asset 目录中的路径。
BundleID 字段详解:
BundleID 是资源所属 Bundle 的 ID,通过 BundleID 可以快速定位 Bundle。
3.3 字符串地址的解析
public class ResourcePackage { public AssetInfo GetAssetInfo(string location) { // 1. 直接在 AssetList 中查找 foreach (var asset in Manifest.AssetList.Assets) { if (asset.Address == location) return asset; } return null; } }直接查找详解:
字符串地址通过直接匹配查找。这种方式简单但效率较低,对于大量资源需要优化。
优化方案详解:
YooAsset 内部使用 Dictionary 索引,提高查找效率。
private Dictionary<string, AssetInfo> _assetInfoDict; public AssetInfo GetAssetInfo(string location) { if (_assetInfoDict.TryGetValue(location, out var info)) return info; return null; }四、GUID Address 寻址
4.1 GUID Address 的概念
GUID Address 使用 Unity 资源的 GUID 作为地址:
GUID 的概念:
GUID(Globally Unique Identifier)是 Unity 为每个资源生成的唯一标识符。
GUID 的生成:
GUID 在资源导入时由 Unity 自动生成,存储在 .meta 文件中。
GUID 示例:
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"4.2 GUID Address 的实现
public class ResourcePackage { public AssetInfo GetAssetInfoByGUID(string guid) { foreach (var asset in Manifest.AssetList.Assets) { if (asset.AssetGUID == guid) return asset; } return null; } }GUID 查找详解:
GUID 地址通过 AssetGUID 字段查找。GUID 是唯一的,不会有冲突。
GUID 的稳定性详解:
GUID 在资源生命周期内保持稳定,不会因路径变化而变化。
4.3 GUID 的应用场景
资源重命名:
资源重命名后,路径会变化,但 GUID 保持不变。使用 GUID 寻址可以避免资源重命名带来的问题。
资源移动:
资源移动后,路径会变化,但 GUID 保持不变。使用 GUID 寻址可以避免资源移动带来的问题。
资源合并:
合并多个资源时,使用 GUID 寻址可以保持引用关系的稳定。
4.4 GUID 的获取
public class GUIDHelper { public static string GetGUID(string assetPath) { return AssetDatabase.AssetPathToGUID(assetPath); } }AssetDatabase.AssetPathToGUID 详解:
使用 Unity 的 AssetDatabase.AssetPathToGUID API 获取资源的 GUID。
运行时使用详解:
运行时,GUID 存储在 Manifest 中,开发者可以通过地址获取 GUID 并加载资源。
五、Label Address 寻址
5.1 Label Address 的概念
Label Address 使用资源标签(Tag)作为寻址方式:
Tag 的概念:
Tag 是资源的标签,可以用于分类和批量访问。
Tag 的设置:
Tag 在 Collector 中设置,或者在资源导入时设置。
Tag 示例:
"ui" // UI 资源 "character" // 角色资源 "weapon" // 武器资源 "audio/bgm" // 音频:背景音乐5.2 Label Address 的实现
public class AssetInfo { public string[] AssetTags { get; set; } // 资源标签 }AssetTags 字段详解:
AssetTags 是资源的标签数组,每个资源可以有多个标签。
Tag 匹配详解:
通过 Tag 查找资源时,需要遍历所有资源,检查是否包含指定 Tag。
5.3 Label Address 的优化
public class ResourcePackage { private Dictionary<string, List<AssetInfo>> _tagIndex; public void BuildTagIndex() { _tagIndex = new Dictionary<string, List<AssetInfo>>(); foreach (var asset in Manifest.AssetList.Assets) { if (asset.AssetTags == null) continue; foreach (var tag in asset.AssetTags) { if (!_tagIndex.ContainsKey(tag)) _tagIndex[tag] = new List<AssetInfo>(); _tagIndex[tag].Add(asset); } } } public List<AssetInfo> GetAssetsByTag(string tag) { if (_tagIndex.TryGetValue(tag, out var assets)) return assets; return null; } }Tag 索引详解:
YooAsset 内部构建了 Tag 索引,可以快速通过 Tag 查找资源。
批量加载详解:
通过 Tag 查找可以一次获取多个资源,便于批量加载。
5.4 Tag 的应用场景
批量加载:
通过 Tag 批量加载资源,如LoadAssetsByTag("ui")加载所有 UI 资源。
资源分类:
通过 Tag 对资源进行分类管理,便于查找和组织。
动态资源:
通过 Tag 动态加载资源,如根据玩家等级加载不同等级的资源。
六、寻址系统的高级特性
6.1 多地址支持
一个资源可以有多个地址:
[CustomAddress("ui/login_panel")] [CustomAddress("ui/start/login")] public class LoginPanel : MonoBehaviour { // ... }多地址优势详解:
多地址可以让同一资源通过不同地址访问,便于集成不同的系统。
多地址实现详解:
通过自定义特性实现多地址,资源可以被多个地址引用。
6.2 地址重定向
地址重定向允许将一个地址映射到另一个地址:
public class AddressRemapper { private Dictionary<string, string> _remap = new Dictionary<string, string>(); public void AddRemap(string source, string target) { _remap[source] = target; } public string Remap(string address) { if (_remap.TryGetValue(address, out var target)) return target; return address; } }地址重定向的作用详解:
地址重定向可以用于资源迁移、A/B 测试、版本切换等场景。
6.3 地址过滤
地址过滤可以在加载前对地址进行验证:
public class AddressValidator { public bool Validate(string address) { if (string.IsNullOrEmpty(address)) return false; if (address.Length > MaxLength) return false; // 其他验证 return true; } }地址验证的作用详解:
地址验证可以避免非法地址、过长地址等导致的加载失败。
七、Bundle 信息查询
7.1 BundleInfo 详解
BundleInfo 是 Bundle 的信息类:
public class BundleInfo { public int BundleID { get; set; } // Bundle ID public string BundleName { get; set; } // Bundle 名称 public string FileName { get; set; } // Bundle 文件名 public string FileHash { get; set; } // Bundle 文件 Hash public long FileSize { get; set; } // Bundle 文件大小 public string FileCRC { get; set; } // Bundle 文件 CRC public bool Encrypted { get; set; } // 是否加密 public EBundleType BundleType { get; set; } // Bundle 类型 public int[] DependIDs { get; set; } // 依赖的 Bundle ID }BundleID 详解:
BundleID 是 Bundle 的唯一标识符。
FileHash 详解:
FileHash 是 Bundle 文件的 Hash,用于版本管理和完整性验证。
Encrypted 详解:
Encrypted 标识 Bundle 是否加密。
7.2 资源到 Bundle 的映射
public class ResourcePackage { public BundleInfo GetBundleInfo(int bundleID) { foreach (var bundle in Manifest.BundleList.Bundles) { if (bundle.BundleID == bundleID) return bundle; } return null; } }Bundle 查找详解:
通过 BundleID 查找 Bundle。
Bundle 索引优化详解:
使用 Dictionary 索引可以提高查找效率。
八、总结
本章深入解析了 YooAsset 寻址系统的源码实现,包括:
- 寻址系统概述:寻址的概念、方式、架构
- String Address 寻址:字符串地址的实现、解析、优化
- GUID Address 寻址:GUID 地址的概念、实现、应用
- Label Address 寻址:Tag 地址的概念、实现、索引
- 寻址高级特性:多地址支持、地址重定向、地址过滤
- Bundle 信息查询:BundleInfo、资源到 Bundle 的映射
通过深入理解寻址系统的实现,开发者可以更好地使用 YooAsset 的资源定位功能,并根据需要实现自定义的寻址策略。
上一篇:运行模式体系(PlayMode)
下一篇:资源提供者(Provider 体系)
