05-04-源码-资源定位系统

源码-寻址系统

篇章 :05-源码深度-运行时核心模块 阅读时间 :约 25 分钟 前置知识:了解 ResourcePackage


一、引言

本章将深入解析 YooAsset 寻址系统的源码实现。寻址系统是 YooAsset 资源管理的核心,通过资源地址(Address)定位资源。YooAsset 支持 String Address、GUID Address、Label Address 三种寻址方式。深入理解寻址系统是掌握 YooAsset 资源定位机制的关键。

寻址系统的设计目标是提供灵活、可靠的资源定位能力。本章将从源码层面深入解析寻址系统的实现。


二、寻址系统概述

2.1 寻址的概念

寻址是通过资源地址(Address)定位资源的过程:

资源地址:

资源地址是资源的唯一标识符,可以是字符串、GUID、Tag 等。

资源定位过程:

  1. 用户传入资源地址
  2. YooAsset 在 Manifest 中查找地址
  3. 找到对应的 AssetInfo
  4. 根据 AssetInfo 加载资源

2.2 寻址方式

YooAsset 支持三种寻址方式:

寻址方式 地址形式 优点 缺点
String Address 字符串,如 "ui/login" 易读、易记 可能冲突
GUID Address GUID,如 "a1b2c3d4" 唯一、不冲突 不可读
Label Address Tag,如 "ui"、"character" 灵活、批量 需要配置

2.3 寻址系统的架构

css 复制代码
寻址系统架构
├── 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。

地址生成:

地址在构建时生成,可以基于资源路径或自定义前缀生成。

地址示例:

csharp 复制代码
"ui/login"        // UI 登录面板
"characters/hero" // 角色:英雄
"weapons/sword"   // 武器:剑

3.2 String Address 的实现

csharp 复制代码
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 字符串地址的解析

csharp 复制代码
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 索引,提高查找效率。

csharp 复制代码
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 示例:

csharp 复制代码
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"

4.2 GUID Address 的实现

csharp 复制代码
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 的获取

csharp 复制代码
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 示例:

csharp 复制代码
"ui"           // UI 资源
"character"    // 角色资源
"weapon"       // 武器资源
"audio/bgm"    // 音频:背景音乐

5.2 Label Address 的实现

csharp 复制代码
public class AssetInfo
{
    public string[] AssetTags { get; set; }  // 资源标签
}

AssetTags 字段详解:

AssetTags 是资源的标签数组,每个资源可以有多个标签。

Tag 匹配详解:

通过 Tag 查找资源时,需要遍历所有资源,检查是否包含指定 Tag。

5.3 Label Address 的优化

csharp 复制代码
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 多地址支持

一个资源可以有多个地址:

csharp 复制代码
[CustomAddress("ui/login_panel")]
[CustomAddress("ui/start/login")]
public class LoginPanel : MonoBehaviour
{
    // ...
}

多地址优势详解:

多地址可以让同一资源通过不同地址访问,便于集成不同的系统。

多地址实现详解:

通过自定义特性实现多地址,资源可以被多个地址引用。

6.2 地址重定向

地址重定向允许将一个地址映射到另一个地址:

csharp 复制代码
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 地址过滤

地址过滤可以在加载前对地址进行验证:

csharp 复制代码
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 的信息类:

csharp 复制代码
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 的映射

csharp 复制代码
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 体系)

相关推荐
Mikko712 小时前
用 Java 复刻了高中时在塞班上玩的「熔岩矿车」:纯 Swing、零依赖、没有一张图片,一个 jar 双击就能玩
java·游戏开发·swing
郝学胜_神的一滴16 小时前
游戏设计:原型与开发 06:读懂游戏设计最容易被忽略的文化层
游戏·游戏开发
SmalBox17 小时前
05-03-源码-运行模式体系(PlayMode)
unity3d·游戏开发
努力小陈12 天前
Redis ZSet 排行榜实战:SLG 后端排行榜的 10 个坑
游戏开发
努力小陈12 天前
SLG 后端最终选了 Actor
游戏开发
努力小陈12 天前
玩家 Actor 的生命周期与阻塞 IO:全局协程池分流实战
游戏开发
SmalBox2 天前
05-02-源码-全局入口与包管理(YooAssets & ResourcePackage)
unity3d·游戏开发
SmalBox3 天前
05-01-源码-运行时总览
unity3d·游戏开发
SmalBox4 天前
04-06-源码-调试与扫描工具
unity3d·游戏开发