YooAsset源码阅读-Download
继续 YooAsset 的下载系统代码研究,本文将详细介绍如何创建下载器相关代码
CreateResourceDownloaderByAll
关键类
- PlayModeImpl.cs
- ResourceDownloaderOperation.cs
- DownloaderOperation.cs
- BundleInfo.cs
CreateResourceDownloaderByAll 方法用于创建下载所有需要更新资源的下载器。
关键源代码
1 | |
流程图
flowchart TD
A["CreateResourceDownloaderByAll"] -->|调用| B["GetDownloadListByAll"]
B -->|遍历| C["manifest.BundleList"]
C -->|每个Bundle| D["GetBelongFileSystem"]
D -->|检查| E["fileSystem.NeedDownload"]
E -->|是| F["创建BundleInfo"]
E -->|否| G["跳过该Bundle"]
F --> H["添加到下载列表"]
G --> I["继续下一个Bundle"]
H --> I
I -->|所有Bundle处理完| J["返回下载列表"]
J --> K["创建ResourceDownloaderOperation"]
K --> L["返回下载器"]
%% 样式定义
style A fill:#ff6b6b,stroke:#ffffff,stroke-width:2px,color:#ffffff
style B fill:#4ecdc4,stroke:#ffffff,stroke-width:2px,color:#000000
style C fill:#45b7d1,stroke:#ffffff,stroke-width:2px,color:#ffffff
style D fill:#f9ca24,stroke:#ffffff,stroke-width:2px,color:#000000
style E fill:#6c5ce7,stroke:#ffffff,stroke-width:2px,color:#ffffff
style F fill:#a29bfe,stroke:#ffffff,stroke-width:2px,color:#ffffff
style G fill:#fd79a8,stroke:#ffffff,stroke-width:2px,color:#ffffff
style H fill:#00d2d3,stroke:#ffffff,stroke-width:2px,color:#ffffff
style I fill:#ff9ff3,stroke:#ffffff,stroke-width:2px,color:#000000
style J fill:#00aaff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style K fill:#ff3838,stroke:#ffffff,stroke-width:2px,color:#ffffff
style L fill:#2ed573,stroke:#ffffff,stroke-width:2px,color:#000000
CreateResourceDownloaderByTags
关键类
- PlayModeImpl.cs
- ResourceDownloaderOperation.cs
- PackageBundle.cs
CreateResourceDownloaderByTags 方法用于创建下载指定标签资源的下载器,支持DLC(可下载内容)场景。
关键源代码
1 | |
流程图
flowchart TD
A["CreateResourceDownloaderByTags"] -->|传入tags数组| B["GetDownloadListByTags"]
B -->|遍历| C["manifest.BundleList"]
C -->|每个Bundle| D["GetBelongFileSystem"]
D -->|检查| E["fileSystem.NeedDownload"]
E -->|否| F["跳过该Bundle"]
E -->|是| G["检查Bundle标签"]
G -->|HasAnyTags = false| H["无标签Bundle
统一下载"]
G -->|HasAnyTags = true| I["检查HasTag匹配"]
I -->|匹配| J["DLC资源
添加到下载列表"]
I -->|不匹配| K["跳过该Bundle"]
H --> L["创建BundleInfo"]
J --> L
L --> M["添加到结果列表"]
F --> N["继续下一个Bundle"]
K --> N
M --> N
N -->|处理完成| O["返回下载列表"]
O --> P["创建ResourceDownloaderOperation"]
%% 样式定义
style A fill:#ff6b6b,stroke:#ffffff,stroke-width:2px,color:#ffffff
style B fill:#4ecdc4,stroke:#ffffff,stroke-width:2px,color:#000000
style C fill:#45b7d1,stroke:#ffffff,stroke-width:2px,color:#ffffff
style D fill:#f9ca24,stroke:#ffffff,stroke-width:2px,color:#000000
style E fill:#6c5ce7,stroke:#ffffff,stroke-width:2px,color:#ffffff
style F fill:#fd79a8,stroke:#ffffff,stroke-width:2px,color:#ffffff
style G fill:#00d2d3,stroke:#ffffff,stroke-width:2px,color:#ffffff
style H fill:#ff9ff3,stroke:#ffffff,stroke-width:2px,color:#000000
style I fill:#00aaff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style J fill:#ff3838,stroke:#ffffff,stroke-width:2px,color:#ffffff
style K fill:#2ed573,stroke:#ffffff,stroke-width:2px,color:#000000
style L fill:#ffa502,stroke:#ffffff,stroke-width:2px,color:#000000
style M fill:#a29bfe,stroke:#ffffff,stroke-width:2px,color:#ffffff
style N fill:#74b9ff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style O fill:#e17055,stroke:#ffffff,stroke-width:2px,color:#ffffff
style P fill:#81ecec,stroke:#ffffff,stroke-width:2px,color:#000000
CreateResourceDownloaderByPaths
关键类
- PlayModeImpl.cs
- ResourceDownloaderOperation.cs
- AssetInfo.cs
- PackageManifest.cs
CreateResourceDownloaderByPaths 方法用于创建下载指定资源路径及其依赖的下载器,支持递归下载选项。
关键源代码
1 | |
流程图
flowchart TD
A["CreateResourceDownloaderByPaths"] -->|AssetInfo数组| B["GetDownloadListByPaths"]
B -->|遍历| C["AssetInfo数组"]
C -->|每个AssetInfo| D{AssetInfo.IsInvalid?}
D -->|是| E["记录警告
跳过该资源"]
D -->|否| F["获取主资源包"]
F --> G["添加到checkList"]
G --> H["获取依赖资源包"]
H --> I["添加依赖到checkList"]
I --> J{recursiveDownload?}
J -->|否| K["处理下一个AssetInfo"]
J -->|是| L["递归处理主资源包内
所有资源的依赖"]
L --> M["获取其他主资源包"]
M --> N["获取其他依赖资源包"]
N --> O["添加到checkList"]
O --> K
E --> K
K -->|所有AssetInfo处理完| P["遍历checkList"]
P -->|每个PackageBundle| Q["GetBelongFileSystem"]
Q --> R{fileSystem.NeedDownload?}
R -->|是| S["创建BundleInfo
添加到结果"]
R -->|否| T["跳过该Bundle"]
S --> U["继续下一个Bundle"]
T --> U
U -->|处理完成| V["返回下载列表"]
V --> W["创建ResourceDownloaderOperation"]
%% 样式定义
style A fill:#ff6b6b,stroke:#ffffff,stroke-width:2px,color:#ffffff
style B fill:#4ecdc4,stroke:#ffffff,stroke-width:2px,color:#000000
style C fill:#45b7d1,stroke:#ffffff,stroke-width:2px,color:#ffffff
style D fill:#f9ca24,stroke:#ffffff,stroke-width:2px,color:#000000
style E fill:#fd79a8,stroke:#ffffff,stroke-width:2px,color:#ffffff
style F fill:#6c5ce7,stroke:#ffffff,stroke-width:2px,color:#ffffff
style G fill:#a29bfe,stroke:#ffffff,stroke-width:2px,color:#ffffff
style H fill:#00d2d3,stroke:#ffffff,stroke-width:2px,color:#ffffff
style I fill:#ff9ff3,stroke:#ffffff,stroke-width:2px,color:#000000
style J fill:#00aaff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style K fill:#ff3838,stroke:#ffffff,stroke-width:2px,color:#ffffff
style L fill:#2ed573,stroke:#ffffff,stroke-width:2px,color:#000000
style M fill:#ffa502,stroke:#ffffff,stroke-width:2px,color:#000000
style N fill:#74b9ff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style O fill:#e17055,stroke:#ffffff,stroke-width:2px,color:#ffffff
style P fill:#81ecec,stroke:#ffffff,stroke-width:2px,color:#000000
style Q fill:#55a3ff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style R fill:#fd79a8,stroke:#ffffff,stroke-width:2px,color:#ffffff
style S fill:#00d2d3,stroke:#ffffff,stroke-width:2px,color:#ffffff
style T fill:#dda0dd,stroke:#ffffff,stroke-width:2px,color:#000000
style U fill:#98fb98,stroke:#ffffff,stroke-width:2px,color:#000000
style V fill:#ffd700,stroke:#ffffff,stroke-width:2px,color:#000000
style W fill:#ff69b4,stroke:#ffffff,stroke-width:2px,color:#ffffff
下载器核心机制
ResourceDownloaderOperation 继承关系
flowchart LR
AsyncOperationBase["AsyncOperationBase
异步操作基类"]
DownloaderOperation["DownloaderOperation
下载器操作基类"]
ResourceDownloaderOperation["ResourceDownloaderOperation
资源下载器"]
ResourceUnpackerOperation["ResourceUnpackerOperation
资源解压器"]
ResourceImporterOperation["ResourceImporterOperation
资源导入器"]
AsyncOperationBase -.->|继承| DownloaderOperation
DownloaderOperation -.->|继承| ResourceDownloaderOperation
DownloaderOperation -.->|继承| ResourceUnpackerOperation
DownloaderOperation -.->|继承| ResourceImporterOperation
%% 样式定义
style AsyncOperationBase fill:#00aaff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style DownloaderOperation fill:#ff6600,stroke:#ffffff,stroke-width:2px,color:#ffffff
style ResourceDownloaderOperation fill:#00ff88,stroke:#ffffff,stroke-width:2px,color:#000000
style ResourceUnpackerOperation fill:#ff4444,stroke:#ffffff,stroke-width:2px,color:#ffffff
style ResourceImporterOperation fill:#44ff44,stroke:#ffffff,stroke-width:2px,color:#000000
下载器状态机
flowchart TD
A["DownloaderOperation.BeginDownload
外部使用"] -->|InternalStart| B["Check"]
B -->|验证下载列表| C{下载列表有效?}
C -->|无效| D["Done
Status=Failed"]
C -->|有效| E["Loading"]
E -->|创建下载器| F["动态管理下载器池"]
F -->|检查下载结果| G{有失败的下载?}
G -->|有| H["Done
Status=Failed"]
G -->|无| I{所有下载完成?}
I -->|否| J["继续下载"]
I -->|是| K["Done
Status=Succeed"]
J --> F
%% 样式定义
style A fill:#ff6b6b,stroke:#ffffff,stroke-width:2px,color:#ffffff
style B fill:#4ecdc4,stroke:#ffffff,stroke-width:2px,color:#000000
style C fill:#f9ca24,stroke:#ffffff,stroke-width:2px,color:#000000
style D fill:#fd79a8,stroke:#ffffff,stroke-width:2px,color:#ffffff
style E fill:#6c5ce7,stroke:#ffffff,stroke-width:2px,color:#ffffff
style F fill:#a29bfe,stroke:#ffffff,stroke-width:2px,color:#ffffff
style G fill:#00d2d3,stroke:#ffffff,stroke-width:2px,color:#ffffff
style H fill:#ff9ff3,stroke:#ffffff,stroke-width:2px,color:#000000
style I fill:#00aaff,stroke:#ffffff,stroke-width:2px,color:#ffffff
style J fill:#ff3838,stroke:#ffffff,stroke-width:2px,color:#ffffff
style K fill:#2ed573,stroke:#ffffff,stroke-width:2px,color:#000000
下载器池管理机制
DownloaderOperation 采用动态下载器池来优化下载性能,主要特性:
- 最大并发限制:通过
MAX_LOADER_COUNT = 64和_downloadingMaxNumber控制同时下载的文件数量 - 失败重试机制:支持
_failedTryAgain参数控制失败重试次数 - 动态调度:当有下载器完成时,自动从待下载列表中选择新的文件开始下载
- 暂停/恢复:支持
PauseDownload()和ResumeDownload()控制下载状态 - 进度回调:提供详细的下载进度、错误、开始等事件回调
需要注意 DownloaderOperation.InternalUpdate 方法中的关键逻辑:
1 | |
从用户调用到UnityWebRequest的完整调用链
看完上面的分析,我觉得还需要把整个调用链梳理清楚,这样更容易理解整个下载流程。
调用链概述
用户调用下载器到最终发起UnityWebRequest的完整调用链是这样的:
graph TD
A[用户代码] -->|downloader.BeginDownload| B[DownloaderOperation]
B -->|OperationSystem.Update| C[InternalUpdate循环]
C -->|bundleInfo.CreateDownloader| D[BundleInfo]
D -->|_fileSystem.DownloadFileAsync| E[DefaultCacheFileSystem]
E -->|new DownloadPackageBundleOperation| F[DownloadPackageBundleOperation]
F -->|DownloadCenter.DownloadFileAsync| G[DownloadCenterOperation]
G -->|创建具体下载器| H[UnityDownloadFileOperation]
H -->|CreateWebRequest| I[UnityWebFileRequestOperation]
I -->|_webRequest.SendWebRequest| J[UnityWebRequest]
%% 详细步骤说明
K[关键步骤说明]
K --> L[用户调用BeginDownload启动下载]
K --> M[OperationSystem每帧Update驱动]
K --> N[BundleInfo适配不同FileSystem]
K --> O[FileSystem创建具体下载操作]
K --> P[DownloadCenter管理并发控制]
K --> Q[UnityWebRequest执行实际网络请求]
%% 暗色主题样式
style A fill:#ff6b6b,stroke:#ffffff,stroke-width:3px,color:#ffffff
style B fill:#4ecdc4,stroke:#ffffff,stroke-width:3px,color:#000000
style C fill:#45b7d1,stroke:#ffffff,stroke-width:3px,color:#ffffff
style D fill:#f9ca24,stroke:#ffffff,stroke-width:3px,color:#000000
style E fill:#6c5ce7,stroke:#ffffff,stroke-width:3px,color:#ffffff
style F fill:#a29bfe,stroke:#ffffff,stroke-width:3px,color:#ffffff
style G fill:#fd79a8,stroke:#ffffff,stroke-width:3px,color:#ffffff
style H fill:#00d2d3,stroke:#ffffff,stroke-width:3px,color:#ffffff
style I fill:#ff9ff3,stroke:#ffffff,stroke-width:3px,color:#000000
style J fill:#00aaff,stroke:#ffffff,stroke-width:3px,color:#ffffff
style K fill:#2ed573,stroke:#ffffff,stroke-width:3px,color:#000000
style L fill:#ffa502,stroke:#ffffff,stroke-width:3px,color:#000000
style M fill:#74b9ff,stroke:#ffffff,stroke-width:3px,color:#ffffff
style N fill:#e17055,stroke:#ffffff,stroke-width:3px,color:#ffffff
style O fill:#81ecec,stroke:#ffffff,stroke-width:3px,color:#000000
style P fill:#55a3ff,stroke:#ffffff,stroke-width:3px,color:#ffffff
style Q fill:#dda0dd,stroke:#ffffff,stroke-width:3px,color:#000000
关键调用点解析
1. 责任分离设计
- DownloaderOperation:管理下载器池和并发控制
- BundleInfo:适配器,统一不同FileSystem的接口
- DefaultCacheFileSystem:处理URL获取和参数配置
- DownloadPackageBundleOperation:状态机管理,重试逻辑
- DownloadCenter:并发限制和下载器复用
- UnityDownloadFileOperation:Unity网络请求的具体实现
2. 异步调用链
整个调用链是异步的,通过 OperationSystem 的 Update 循环驱动:
1 | |
3. 错误处理和重试
在调用链的每一层都有相应的错误处理:
- DownloaderOperation:失败隔离策略
- DownloadPackageBundleOperation:重试逻辑和超时处理
- UnityWebRequest:网络层错误处理
YooAsset源码阅读-Download
https://lshgame.com/2025/08/25/YooAsset_Code_Reading_Download/