mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-25 10:11:51 +00:00
docs : 增加模块的文档说明
This commit is contained in:
@@ -0,0 +1,488 @@
|
||||
# DefaultBuildinFileSystem 内置文件系统
|
||||
|
||||
## 模块概述
|
||||
|
||||
DefaultBuildinFileSystem 是 YooAsset 的**内置资源文件系统**,用于管理打包到应用程序中的资源文件(StreamingAssets)。该文件系统支持 AssetBundle 和原生文件的加载,并内置解压文件系统以处理 Android/OpenHarmony 平台的特殊需求。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **内置资源管理**:管理 StreamingAssets 目录下的资源文件
|
||||
- **Catalog 目录系统**:使用目录文件快速查询内置资源
|
||||
- **自动解压机制**:Android/OpenHarmony 平台自动解压加密和原生文件
|
||||
- **清单拷贝功能**:支持将内置清单拷贝到沙盒目录
|
||||
- **加密资源支持**:通过解密服务接口支持加密资源加载
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **跨平台支持** | 统一处理各平台 StreamingAssets 的访问差异 |
|
||||
| **高效查询** | 通过 Catalog 文件快速判断资源是否内置 |
|
||||
| **自动解压** | 自动处理 Android 平台无法直接访问的资源 |
|
||||
| **灵活配置** | 支持多种参数配置适应不同需求 |
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
DefaultBuildinFileSystem/
|
||||
├── DefaultBuildinFileSystem.cs # 文件系统主类
|
||||
├── DefaultBuildinFileSystemDefine.cs # 常量定义
|
||||
├── DefaultBuildinFileCatalog.cs # 内置资源目录结构
|
||||
├── CatalogDefine.cs # Catalog 文件格式定义
|
||||
├── CatalogTools.cs # Catalog 序列化工具
|
||||
└── Operation/ # 操作类
|
||||
├── DBFSInitializeOperation.cs # 初始化操作
|
||||
├── DBFSRequestPackageVersionOperation.cs # 请求版本操作
|
||||
├── DBFSLoadPackageManifestOperation.cs # 加载清单操作
|
||||
├── DBFSLoadBundleOperation.cs # 加载资源包操作
|
||||
└── internal/ # 内部操作类
|
||||
├── CopyBuildinFileOperation.cs # 拷贝内置文件操作
|
||||
├── LoadBuildinCatalogFileOperation.cs # 加载 Catalog 文件操作
|
||||
├── LoadBuildinPackageManifestOperation.cs# 加载清单文件操作
|
||||
├── RequestBuildinPackageHashOperation.cs # 请求哈希文件操作
|
||||
└── RequestBuildinPackageVersionOperation.cs # 请求版本文件操作
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心类说明
|
||||
|
||||
### DefaultBuildinFileSystem
|
||||
|
||||
内置文件系统的主类,实现 `IFileSystem` 接口。
|
||||
|
||||
#### 基本属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `PackageName` | `string` | 包裹名称 |
|
||||
| `FileRoot` | `string` | 文件根目录(StreamingAssets 下的包裹目录) |
|
||||
| `FileCount` | `int` | 已记录的内置文件数量 |
|
||||
| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 |
|
||||
|
||||
#### 自定义参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `InstallClearMode` | `EOverwriteInstallClearMode` | `ClearAllManifestFiles` | 覆盖安装时的缓存清理模式 |
|
||||
| `FileVerifyLevel` | `EFileVerifyLevel` | `Middle` | 文件校验级别 |
|
||||
| `FileVerifyMaxConcurrency` | `int` | `32` | 文件校验最大并发数 |
|
||||
| `AppendFileExtension` | `bool` | `false` | 是否追加文件扩展名 |
|
||||
| `DisableCatalogFile` | `bool` | `false` | 禁用 Catalog 目录文件 |
|
||||
| `CopyBuildinPackageManifest` | `bool` | `false` | 是否拷贝内置清单到沙盒 |
|
||||
| `CopyBuildinPackageManifestDestRoot` | `string` | `null` | 清单拷贝目标目录 |
|
||||
| `UnpackFileSystemRoot` | `string` | `null` | 解压文件系统根目录 |
|
||||
| `DecryptionServices` | `IDecryptionServices` | `null` | 解密服务接口 |
|
||||
| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单恢复服务接口 |
|
||||
| `CopyLocalFileServices` | `ICopyLocalFileServices` | `null` | 本地文件拷贝服务接口 |
|
||||
|
||||
#### 核心方法
|
||||
|
||||
```csharp
|
||||
// 生命周期
|
||||
void OnCreate(string packageName, string packageRoot);
|
||||
void OnDestroy();
|
||||
void SetParameter(string name, object value);
|
||||
|
||||
// 异步操作
|
||||
FSInitializeFileSystemOperation InitializeFileSystemAsync();
|
||||
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
|
||||
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
|
||||
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
|
||||
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options);
|
||||
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options);
|
||||
|
||||
// 文件查询
|
||||
bool Belong(PackageBundle bundle); // 检查是否属于内置文件
|
||||
bool Exists(PackageBundle bundle); // 检查文件是否存在
|
||||
bool NeedDownload(PackageBundle bundle);// 始终返回 false
|
||||
bool NeedUnpack(PackageBundle bundle); // 检查是否需要解压
|
||||
bool NeedImport(PackageBundle bundle); // 始终返回 false
|
||||
|
||||
// 文件访问
|
||||
string GetBundleFilePath(PackageBundle bundle);
|
||||
byte[] ReadBundleFileData(PackageBundle bundle);
|
||||
string ReadBundleFileText(PackageBundle bundle);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Catalog 目录系统
|
||||
|
||||
### DefaultBuildinFileCatalog
|
||||
|
||||
内置资源目录结构,记录所有内置资源文件的信息。
|
||||
|
||||
```csharp
|
||||
[Serializable]
|
||||
internal class DefaultBuildinFileCatalog
|
||||
{
|
||||
[Serializable]
|
||||
public class FileWrapper
|
||||
{
|
||||
public string BundleGUID; // 资源包 GUID
|
||||
public string FileName; // 文件名
|
||||
}
|
||||
|
||||
public string FileVersion; // 文件版本
|
||||
public string PackageName; // 包裹名称
|
||||
public string PackageVersion; // 包裹版本
|
||||
public List<FileWrapper> Wrappers; // 文件列表
|
||||
}
|
||||
```
|
||||
|
||||
### CatalogDefine
|
||||
|
||||
Catalog 文件格式常量定义。
|
||||
|
||||
```csharp
|
||||
internal class CatalogDefine
|
||||
{
|
||||
public const int FileMaxSize = 104857600; // 文件极限大小(100MB)
|
||||
public const uint FileSign = 0x133C5EE; // 文件头标记
|
||||
public const string FileVersion = "1.0.0"; // 文件格式版本
|
||||
}
|
||||
```
|
||||
|
||||
### CatalogTools
|
||||
|
||||
Catalog 文件的序列化和反序列化工具。
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `CreateCatalogFile()` | 生成包裹的内置资源目录文件(编辑器) |
|
||||
| `CreateEmptyCatalogFile()` | 生成空的内置资源目录文件(编辑器) |
|
||||
| `SerializeToJson()` | 序列化为 JSON 文件 |
|
||||
| `DeserializeFromJson()` | 从 JSON 文件反序列化 |
|
||||
| `SerializeToBinary()` | 序列化为二进制文件 |
|
||||
| `DeserializeFromBinary()` | 从二进制文件反序列化 |
|
||||
|
||||
---
|
||||
|
||||
## 操作类说明
|
||||
|
||||
### DBFSInitializeOperation
|
||||
|
||||
初始化操作,执行以下步骤:
|
||||
|
||||
```
|
||||
状态流程:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ CopyBuildinPackageManifest = true ? │
|
||||
│ │ │
|
||||
│ ├── Yes ──► LoadBuildinPackageVersion │
|
||||
│ │ └── RequestBuildinPackageVersionOp │
|
||||
│ │ ↓ │
|
||||
│ │ CopyBuildinPackageHash │
|
||||
│ │ └── CopyBuildinFileOperation │
|
||||
│ │ ↓ │
|
||||
│ │ CopyBuildinPackageManifest │
|
||||
│ │ └── CopyBuildinFileOperation │
|
||||
│ │ ↓ │
|
||||
│ └── No ─────────────────┘ │
|
||||
│ ↓ │
|
||||
│ InitUnpackFileSystem │
|
||||
│ └── DefaultUnpackFileSystem.Init │
|
||||
│ ↓ │
|
||||
│ DisableCatalogFile = true ? │
|
||||
│ ├── Yes ──► Done (Succeed) │
|
||||
│ └── No ──► LoadCatalogFile │
|
||||
│ └── LoadBuildinCatalog │
|
||||
│ ↓ │
|
||||
│ RecordCatalogFile │
|
||||
│ ↓ │
|
||||
│ Done (Succeed) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### DBFSLoadBundleOperation
|
||||
|
||||
加载资源包操作,支持多种资源类型。
|
||||
|
||||
#### DBFSLoadAssetBundleOperation
|
||||
|
||||
加载 AssetBundle 文件。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadAssetBundle
|
||||
├── 加密资源 ──► DecryptionServices.LoadAssetBundle[Async]
|
||||
└── 普通资源 ──► AssetBundle.LoadFromFile[Async]
|
||||
↓
|
||||
CheckResult
|
||||
├── 成功 ──► AssetBundleResult
|
||||
└── 失败 ──► Error
|
||||
```
|
||||
|
||||
#### DBFSLoadRawBundleOperation
|
||||
|
||||
加载原生文件。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadBuildinRawBundle
|
||||
├── Android 平台 ──► Error(不支持直接读取)
|
||||
└── 其他平台 ──► RawBundleResult
|
||||
```
|
||||
|
||||
#### DBFSLoadInstantBundleOperation
|
||||
|
||||
加载团结引擎(Tuanjie)专用资源包(需要 `TUANJIE_1_7_OR_NEWER` 宏)。
|
||||
|
||||
---
|
||||
|
||||
## 内部操作类
|
||||
|
||||
### LoadBuildinCatalogFileOperation
|
||||
|
||||
加载 Catalog 目录文件。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
TryLoadFileData
|
||||
├── 文件存在 ──► File.ReadAllBytes
|
||||
└── 文件不存在 ──► RequestFileData (UnityWebRequest)
|
||||
↓
|
||||
LoadCatalog
|
||||
└── CatalogTools.DeserializeFromBinary
|
||||
```
|
||||
|
||||
### CopyBuildinFileOperation
|
||||
|
||||
拷贝内置文件到目标路径。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
CheckFileExist
|
||||
├── 目标已存在 ──► Done (Succeed)
|
||||
└── 目标不存在 ──► TryCopyFile
|
||||
↓
|
||||
TryCopyFile
|
||||
├── 源文件存在 ──► File.Copy
|
||||
└── 源文件不存在 ──► UnpackFile (UnityWebRequest)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 解压机制
|
||||
|
||||
### 自动解压条件
|
||||
|
||||
在 Android/OpenHarmony 平台上,以下情况需要解压到沙盒:
|
||||
|
||||
```csharp
|
||||
protected virtual bool IsUnpackBundleFile(PackageBundle bundle)
|
||||
{
|
||||
#if UNITY_ANDROID || UNITY_OPENHARMONY
|
||||
if (bundle.Encrypted) // 加密资源
|
||||
return true;
|
||||
if (bundle.BundleType == RawBundle) // 原生文件
|
||||
return true;
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
```
|
||||
|
||||
### 解压文件系统
|
||||
|
||||
内置文件系统在创建时会自动创建一个 `DefaultUnpackFileSystem` 实例:
|
||||
|
||||
```csharp
|
||||
public virtual void OnCreate(string packageName, string packageRoot)
|
||||
{
|
||||
// 创建解压文件系统
|
||||
var remoteServices = new DefaultUnpackRemoteServices(_packageRoot);
|
||||
_unpackFileSystem = new DefaultUnpackFileSystem();
|
||||
_unpackFileSystem.SetParameter(REMOTE_SERVICES, remoteServices);
|
||||
_unpackFileSystem.SetParameter(FILE_VERIFY_LEVEL, FileVerifyLevel);
|
||||
// ... 其他参数
|
||||
_unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 平台差异处理
|
||||
|
||||
### Android 平台限制
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Android 平台特殊处理 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ StreamingAssets 文件位于 APK 压缩包内,无法直接访问: │
|
||||
│ │
|
||||
│ ✓ AssetBundle.LoadFromFile 支持(Unity 内部处理) │
|
||||
│ ✗ File.ReadAllBytes 不支持 │
|
||||
│ ✗ File.Exists 不支持 │
|
||||
│ ✓ UnityWebRequest 支持(jar:file:// 协议) │
|
||||
│ │
|
||||
│ 解决方案: │
|
||||
│ 1. 加密资源 → 自动解压到沙盒 │
|
||||
│ 2. 原生文件 → 自动解压到沙盒 │
|
||||
│ 3. Catalog → 使用 UnityWebRequest 读取 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### WebGL 平台
|
||||
|
||||
```csharp
|
||||
#if UNITY_WEBGL
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{nameof(DefaultBuildinFileSystem)} is not support WEBGL platform !";
|
||||
#endif
|
||||
```
|
||||
|
||||
WebGL 平台不支持 DefaultBuildinFileSystem,应使用 `DefaultWebServerFileSystem`。
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础配置
|
||||
|
||||
```csharp
|
||||
// 创建内置文件系统参数
|
||||
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||
|
||||
// 初始化包裹
|
||||
var initParams = new OfflinePlayModeParameters();
|
||||
initParams.BuildinFileSystemParameters = buildinParams;
|
||||
var initOp = package.InitializeAsync(initParams);
|
||||
```
|
||||
|
||||
### 配置解密服务
|
||||
|
||||
```csharp
|
||||
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||
|
||||
// 设置解密服务
|
||||
buildinParams.AddParameter(
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES,
|
||||
new MyDecryptionServices()
|
||||
);
|
||||
```
|
||||
|
||||
### 配置清单拷贝
|
||||
|
||||
```csharp
|
||||
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||
|
||||
// 启用清单拷贝(用于离线模式切换到联机模式)
|
||||
buildinParams.AddParameter(
|
||||
FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST,
|
||||
true
|
||||
);
|
||||
|
||||
// 可选:指定拷贝目标目录
|
||||
buildinParams.AddParameter(
|
||||
FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT,
|
||||
"/custom/path"
|
||||
);
|
||||
```
|
||||
|
||||
### 禁用 Catalog 文件
|
||||
|
||||
```csharp
|
||||
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||
|
||||
// 禁用 Catalog(所有资源视为内置)
|
||||
buildinParams.AddParameter(
|
||||
FileSystemParametersDefine.DISABLE_CATALOG_FILE,
|
||||
true
|
||||
);
|
||||
```
|
||||
|
||||
### 配置解压文件系统根目录
|
||||
|
||||
```csharp
|
||||
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
|
||||
|
||||
// 设置解压文件系统的根目录
|
||||
buildinParams.AddParameter(
|
||||
FileSystemParametersDefine.UNPACK_FILE_SYSTEM_ROOT,
|
||||
"/custom/unpack/path"
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数常量
|
||||
|
||||
```csharp
|
||||
// 安装清理
|
||||
FileSystemParametersDefine.INSTALL_CLEAR_MODE // EOverwriteInstallClearMode
|
||||
|
||||
// 文件校验
|
||||
FileSystemParametersDefine.FILE_VERIFY_LEVEL // EFileVerifyLevel
|
||||
FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY // int
|
||||
|
||||
// 文件配置
|
||||
FileSystemParametersDefine.APPEND_FILE_EXTENSION // bool
|
||||
FileSystemParametersDefine.DISABLE_CATALOG_FILE // bool
|
||||
|
||||
// 清单拷贝
|
||||
FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST // bool
|
||||
FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT // string
|
||||
|
||||
// 解压配置
|
||||
FileSystemParametersDefine.UNPACK_FILE_SYSTEM_ROOT // string
|
||||
|
||||
// 服务接口
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES // IDecryptionServices
|
||||
FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices
|
||||
FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES // ICopyLocalFileServices
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
IFileSystem
|
||||
└── DefaultBuildinFileSystem
|
||||
└── (内部持有) DefaultUnpackFileSystem
|
||||
|
||||
FSInitializeFileSystemOperation
|
||||
└── DBFSInitializeOperation
|
||||
|
||||
FSRequestPackageVersionOperation
|
||||
└── DBFSRequestPackageVersionOperation
|
||||
|
||||
FSLoadPackageManifestOperation
|
||||
└── DBFSLoadPackageManifestOperation
|
||||
|
||||
FSLoadBundleOperation
|
||||
├── DBFSLoadAssetBundleOperation
|
||||
├── DBFSLoadRawBundleOperation
|
||||
└── DBFSLoadInstantBundleOperation (Tuanjie)
|
||||
|
||||
AsyncOperationBase
|
||||
├── LoadBuildinCatalogFileOperation
|
||||
├── CopyBuildinFileOperation
|
||||
├── LoadBuildinPackageManifestOperation
|
||||
├── RequestBuildinPackageHashOperation
|
||||
└── RequestBuildinPackageVersionOperation
|
||||
|
||||
BundleResult
|
||||
├── AssetBundleResult ← AssetBundle 资源
|
||||
└── RawBundleResult ← 原生文件
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **WebGL 不支持**:DefaultBuildinFileSystem 不支持 WebGL 平台
|
||||
2. **Android 限制**:Android 平台无法直接读取 StreamingAssets 中的原生文件
|
||||
3. **Catalog 文件**:构建时需要生成 Catalog 文件,否则需要禁用 Catalog 功能
|
||||
4. **解压目录**:解压的文件存储在 `UnpackFileSystemRoot` 指定的目录
|
||||
5. **加密资源**:加密资源在 Android/OpenHarmony 平台会自动解压到沙盒
|
||||
6. **清单拷贝**:启用清单拷贝可以支持从离线模式平滑切换到联机模式
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ec531875d1515b4496e0e9035e63661
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,791 @@
|
||||
# DefaultCacheFileSystem 缓存文件系统
|
||||
|
||||
## 模块概述
|
||||
|
||||
DefaultCacheFileSystem 是 YooAsset 的**缓存文件系统**,负责管理从远程服务器下载并缓存到本地沙盒的资源文件。该文件系统是联机运行模式(HostPlayMode)的核心组件,提供完整的下载、验证、缓存和加载功能。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **智能缓存管理**:基于 GUID 的文件索引,支持增量更新
|
||||
- **断点续传**:大文件下载支持从断点继续
|
||||
- **多线程验证**:后台线程验证文件完整性,不阻塞主线程
|
||||
- **并发下载**:可配置的下载并发数和请求速率
|
||||
- **覆盖安装检测**:App 版本变更时自动清理过期缓存
|
||||
- **加密支持**:支持加密资源包的解密加载
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **高性能** | 多线程验证、并发下载、路径缓存优化 |
|
||||
| **高可靠** | CRC/Hash 验证、损坏文件自动清理、加载失败重试 |
|
||||
| **可扩展** | 支持自定义解密服务、远程服务、本地拷贝服务 |
|
||||
| **易配置** | 丰富的参数配置,适应不同网络环境 |
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
DefaultCacheFileSystem/
|
||||
├── DefaultCacheFileSystem.cs # 文件系统主类
|
||||
├── DefaultCacheFileSystemDefine.cs # 常量定义
|
||||
├── EOverwriteInstallClearMode.cs # 覆盖安装清理模式枚举
|
||||
├── ApplicationFootPrint.cs # 应用版本足迹
|
||||
├── Elements/ # 元素类
|
||||
│ ├── RecordFileElement.cs # 缓存文件记录元素
|
||||
│ ├── TempFileElement.cs # 临时文件元素
|
||||
│ └── VerifyFileElement.cs # 验证文件元素
|
||||
└── Operation/ # 操作类
|
||||
├── DCFSInitializeOperation.cs # 初始化操作
|
||||
├── DCFSRequestPackageVersionOperation.cs # 请求版本操作
|
||||
├── DCFSLoadPackageManifestOperation.cs # 加载清单操作
|
||||
├── DCFSLoadBundleOperation.cs # 加载资源包操作
|
||||
└── internal/ # 内部操作类
|
||||
├── SearchCacheFilesOperation.cs # 搜索缓存文件
|
||||
├── VerifyCacheFilesOperation.cs # 验证缓存文件
|
||||
├── VerifyTempFileOperation.cs # 验证临时文件
|
||||
├── DownloadPackageHashOperation.cs # 下载哈希文件
|
||||
├── DownloadPackageManifestOperation.cs # 下载清单文件
|
||||
├── DownloadPackageBundleOperation.cs # 下载资源包
|
||||
├── LoadCachePackageHashOperation.cs # 加载缓存哈希
|
||||
├── LoadCachePackageManifestOperation.cs # 加载缓存清单
|
||||
├── ClearAllCacheBundleFilesOperation.cs # 清理所有缓存
|
||||
├── ClearUnusedCacheBundleFilesOperation.cs # 清理未使用缓存
|
||||
├── ClearCacheBundleFilesByTagsOperaiton.cs # 按标签清理
|
||||
├── ClearCacheBundleFilesByLocationsOperaiton.cs # 按位置清理
|
||||
├── ClearAllCacheManifestFilesOperation.cs # 清理所有清单
|
||||
├── ClearUnusedCacheManifestFilesOperation.cs # 清理未使用清单
|
||||
└── Scheduler/ # 下载调度器
|
||||
├── DownloadSchedulerOperation.cs # 下载调度器
|
||||
├── DownloadAndCacheFileOperation.cs # 下载并缓存基类
|
||||
├── DownloadAndCacheRemoteFileOperation.cs # 远程文件下载
|
||||
└── DownloadAndCacheLocalFileOperation.cs # 本地文件拷贝
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心类说明
|
||||
|
||||
### DefaultCacheFileSystem
|
||||
|
||||
缓存文件系统的主类,实现 `IFileSystem` 接口。
|
||||
|
||||
#### 基本属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `PackageName` | `string` | 包裹名称 |
|
||||
| `FileRoot` | `string` | 缓存根目录 |
|
||||
| `FileCount` | `int` | 已缓存文件数量 |
|
||||
| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 |
|
||||
| `DownloadScheduler` | `DownloadSchedulerOperation` | 下载调度器 |
|
||||
|
||||
#### 自定义参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `RemoteServices` | `IRemoteServices` | - | 远程服务接口(必需) |
|
||||
| `InstallClearMode` | `EOverwriteInstallClearMode` | `ClearAllManifestFiles` | 覆盖安装缓存清理模式 |
|
||||
| `FileVerifyLevel` | `EFileVerifyLevel` | `Middle` | 初始化时文件校验级别 |
|
||||
| `FileVerifyMaxConcurrency` | `int` | `32` | 文件校验最大并发数(1-256) |
|
||||
| `AppendFileExtension` | `bool` | `false` | 数据文件追加文件扩展名 |
|
||||
| `DisableOnDemandDownload` | `bool` | `false` | 禁用边玩边下机制 |
|
||||
| `DownloadMaxConcurrency` | `int` | `10` | 最大并发下载数(1-64) |
|
||||
| `DownloadMaxRequestPerFrame` | `int` | `5` | 每帧最大请求数(1-20) |
|
||||
| `DownloadWatchDogTime` | `int` | `0` | 下载看门狗超时时间(秒) |
|
||||
| `ResumeDownloadMinimumSize` | `long` | `long.MaxValue` | 启用断点续传的最小文件大小 |
|
||||
| `ResumeDownloadResponseCodes` | `List<long>` | `null` | 断点续传关注的HTTP错误码 |
|
||||
| `DecryptionServices` | `IDecryptionServices` | `null` | 解密服务接口 |
|
||||
| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单服务接口 |
|
||||
| `CopyLocalFileServices` | `ICopyLocalFileServices` | `null` | 本地文件拷贝服务 |
|
||||
|
||||
#### 核心方法
|
||||
|
||||
```csharp
|
||||
// 生命周期
|
||||
void OnCreate(string packageName, string packageRoot);
|
||||
void OnDestroy();
|
||||
void SetParameter(string name, object value);
|
||||
|
||||
// 异步操作
|
||||
FSInitializeFileSystemOperation InitializeFileSystemAsync();
|
||||
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
|
||||
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
|
||||
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
|
||||
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options);
|
||||
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options);
|
||||
|
||||
// 文件查询
|
||||
bool Belong(PackageBundle bundle); // 始终返回 true(保底加载)
|
||||
bool Exists(PackageBundle bundle); // 检查文件是否已缓存
|
||||
bool NeedDownload(PackageBundle bundle); // 检查是否需要下载
|
||||
bool NeedUnpack(PackageBundle bundle); // 始终返回 false
|
||||
bool NeedImport(PackageBundle bundle); // 检查是否需要导入
|
||||
|
||||
// 文件访问
|
||||
string GetBundleFilePath(PackageBundle bundle);
|
||||
byte[] ReadBundleFileData(PackageBundle bundle);
|
||||
string ReadBundleFileText(PackageBundle bundle);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 缓存目录结构
|
||||
|
||||
```
|
||||
{CacheRoot}/{PackageName}/
|
||||
├── BundleFiles/ # 资源包文件目录
|
||||
│ ├── {Hash[0:2]}/ # 哈希前两位分组(256个目录)
|
||||
│ │ ├── {BundleGUID}/ # 资源包 GUID 目录
|
||||
│ │ │ ├── __data # 数据文件(或 __data.bundle)
|
||||
│ │ │ └── __info # 信息文件(CRC + Size)
|
||||
│ │ └── ...
|
||||
│ └── ...
|
||||
├── ManifestFiles/ # 清单文件目录
|
||||
│ ├── {PackageName}_{Version}.bytes # 清单二进制文件
|
||||
│ ├── {PackageName}_{Version}.hash # 清单哈希文件
|
||||
│ └── __app_footprint.txt # 应用版本足迹文件
|
||||
└── TempFiles/ # 临时文件目录
|
||||
├── {BundleGUID} # 下载中的临时文件
|
||||
└── ...
|
||||
```
|
||||
|
||||
### 信息文件格式(__info)
|
||||
|
||||
```
|
||||
| 字段 | 类型 | 大小 | 说明 |
|
||||
|------|------|------|------|
|
||||
| DataFileCRC | uint32 | 4 bytes | 数据文件 CRC |
|
||||
| DataFileSize | int64 | 8 bytes | 数据文件大小 |
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 操作类说明
|
||||
|
||||
### DCFSInitializeOperation
|
||||
|
||||
初始化操作,执行完整的缓存系统初始化流程。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
CheckAppFootPrint
|
||||
├── 版本相同 → 继续
|
||||
└── 版本不同 → 根据 InstallClearMode 清理缓存
|
||||
↓
|
||||
SearchCacheFiles
|
||||
└── SearchCacheFilesOperation
|
||||
└── 遍历 BundleFiles 目录
|
||||
└── 收集需要验证的文件
|
||||
↓
|
||||
VerifyCacheFiles
|
||||
└── VerifyCacheFilesOperation(多线程)
|
||||
├── 验证成功 → 记录到 _records
|
||||
└── 验证失败 → 删除损坏文件
|
||||
↓
|
||||
CreateDownloadScheduler
|
||||
└── 创建 DownloadSchedulerOperation
|
||||
↓
|
||||
Done → Status = Succeed
|
||||
```
|
||||
|
||||
#### 状态机枚举
|
||||
|
||||
```csharp
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckAppFootPrint, // 检查应用版本足迹
|
||||
SearchCacheFiles, // 搜索缓存文件
|
||||
VerifyCacheFiles, // 验证缓存文件
|
||||
CreateDownloadScheduler,// 创建下载调度器
|
||||
Done // 完成
|
||||
}
|
||||
```
|
||||
|
||||
### DCFSLoadAssetBundleOperation
|
||||
|
||||
加载 AssetBundle 操作,支持按需下载和多重容错机制。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
CheckExist
|
||||
├── 已缓存 → LoadAssetBundle
|
||||
└── 未缓存 → 检查 DisableOnDemandDownload
|
||||
├── 禁用 → Failed
|
||||
└── 启用 → DownloadFile
|
||||
↓
|
||||
DownloadFile
|
||||
└── DownloadFileAsync()
|
||||
├── 下载成功 → LoadAssetBundle
|
||||
└── 下载失败 → Failed
|
||||
↓
|
||||
LoadAssetBundle
|
||||
├── 未加密 → AssetBundle.LoadFromFile[Async]
|
||||
└── 已加密 → DecryptionServices.LoadAssetBundle[Async]
|
||||
↓
|
||||
CheckResult
|
||||
├── 加载成功 → AssetBundleResult → Succeed
|
||||
└── 加载失败 → 验证文件完整性
|
||||
├── 验证通过 → LoadFromMemory 重试
|
||||
└── 验证失败 → 删除损坏文件 → Failed
|
||||
```
|
||||
|
||||
#### 移动平台容错机制
|
||||
|
||||
```csharp
|
||||
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
|
||||
// 说明:大多数情况在首次安装下载资源到沙盒内,游戏过程中切换到后台再回到游戏内有很大概率触发!
|
||||
string filePath = _fileSystem.GetCacheBundleFileLoadPath(_bundle);
|
||||
byte[] fileData = FileUtility.ReadAllBytes(filePath);
|
||||
if (fileData != null && fileData.Length > 0)
|
||||
{
|
||||
_assetBundle = AssetBundle.LoadFromMemory(fileData);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### DCFSLoadRawBundleOperation
|
||||
|
||||
加载原生资源包操作,处理文件格式变更场景。
|
||||
|
||||
```csharp
|
||||
// 注意:缓存的原生文件的格式,可能会在业务端根据需求发生变动!
|
||||
// 注意:这里需要校验文件格式,如果不一致对本地文件进行修正!
|
||||
if (File.Exists(filePath) == false)
|
||||
{
|
||||
var recordFileElement = _fileSystem.GetRecordFileElement(_bundle);
|
||||
File.Move(recordFileElement.DataFilePath, filePath);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 下载调度器
|
||||
|
||||
### DownloadSchedulerOperation
|
||||
|
||||
管理所有活跃的下载任务,控制并发数量。
|
||||
|
||||
#### 核心属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `Paused` | `bool` | 是否已暂停 |
|
||||
| `ActiveDownloadCount` | `int` | 当前活跃的下载任务数 |
|
||||
| `PendingDownloadCount` | `int` | 当前等待中的下载任务数 |
|
||||
|
||||
#### 工作原理
|
||||
|
||||
```
|
||||
InternalUpdate()
|
||||
│
|
||||
├── 1. 驱动下载后台 _fileSystem.DownloadBackend.Update()
|
||||
│
|
||||
├── 2. 遍历下载器集合
|
||||
│ ├── 已完成 → 加入移除列表
|
||||
│ └── RefCount <= 0 → 中止并移除
|
||||
│
|
||||
├── 3. 移除已完成/中止的下载器
|
||||
│
|
||||
└── 4. 启动新下载任务(如未暂停)
|
||||
├── 计算可启动数量 = min(maxConcurrency - active, maxRequestPerFrame)
|
||||
└── 启动等待中的下载器
|
||||
```
|
||||
|
||||
#### 引用计数机制
|
||||
|
||||
```csharp
|
||||
// 查询旧的下载器(复用)
|
||||
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
|
||||
{
|
||||
oldDownloader.Reference(); // 引用计数 +1
|
||||
return oldDownloader;
|
||||
}
|
||||
|
||||
// 创建新的下载器
|
||||
DownloadAndCacheFileOperation newDownloader;
|
||||
// ...
|
||||
newDownloader.Reference(); // 引用计数 +1
|
||||
```
|
||||
|
||||
### DownloadAndCacheRemoteFileOperation
|
||||
|
||||
远程文件下载操作,支持断点续传。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
CreateRequest
|
||||
├── 文件大小 >= ResumeDownloadMinimumSize
|
||||
│ └── CreateResumeRequest(断点续传)
|
||||
└── 文件大小 < ResumeDownloadMinimumSize
|
||||
└── CreateNormalRequest(普通下载)
|
||||
↓
|
||||
CheckRequest
|
||||
├── 下载成功 → VerifyBundleFile
|
||||
└── 下载失败 → ClearTempFileWhenError → Failed
|
||||
↓
|
||||
VerifyBundleFile
|
||||
└── VerifyTempFileOperation(多线程验证)
|
||||
├── 验证成功 → CacheBundleFile
|
||||
└── 验证失败 → 删除临时文件 → Failed
|
||||
↓
|
||||
CacheBundleFile
|
||||
└── WriteCacheBundleFile()
|
||||
├── 成功 → 删除临时文件 → Succeed
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
#### 断点续传实现
|
||||
|
||||
```csharp
|
||||
private IDownloadRequest CreateResumeRequest()
|
||||
{
|
||||
// 获取下载起始位置
|
||||
if (File.Exists(_tempFilePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(_tempFilePath);
|
||||
if (fileInfo.Length >= _bundle.FileSize)
|
||||
{
|
||||
File.Delete(_tempFilePath); // 文件已完整,删除重下
|
||||
}
|
||||
else
|
||||
{
|
||||
_fileOriginLength = fileInfo.Length; // 记录已下载大小
|
||||
}
|
||||
}
|
||||
|
||||
var args = new DownloadFileRequestArgs(
|
||||
URL, _tempFilePath, timeout, watchdogTime,
|
||||
appendToFile: true, // 追加写入
|
||||
removeFileOnAbort: false, // 中止时保留文件
|
||||
resumeFromBytes: _fileOriginLength // 断点位置
|
||||
);
|
||||
return _fileSystem.DownloadBackend.CreateFileRequest(args);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 缓存验证系统
|
||||
|
||||
### VerifyCacheFilesOperation
|
||||
|
||||
多线程缓存文件验证,在初始化时执行。
|
||||
|
||||
#### 验证流程
|
||||
|
||||
```
|
||||
InitVerify
|
||||
├── 获取系统线程池信息
|
||||
└── 计算实际并发数 = min(threads, FileVerifyMaxConcurrency)
|
||||
↓
|
||||
UpdateVerify(循环)
|
||||
├── 检测已完成的验证任务
|
||||
│ ├── 验证成功 → RecordBundleFile
|
||||
│ └── 验证失败 → DeleteFiles
|
||||
│
|
||||
└── 启动新的验证任务
|
||||
└── ThreadPool.QueueUserWorkItem(VerifyInThread)
|
||||
```
|
||||
|
||||
#### 验证级别
|
||||
|
||||
```csharp
|
||||
private EFileVerifyResult VerifyingCacheFile(VerifyFileElement element, EFileVerifyLevel verifyLevel)
|
||||
{
|
||||
if (verifyLevel == EFileVerifyLevel.Low)
|
||||
{
|
||||
// Low:仅检查文件存在
|
||||
if (File.Exists(element.InfoFilePath) == false)
|
||||
return EFileVerifyResult.InfoFileNotExisted;
|
||||
if (File.Exists(element.DataFilePath) == false)
|
||||
return EFileVerifyResult.DataFileNotExisted;
|
||||
return EFileVerifyResult.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Middle/High:检查文件存在 + CRC/Size 验证
|
||||
_fileSystem.ReadBundleInfoFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
|
||||
return FileVerifyHelper.FileVerify(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### VerifyTempFileOperation
|
||||
|
||||
下载文件验证,在线程池中执行。
|
||||
|
||||
```csharp
|
||||
private void VerifyInThread(object obj)
|
||||
{
|
||||
TempFileElement element = (TempFileElement)obj;
|
||||
int result = (int)FileVerifyHelper.FileVerify(
|
||||
element.TempFilePath,
|
||||
element.TempFileSize,
|
||||
element.TempFileCRC,
|
||||
EFileVerifyLevel.High // 始终使用高级验证
|
||||
);
|
||||
element.Result = result; // 线程安全的结果设置
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 覆盖安装检测
|
||||
|
||||
### ApplicationFootPrint
|
||||
|
||||
应用版本足迹,用于检测 App 覆盖安装。
|
||||
|
||||
```csharp
|
||||
public static bool IsDirty(DefaultCacheFileSystem fileSystem)
|
||||
{
|
||||
string filePath = fileSystem.GetSandboxAppFootPrintFilePath();
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
string footPrint = FileUtility.ReadAllText(filePath);
|
||||
return IsValidVersion(footPrint) == false; // 版本不同
|
||||
}
|
||||
return true; // 文件不存在
|
||||
}
|
||||
```
|
||||
|
||||
### EOverwriteInstallClearMode
|
||||
|
||||
覆盖安装时的缓存清理模式。
|
||||
|
||||
| 枚举值 | 说明 |
|
||||
|--------|------|
|
||||
| `NeverClear` | 不清理任何缓存 |
|
||||
| `ClearAllManifestFiles` | 清理所有清单文件(默认) |
|
||||
| `ClearAllBundleAndManifestFiles` | 清理所有资源包和清单文件 |
|
||||
|
||||
---
|
||||
|
||||
## 缓存清理操作
|
||||
|
||||
### 清理模式对照表
|
||||
|
||||
| 清理模式 | 操作类 | 说明 |
|
||||
|----------|--------|------|
|
||||
| `ClearAllBundleFiles` | `ClearAllCacheBundleFilesOperation` | 清理所有缓存资源包 |
|
||||
| `ClearUnusedBundleFiles` | `ClearUnusedCacheBundleFilesOperation` | 清理不在清单中的资源包 |
|
||||
| `ClearBundleFilesByTags` | `ClearCacheBundleFilesByTagsOperaiton` | 按标签清理 |
|
||||
| `ClearBundleFilesByLocations` | `ClearCacheBundleFilesByLocationsOperaiton` | 按资源路径清理 |
|
||||
| `ClearAllManifestFiles` | `ClearAllCacheManifestFilesOperation` | 清理所有清单文件 |
|
||||
| `ClearUnusedManifestFiles` | `ClearUnusedCacheManifestFilesOperation` | 清理未使用的清单文件 |
|
||||
|
||||
### 时间切片清理
|
||||
|
||||
```csharp
|
||||
for (int i = _allBundleGUIDs.Count - 1; i >= 0; i--)
|
||||
{
|
||||
string bundleGUID = _allBundleGUIDs[i];
|
||||
_fileSystem.DeleteCacheBundleFile(bundleGUID);
|
||||
_allBundleGUIDs.RemoveAt(i);
|
||||
|
||||
// 检查操作系统是否繁忙,避免阻塞主线程
|
||||
if (OperationSystem.IsBusy)
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 元素类说明
|
||||
|
||||
### RecordFileElement
|
||||
|
||||
缓存文件记录元素,存储已验证的缓存文件信息。
|
||||
|
||||
```csharp
|
||||
internal class RecordFileElement
|
||||
{
|
||||
public readonly string InfoFilePath; // 信息文件路径
|
||||
public readonly string DataFilePath; // 数据文件路径
|
||||
public readonly uint DataFileCRC; // 数据文件 CRC
|
||||
public readonly long DataFileSize; // 数据文件大小
|
||||
|
||||
public bool DeleteFolder(); // 删除整个文件夹
|
||||
}
|
||||
```
|
||||
|
||||
### TempFileElement
|
||||
|
||||
临时文件元素,用于下载文件验证。
|
||||
|
||||
```csharp
|
||||
internal class TempFileElement
|
||||
{
|
||||
public readonly string TempFilePath; // 临时文件路径
|
||||
public readonly uint TempFileCRC; // 预期 CRC
|
||||
public readonly long TempFileSize; // 预期文件大小
|
||||
|
||||
private int _result = 0;
|
||||
public int Result // 线程安全的验证结果
|
||||
{
|
||||
get => Interlocked.CompareExchange(ref _result, 0, 0);
|
||||
set => Interlocked.Exchange(ref _result, value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### VerifyFileElement
|
||||
|
||||
验证文件元素,用于缓存文件批量验证。
|
||||
|
||||
```csharp
|
||||
internal class VerifyFileElement
|
||||
{
|
||||
public readonly string PackageName; // 包裹名称
|
||||
public readonly string BundleGUID; // 资源包 GUID
|
||||
public readonly string FileRootPath; // 文件根目录
|
||||
public readonly string DataFilePath; // 数据文件路径
|
||||
public readonly string InfoFilePath; // 信息文件路径
|
||||
|
||||
public uint DataFileCRC; // 数据文件 CRC
|
||||
public long DataFileSize; // 数据文件大小
|
||||
|
||||
private int _result = 0;
|
||||
public int Result // 线程安全的验证结果
|
||||
{
|
||||
get => Interlocked.CompareExchange(ref _result, 0, 0);
|
||||
set => Interlocked.Exchange(ref _result, value);
|
||||
}
|
||||
|
||||
public void DeleteFiles(); // 删除所有相关文件
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础配置
|
||||
|
||||
```csharp
|
||||
// 创建远程服务接口
|
||||
class GameRemoteServices : IRemoteServices
|
||||
{
|
||||
public string GetRemoteMainURL(string fileName)
|
||||
{
|
||||
return $"https://cdn.example.com/bundles/{fileName}";
|
||||
}
|
||||
public string GetRemoteFallbackURL(string fileName)
|
||||
{
|
||||
return $"https://cdn-backup.example.com/bundles/{fileName}";
|
||||
}
|
||||
}
|
||||
|
||||
// 创建缓存文件系统参数
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 初始化包裹
|
||||
var initParams = new HostPlayModeParameters();
|
||||
initParams.BuildinFileSystemParameters = buildinParams;
|
||||
initParams.CacheFileSystemParameters = cacheParams;
|
||||
var initOp = package.InitializeAsync(initParams);
|
||||
```
|
||||
|
||||
### 配置下载参数
|
||||
|
||||
```csharp
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 设置下载并发数
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY, 8);
|
||||
|
||||
// 设置每帧最大请求数
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME, 3);
|
||||
|
||||
// 设置下载看门狗时间(秒)
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME, 30);
|
||||
```
|
||||
|
||||
### 配置断点续传
|
||||
|
||||
```csharp
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 启用断点续传的最小文件大小(1MB)
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE, 1024 * 1024);
|
||||
|
||||
// 断点续传关注的HTTP错误码(这些错误码时删除临时文件重新下载)
|
||||
var responseCodes = new List<long> { 416 }; // Range Not Satisfiable
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES, responseCodes);
|
||||
```
|
||||
|
||||
### 配置文件验证
|
||||
|
||||
```csharp
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 设置验证级别
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, EFileVerifyLevel.High);
|
||||
|
||||
// 设置验证并发数
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, 64);
|
||||
```
|
||||
|
||||
### 配置加密支持
|
||||
|
||||
```csharp
|
||||
// 自定义解密服务
|
||||
class GameDecryptionServices : IDecryptionServices
|
||||
{
|
||||
public DecryptResult LoadAssetBundle(DecryptFileInfo fileInfo)
|
||||
{
|
||||
// 实现解密逻辑
|
||||
byte[] data = DecryptFile(fileInfo.FileLoadPath);
|
||||
AssetBundle bundle = AssetBundle.LoadFromMemory(data);
|
||||
return new DecryptResult { Result = bundle };
|
||||
}
|
||||
// ...
|
||||
}
|
||||
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 设置解密服务
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, new GameDecryptionServices());
|
||||
```
|
||||
|
||||
### 配置覆盖安装行为
|
||||
|
||||
```csharp
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 覆盖安装时清理所有资源包和清单
|
||||
cacheParams.AddParameter(
|
||||
FileSystemParametersDefine.INSTALL_CLEAR_MODE,
|
||||
EOverwriteInstallClearMode.ClearAllBundleAndManifestFiles
|
||||
);
|
||||
```
|
||||
|
||||
### 清理缓存
|
||||
|
||||
```csharp
|
||||
// 清理所有缓存
|
||||
var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearAllBundleFiles);
|
||||
await clearOp.ToTask();
|
||||
|
||||
// 清理未使用的缓存
|
||||
var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearUnusedBundleFiles);
|
||||
await clearOp.ToTask();
|
||||
|
||||
// 按标签清理
|
||||
var clearOp = package.ClearCacheFilesAsync(EFileClearMode.ClearBundleFilesByTags, "dlc1");
|
||||
await clearOp.ToTask();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数常量
|
||||
|
||||
```csharp
|
||||
// 远程服务
|
||||
FileSystemParametersDefine.REMOTE_SERVICES // IRemoteServices: 远程服务接口
|
||||
|
||||
// 覆盖安装
|
||||
FileSystemParametersDefine.INSTALL_CLEAR_MODE // EOverwriteInstallClearMode: 清理模式
|
||||
|
||||
// 文件验证
|
||||
FileSystemParametersDefine.FILE_VERIFY_LEVEL // EFileVerifyLevel: 验证级别
|
||||
FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY // int: 验证并发数
|
||||
|
||||
// 文件格式
|
||||
FileSystemParametersDefine.APPEND_FILE_EXTENSION // bool: 追加文件扩展名
|
||||
|
||||
// 下载控制
|
||||
FileSystemParametersDefine.DISABLE_ONDEMAND_DOWNLOAD // bool: 禁用边玩边下
|
||||
FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY // int: 下载并发数
|
||||
FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME // int: 每帧请求数
|
||||
FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME // int: 看门狗时间
|
||||
|
||||
// 断点续传
|
||||
FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE // long: 最小文件大小
|
||||
FileSystemParametersDefine.RESUME_DOWNLOAD_RESPONSE_CODES // List<long>: 关注错误码
|
||||
|
||||
// 服务接口
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES // IDecryptionServices: 解密服务
|
||||
FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices: 清单服务
|
||||
FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES // ICopyLocalFileServices: 本地拷贝服务
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
IFileSystem
|
||||
└── DefaultCacheFileSystem
|
||||
|
||||
FSInitializeFileSystemOperation
|
||||
└── DCFSInitializeOperation
|
||||
|
||||
FSRequestPackageVersionOperation
|
||||
└── DCFSRequestPackageVersionOperation
|
||||
|
||||
FSLoadPackageManifestOperation
|
||||
└── DCFSLoadPackageManifestOperation
|
||||
|
||||
FSLoadBundleOperation
|
||||
├── DCFSLoadAssetBundleOperation
|
||||
└── DCFSLoadRawBundleOperation
|
||||
|
||||
FSDownloadFileOperation
|
||||
└── DownloadPackageBundleOperation
|
||||
|
||||
FSClearCacheFilesOperation
|
||||
├── ClearAllCacheBundleFilesOperation
|
||||
├── ClearUnusedCacheBundleFilesOperation
|
||||
├── ClearCacheBundleFilesByTagsOperaiton
|
||||
├── ClearCacheBundleFilesByLocationsOperaiton
|
||||
├── ClearAllCacheManifestFilesOperation
|
||||
└── ClearUnusedCacheManifestFilesOperation
|
||||
|
||||
AsyncOperationBase
|
||||
├── DownloadSchedulerOperation
|
||||
├── DownloadAndCacheFileOperation (abstract)
|
||||
│ ├── DownloadAndCacheRemoteFileOperation
|
||||
│ └── DownloadAndCacheLocalFileOperation
|
||||
├── SearchCacheFilesOperation
|
||||
├── VerifyCacheFilesOperation
|
||||
├── VerifyTempFileOperation
|
||||
├── DownloadPackageHashOperation
|
||||
├── DownloadPackageManifestOperation
|
||||
├── LoadCachePackageHashOperation
|
||||
├── LoadCachePackageManifestOperation
|
||||
└── RequestRemotePackageVersionOperation
|
||||
|
||||
BundleResult
|
||||
├── AssetBundleResult ← AssetBundle 资源
|
||||
└── RawBundleResult ← 原生文件资源
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **远程服务必需**:使用缓存文件系统必须配置 `IRemoteServices` 接口
|
||||
2. **保底加载**:缓存文件系统的 `Belong()` 始终返回 true,作为资源加载的保底方案
|
||||
3. **线程安全**:文件验证和下载使用后台线程,但核心逻辑仍在主线程执行
|
||||
4. **并发限制**:合理设置下载和验证的并发数,避免系统过载
|
||||
5. **移动平台**:Android 平台存在极小概率的 AssetBundle 加载失败,系统会自动尝试 LoadFromMemory 作为备选方案
|
||||
6. **断点续传**:启用断点续传时,需要合理设置 `ResumeDownloadMinimumSize` 和 `ResumeDownloadResponseCodes`
|
||||
7. **覆盖安装**:App 版本更新时会自动检测并根据配置清理缓存,避免旧缓存导致问题
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8292f707fbf60854e852e1a75824d892
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,424 @@
|
||||
# DefaultEditorFileSystem 编辑器模拟文件系统
|
||||
|
||||
## 模块概述
|
||||
|
||||
DefaultEditorFileSystem 是 YooAsset 的**编辑器模拟文件系统**,专为 Unity 编辑器开发环境设计。该文件系统无需构建实际的 AssetBundle 文件,直接使用 Unity 的 AssetDatabase API 加载资源,实现快速迭代开发。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **无需构建资源包**:直接使用 AssetDatabase 加载资源
|
||||
- **模拟下载流程**:支持模拟网络下载行为(用于 UI 调试)
|
||||
- **模拟异步延迟**:可配置异步加载的模拟帧数
|
||||
- **WebGL 模式模拟**:支持模拟 WebGL 平台行为
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **快速迭代** | 无需构建 AssetBundle,修改资源后立即生效 |
|
||||
| **行为模拟** | 模拟真实环境的下载和加载行为 |
|
||||
| **调试友好** | 支持 UI 进度条等功能的调试 |
|
||||
| **零配置** | 开箱即用,最小化配置需求 |
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
DefaultEditorFileSystem/
|
||||
├── DefaultEditorFileSystem.cs # 文件系统主类
|
||||
├── DefaultEditorFileSystemDefine.cs # 常量定义(预留)
|
||||
└── Operation/ # 操作类
|
||||
├── DEFSInitializeOperation.cs # 初始化操作
|
||||
├── DEFSRequestPackageVersionOperation.cs # 请求版本操作
|
||||
├── DEFSLoadPackageManifestOperation.cs # 加载清单操作
|
||||
├── DEFSLoadBundleOperation.cs # 加载资源包操作
|
||||
└── internal/ # 内部操作类
|
||||
├── DownloadVirutalBundleOperation.cs # 虚拟下载操作
|
||||
├── LoadEditorPackageVersionOperation.cs # 加载版本文件操作
|
||||
├── LoadEditorPackageHashOperation.cs # 加载哈希文件操作
|
||||
└── LoadEditorPackageManifestOperation.cs # 加载清单文件操作
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心类说明
|
||||
|
||||
### DefaultEditorFileSystem
|
||||
|
||||
编辑器模拟文件系统的主类,实现 `IFileSystem` 接口。
|
||||
|
||||
#### 基本属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `PackageName` | `string` | 包裹名称 |
|
||||
| `FileRoot` | `string` | 文件根目录(清单文件所在目录) |
|
||||
| `FileCount` | `int` | 文件数量(始终返回 0) |
|
||||
| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 |
|
||||
|
||||
#### 自定义参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `VirtualWebGLMode` | `bool` | `false` | 模拟 WebGL 平台模式 |
|
||||
| `VirtualDownloadMode` | `bool` | `false` | 模拟虚拟下载模式 |
|
||||
| `VirtualDownloadSpeed` | `int` | `1024` | 模拟下载速度(字节/秒) |
|
||||
| `AsyncSimulateMinFrame` | `int` | `1` | 异步加载最小模拟帧数 |
|
||||
| `AsyncSimulateMaxFrame` | `int` | `1` | 异步加载最大模拟帧数 |
|
||||
|
||||
#### 核心方法
|
||||
|
||||
```csharp
|
||||
// 生命周期
|
||||
void OnCreate(string packageName, string packageRoot);
|
||||
void OnDestroy();
|
||||
void SetParameter(string name, object value);
|
||||
|
||||
// 异步操作
|
||||
FSInitializeFileSystemOperation InitializeFileSystemAsync();
|
||||
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
|
||||
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
|
||||
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
|
||||
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options);
|
||||
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options);
|
||||
|
||||
// 文件查询
|
||||
bool Belong(PackageBundle bundle); // 始终返回 true
|
||||
bool Exists(PackageBundle bundle); // VirtualDownloadMode 时检查记录
|
||||
bool NeedDownload(PackageBundle bundle);// VirtualDownloadMode 时返回未记录的文件
|
||||
bool NeedUnpack(PackageBundle bundle); // 始终返回 false
|
||||
bool NeedImport(PackageBundle bundle); // 始终返回 false
|
||||
|
||||
// 文件访问
|
||||
string GetBundleFilePath(PackageBundle bundle); // 返回资源路径
|
||||
byte[] ReadBundleFileData(PackageBundle bundle); // 读取文件二进制
|
||||
string ReadBundleFileText(PackageBundle bundle); // 读取文件文本
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 操作类说明
|
||||
|
||||
### DEFSInitializeOperation
|
||||
|
||||
初始化操作,立即完成(无需任何初始化工作)。
|
||||
|
||||
```
|
||||
状态流程:InternalStart() → Status = Succeed
|
||||
```
|
||||
|
||||
### DEFSRequestPackageVersionOperation
|
||||
|
||||
请求包裹版本操作,从本地版本文件读取版本号。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadPackageVersion
|
||||
└── LoadEditorPackageVersionOperation
|
||||
└── 读取 {PackageName}_Version.txt
|
||||
├── 成功 → PackageVersion = 文件内容
|
||||
└── 失败 → Error
|
||||
```
|
||||
|
||||
### DEFSLoadPackageManifestOperation
|
||||
|
||||
加载资源清单操作,从本地清单文件加载并解析清单。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadEditorPackageHash
|
||||
└── LoadEditorPackageHashOperation
|
||||
└── 读取 {PackageName}_{Version}.hash
|
||||
├── 成功 → PackageHash
|
||||
└── 失败 → Error
|
||||
↓
|
||||
LoadEditorPackageManifest
|
||||
└── LoadEditorPackageManifestOperation
|
||||
├── 读取 {PackageName}_{Version}.bytes
|
||||
├── 验证哈希值
|
||||
└── 反序列化清单
|
||||
├── 成功 → Manifest
|
||||
└── 失败 → Error
|
||||
```
|
||||
|
||||
### DEFSLoadBundleOperation
|
||||
|
||||
加载资源包操作,支持虚拟下载模式和异步模拟延迟。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
CheckExist
|
||||
├── 文件存在 → LoadAssetBundle
|
||||
└── 文件不存在 → DownloadFile
|
||||
↓
|
||||
DownloadFile
|
||||
└── DownloadVirtualBundleOperation
|
||||
├── 模拟下载进度
|
||||
└── 记录下载完成
|
||||
↓
|
||||
LoadAssetBundle
|
||||
└── 等待模拟帧数
|
||||
↓
|
||||
CheckResult
|
||||
└── 创建 VirtualBundleResult → Status = Succeed
|
||||
```
|
||||
|
||||
#### 状态机枚举
|
||||
|
||||
```csharp
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckExist, // 检查文件是否存在
|
||||
DownloadFile, // 下载文件(虚拟下载)
|
||||
AbortDownload, // 中断下载
|
||||
LoadAssetBundle, // 加载资源包(模拟延迟)
|
||||
CheckResult, // 检查结果
|
||||
Done // 完成
|
||||
}
|
||||
```
|
||||
|
||||
### DownloadVirtualBundleOperation
|
||||
|
||||
虚拟下载操作,模拟网络下载行为。
|
||||
|
||||
**特性:**
|
||||
- 使用 `VirtualFileDownloader` 模拟下载进度
|
||||
- 支持失败重试机制
|
||||
- 下载完成后记录到 `_records` 字典
|
||||
|
||||
```
|
||||
状态流程:
|
||||
CheckExists
|
||||
├── 文件已记录 → Status = Succeed
|
||||
└── 文件未记录 → CreateRequest
|
||||
↓
|
||||
CreateRequest
|
||||
└── DownloadSimulateRequestArgs
|
||||
├── URL = BundleName
|
||||
├── FileSize = Bundle.FileSize
|
||||
└── DownloadSpeed = VirtualDownloadSpeed
|
||||
↓
|
||||
CheckRequest
|
||||
├── 下载成功 → RecordDownloadFile() → Status = Succeed
|
||||
└── 下载失败 → TryAgain 或 Status = Failed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 内部操作类
|
||||
|
||||
### LoadEditorPackageVersionOperation
|
||||
|
||||
从本地文件加载包裹版本号。
|
||||
|
||||
| 属性 | 说明 |
|
||||
|------|------|
|
||||
| `PackageVersion` | 读取到的版本号字符串 |
|
||||
|
||||
### LoadEditorPackageHashOperation
|
||||
|
||||
从本地文件加载包裹哈希值。
|
||||
|
||||
| 属性 | 说明 |
|
||||
|------|------|
|
||||
| `PackageHash` | 读取到的哈希值字符串 |
|
||||
|
||||
### LoadEditorPackageManifestOperation
|
||||
|
||||
加载并反序列化资源清单。
|
||||
|
||||
| 属性 | 说明 |
|
||||
|------|------|
|
||||
| `Manifest` | 反序列化后的清单对象 |
|
||||
|
||||
**处理流程:**
|
||||
1. 读取清单二进制文件
|
||||
2. 使用哈希值验证文件完整性
|
||||
3. 反序列化为 `PackageManifest` 对象
|
||||
|
||||
---
|
||||
|
||||
## 工作原理
|
||||
|
||||
### 资源加载机制
|
||||
|
||||
```
|
||||
用户请求加载资源
|
||||
│
|
||||
▼
|
||||
DefaultEditorFileSystem.LoadBundleFile()
|
||||
│
|
||||
▼
|
||||
DEFSLoadBundleOperation
|
||||
│
|
||||
▼
|
||||
创建 VirtualBundleResult
|
||||
│
|
||||
▼
|
||||
VirtualBundleResult.LoadAssetAsync()
|
||||
│
|
||||
▼
|
||||
VirtualBundleLoadAssetOperation
|
||||
│
|
||||
▼
|
||||
AssetDatabase.LoadAssetAtPath() ← Unity 编辑器 API
|
||||
│
|
||||
▼
|
||||
返回资源对象
|
||||
```
|
||||
|
||||
### 虚拟下载模式
|
||||
|
||||
当 `VirtualDownloadMode = true` 时:
|
||||
|
||||
1. **首次加载**:资源被视为"未下载",需要执行虚拟下载
|
||||
2. **虚拟下载**:使用 `VirtualFileDownloader` 模拟下载进度
|
||||
3. **记录完成**:下载完成后将 BundleGUID 记录到 `_records` 字典
|
||||
4. **后续加载**:检查 `_records` 字典,已记录的资源直接加载
|
||||
|
||||
```csharp
|
||||
// 记录下载完成的文件
|
||||
protected readonly Dictionary<string, string> _records;
|
||||
|
||||
// 检查文件是否存在
|
||||
public virtual bool Exists(PackageBundle bundle)
|
||||
{
|
||||
if (VirtualDownloadMode)
|
||||
return _records.ContainsKey(bundle.BundleGUID);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### 异步模拟延迟
|
||||
|
||||
通过 `AsyncSimulateMinFrame` 和 `AsyncSimulateMaxFrame` 参数模拟异步加载延迟:
|
||||
|
||||
```csharp
|
||||
// 获取随机模拟帧数
|
||||
public int GetAsyncSimulateFrame()
|
||||
{
|
||||
return UnityEngine.Random.Range(AsyncSimulateMinFrame, AsyncSimulateMaxFrame + 1);
|
||||
}
|
||||
|
||||
// 在 DEFSLoadBundleOperation 中等待
|
||||
if (_steps == ESteps.LoadAssetBundle)
|
||||
{
|
||||
if (_asyncSimulateFrame <= 0)
|
||||
_steps = ESteps.CheckResult;
|
||||
else
|
||||
_asyncSimulateFrame--;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础配置
|
||||
|
||||
```csharp
|
||||
// 创建编辑器文件系统参数
|
||||
var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters(
|
||||
packageRoot: "Assets/GameRes/Bundles/DefaultPackage"
|
||||
);
|
||||
|
||||
// 初始化包裹
|
||||
var initParams = new EditorSimulateModeParameters();
|
||||
initParams.EditorFileSystemParameters = editorParams;
|
||||
var initOp = package.InitializeAsync(initParams);
|
||||
```
|
||||
|
||||
### 启用虚拟下载模式
|
||||
|
||||
```csharp
|
||||
var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters(
|
||||
packageRoot: "Assets/GameRes/Bundles/DefaultPackage"
|
||||
);
|
||||
|
||||
// 启用虚拟下载模式
|
||||
editorParams.AddParameter(FileSystemParametersDefine.VIRTUAL_DOWNLOAD_MODE, true);
|
||||
editorParams.AddParameter(FileSystemParametersDefine.VIRTUAL_DOWNLOAD_SPEED, 1024 * 100); // 100KB/s
|
||||
```
|
||||
|
||||
### 配置异步模拟延迟
|
||||
|
||||
```csharp
|
||||
var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters(
|
||||
packageRoot: "Assets/GameRes/Bundles/DefaultPackage"
|
||||
);
|
||||
|
||||
// 设置异步加载延迟 1-3 帧
|
||||
editorParams.AddParameter(FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME, 1);
|
||||
editorParams.AddParameter(FileSystemParametersDefine.ASYNC_SIMULATE_MAX_FRAME, 3);
|
||||
```
|
||||
|
||||
### 模拟 WebGL 模式
|
||||
|
||||
```csharp
|
||||
var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters(
|
||||
packageRoot: "Assets/GameRes/Bundles/DefaultPackage"
|
||||
);
|
||||
|
||||
// 启用 WebGL 模拟模式
|
||||
editorParams.AddParameter(FileSystemParametersDefine.VIRTUAL_WEBGL_MODE, true);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数常量
|
||||
|
||||
```csharp
|
||||
// 模拟模式参数
|
||||
FileSystemParametersDefine.VIRTUAL_WEBGL_MODE // bool: 模拟 WebGL 模式
|
||||
FileSystemParametersDefine.VIRTUAL_DOWNLOAD_MODE // bool: 模拟下载模式
|
||||
FileSystemParametersDefine.VIRTUAL_DOWNLOAD_SPEED // int: 模拟下载速度(字节/秒)
|
||||
FileSystemParametersDefine.ASYNC_SIMULATE_MIN_FRAME // int: 异步模拟最小帧数
|
||||
FileSystemParametersDefine.ASYNC_SIMULATE_MAX_FRAME // int: 异步模拟最大帧数
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
IFileSystem
|
||||
└── DefaultEditorFileSystem
|
||||
|
||||
FSInitializeFileSystemOperation
|
||||
└── DEFSInitializeOperation
|
||||
|
||||
FSRequestPackageVersionOperation
|
||||
└── DEFSRequestPackageVersionOperation
|
||||
|
||||
FSLoadPackageManifestOperation
|
||||
└── DEFSLoadPackageManifestOperation
|
||||
|
||||
FSLoadBundleOperation
|
||||
└── DEFSLoadBundleOperation
|
||||
|
||||
FSDownloadFileOperation
|
||||
└── DownloadVirtualBundleOperation
|
||||
|
||||
AsyncOperationBase
|
||||
├── LoadEditorPackageVersionOperation
|
||||
├── LoadEditorPackageHashOperation
|
||||
└── LoadEditorPackageManifestOperation
|
||||
|
||||
BundleResult
|
||||
└── VirtualBundleResult ← 编辑器模式专用
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **仅限编辑器**:此文件系统仅在 Unity 编辑器中有效
|
||||
2. **需要构建清单**:虽然不需要构建 AssetBundle,但需要构建资源清单文件
|
||||
3. **VirtualBundle 类型**:只支持 `EBuildBundleType.VirtualBundle` 类型的资源包
|
||||
4. **WebGL 模式限制**:`VirtualWebGLMode` 下不支持同步加载(`WaitForAsyncComplete`)
|
||||
5. **性能差异**:编辑器模式下的加载性能与真机不同,仅供开发调试使用
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10ca037f4f07977458b8e94e4ea0f32c
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,385 @@
|
||||
# DefaultUnpackFileSystem 解压文件系统
|
||||
|
||||
## 模块概述
|
||||
|
||||
DefaultUnpackFileSystem 是 YooAsset 的**解压文件系统**,专为处理 Android 和 OpenHarmony 平台的内置资源解压需求而设计。该文件系统继承自 `DefaultCacheFileSystem`,复用其完整的下载、验证、缓存功能,仅重定义存储目录结构。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **继承复用**:完全继承 DefaultCacheFileSystem 的所有功能
|
||||
- **独立存储**:使用独立的目录存储解压后的资源
|
||||
- **本地下载**:通过 WWW 路径从 StreamingAssets "下载"资源
|
||||
- **平台适配**:解决 Android APK 内文件无法直接访问的问题
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **平台兼容** | 解决 Android/OpenHarmony 平台 APK 内文件访问限制 |
|
||||
| **代码复用** | 继承 DefaultCacheFileSystem,避免重复实现 |
|
||||
| **资源隔离** | 解压资源与下载缓存分开存储,便于管理 |
|
||||
| **透明集成** | 作为 DefaultBuildinFileSystem 的内部组件工作 |
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
DefaultUnpackFileSystem/
|
||||
├── DefaultUnpackFileSystem.cs # 解压文件系统主类
|
||||
├── DefaultUnpackFileSystemDefine.cs # 常量定义
|
||||
└── DefaultUnpackRemoteServices.cs # 本地资源服务接口
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心类说明
|
||||
|
||||
### DefaultUnpackFileSystem
|
||||
|
||||
解压文件系统主类,继承自 `DefaultCacheFileSystem`。
|
||||
|
||||
```csharp
|
||||
internal class DefaultUnpackFileSystem : DefaultCacheFileSystem
|
||||
{
|
||||
public override void OnCreate(string packageName, string rootDirectory)
|
||||
{
|
||||
base.OnCreate(packageName, rootDirectory);
|
||||
|
||||
// 重写保存根目录和临时目录
|
||||
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, "UnpackBundleFiles");
|
||||
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, "UnpackManifestFiles");
|
||||
_tempFilesRoot = PathUtility.Combine(_packageRoot, "UnpackTempFiles");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 继承的功能
|
||||
|
||||
由于继承自 `DefaultCacheFileSystem`,DefaultUnpackFileSystem 拥有以下完整功能:
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| 文件下载 | 通过 DownloadScheduler 下载资源 |
|
||||
| 断点续传 | 支持大文件断点续传 |
|
||||
| 文件验证 | 多线程 CRC/Hash 验证 |
|
||||
| 缓存管理 | 记录已解压文件,避免重复解压 |
|
||||
| 加密支持 | 支持 IDecryptionServices 解密 |
|
||||
| 覆盖安装检测 | App 版本变更时清理解压缓存 |
|
||||
|
||||
### DefaultUnpackFileSystemDefine
|
||||
|
||||
常量定义类,定义解压目录名称。
|
||||
|
||||
```csharp
|
||||
internal class DefaultUnpackFileSystemDefine
|
||||
{
|
||||
/// <summary>
|
||||
/// 保存的资源文件的文件夹名称
|
||||
/// </summary>
|
||||
public const string SaveBundleFilesFolderName = "UnpackBundleFiles";
|
||||
|
||||
/// <summary>
|
||||
/// 保存的清单文件的文件夹名称
|
||||
/// </summary>
|
||||
public const string SaveManifestFilesFolderName = "UnpackManifestFiles";
|
||||
|
||||
/// <summary>
|
||||
/// 下载的临时文件的文件夹名称
|
||||
/// </summary>
|
||||
public const string TempFilesFolderName = "UnpackTempFiles";
|
||||
}
|
||||
```
|
||||
|
||||
### DefaultUnpackRemoteServices
|
||||
|
||||
本地资源服务接口,将 StreamingAssets 路径转换为 WWW 请求路径。
|
||||
|
||||
```csharp
|
||||
internal class DefaultUnpackRemoteServices : IRemoteServices
|
||||
{
|
||||
private readonly string _buildinPackageRoot;
|
||||
protected readonly Dictionary<string, string> _mapping = new Dictionary<string, string>(10000);
|
||||
|
||||
public DefaultUnpackRemoteServices(string buildinPackRoot)
|
||||
{
|
||||
_buildinPackageRoot = buildinPackRoot;
|
||||
}
|
||||
|
||||
// 主地址和备用地址相同(本地文件)
|
||||
string IRemoteServices.GetRemoteMainURL(string fileName)
|
||||
{
|
||||
return GetFileLoadURL(fileName);
|
||||
}
|
||||
|
||||
string IRemoteServices.GetRemoteFallbackURL(string fileName)
|
||||
{
|
||||
return GetFileLoadURL(fileName);
|
||||
}
|
||||
|
||||
private string GetFileLoadURL(string fileName)
|
||||
{
|
||||
if (_mapping.TryGetValue(fileName, out string url) == false)
|
||||
{
|
||||
string filePath = PathUtility.Combine(_buildinPackageRoot, fileName);
|
||||
url = DownloadSystemHelper.ConvertToWWWPath(filePath);
|
||||
_mapping.Add(fileName, url);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 路径转换示例
|
||||
|
||||
```
|
||||
输入文件名: bundle_abc123.bundle
|
||||
|
||||
StreamingAssets 路径:
|
||||
{Application.streamingAssetsPath}/DefaultPackage/bundle_abc123.bundle
|
||||
|
||||
WWW 请求路径 (Android):
|
||||
jar:file:///data/app/com.example.game.apk!/assets/DefaultPackage/bundle_abc123.bundle
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
### 与 DefaultCacheFileSystem 对比
|
||||
|
||||
| 目录类型 | DefaultCacheFileSystem | DefaultUnpackFileSystem |
|
||||
|----------|----------------------|------------------------|
|
||||
| 资源文件 | `BundleFiles/` | `UnpackBundleFiles/` |
|
||||
| 清单文件 | `ManifestFiles/` | `UnpackManifestFiles/` |
|
||||
| 临时文件 | `TempFiles/` | `UnpackTempFiles/` |
|
||||
|
||||
### 实际目录结构
|
||||
|
||||
```
|
||||
{SandboxRoot}/{PackageName}/
|
||||
├── BundleFiles/ # DefaultCacheFileSystem 下载缓存
|
||||
│ └── ...
|
||||
├── ManifestFiles/ # DefaultCacheFileSystem 清单缓存
|
||||
│ └── ...
|
||||
├── UnpackBundleFiles/ # DefaultUnpackFileSystem 解压缓存
|
||||
│ ├── {Hash[0:2]}/
|
||||
│ │ └── {BundleGUID}/
|
||||
│ │ ├── __data
|
||||
│ │ └── __info
|
||||
│ └── ...
|
||||
├── UnpackManifestFiles/ # DefaultUnpackFileSystem 清单
|
||||
│ └── ...
|
||||
└── UnpackTempFiles/ # DefaultUnpackFileSystem 临时文件
|
||||
└── ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 工作原理
|
||||
|
||||
### 解压触发条件
|
||||
|
||||
在 `DefaultBuildinFileSystem` 中,以下情况会触发解压:
|
||||
|
||||
```csharp
|
||||
protected virtual bool IsUnpackBundleFile(PackageBundle bundle)
|
||||
{
|
||||
if (Belong(bundle) == false)
|
||||
return false;
|
||||
|
||||
#if UNITY_ANDROID || UNITY_OPENHARMONY
|
||||
// Android/OpenHarmony 平台
|
||||
if (bundle.Encrypted)
|
||||
return true; // 加密资源需要解压
|
||||
|
||||
if (bundle.BundleType == (int)EBuildBundleType.RawBundle)
|
||||
return true; // 原生文件需要解压
|
||||
|
||||
return false; // 普通 AssetBundle 不需要解压
|
||||
#else
|
||||
return false; // 其他平台不需要解压
|
||||
#endif
|
||||
}
|
||||
```
|
||||
|
||||
### 解压流程
|
||||
|
||||
```
|
||||
DefaultBuildinFileSystem
|
||||
│
|
||||
├── NeedUnpack(bundle) 检查
|
||||
│ └── IsUnpackBundleFile(bundle)
|
||||
│ ├── Android/OpenHarmony 平台
|
||||
│ │ ├── 加密资源 → true
|
||||
│ │ └── RawBundle → true
|
||||
│ └── 其他平台 → false
|
||||
│
|
||||
├── 需要解压时
|
||||
│ └── _unpackFileSystem.DownloadFileAsync(bundle, options)
|
||||
│ └── DefaultUnpackRemoteServices.GetRemoteMainURL()
|
||||
│ └── 返回 StreamingAssets 的 WWW 路径
|
||||
│ ↓
|
||||
│ └── DownloadAndCacheRemoteFileOperation
|
||||
│ ├── 从 APK 内 "下载" 资源
|
||||
│ ├── 验证文件完整性
|
||||
│ └── 保存到 UnpackBundleFiles 目录
|
||||
│
|
||||
└── 加载资源时
|
||||
└── _unpackFileSystem.LoadBundleFile(bundle)
|
||||
└── 从 UnpackBundleFiles 加载
|
||||
```
|
||||
|
||||
### 资源加载委托
|
||||
|
||||
```csharp
|
||||
// DefaultBuildinFileSystem.LoadBundleFile()
|
||||
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
|
||||
{
|
||||
// 需要解压的资源,委托给解压文件系统加载
|
||||
if (IsUnpackBundleFile(bundle))
|
||||
{
|
||||
return _unpackFileSystem.LoadBundleFile(bundle);
|
||||
}
|
||||
|
||||
// 普通资源直接从 StreamingAssets 加载
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与 DefaultBuildinFileSystem 集成
|
||||
|
||||
### 初始化流程
|
||||
|
||||
```csharp
|
||||
// DefaultBuildinFileSystem.OnCreate()
|
||||
public virtual void OnCreate(string packageName, string packageRoot)
|
||||
{
|
||||
// ... 基础初始化 ...
|
||||
|
||||
// 创建解压文件系统
|
||||
var remoteServices = new DefaultUnpackRemoteServices(_packageRoot);
|
||||
_unpackFileSystem = new DefaultUnpackFileSystem();
|
||||
|
||||
// 传递配置参数
|
||||
_unpackFileSystem.SetParameter(REMOTE_SERVICES, remoteServices);
|
||||
_unpackFileSystem.SetParameter(INSTALL_CLEAR_MODE, InstallClearMode);
|
||||
_unpackFileSystem.SetParameter(FILE_VERIFY_LEVEL, FileVerifyLevel);
|
||||
_unpackFileSystem.SetParameter(FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency);
|
||||
_unpackFileSystem.SetParameter(APPEND_FILE_EXTENSION, AppendFileExtension);
|
||||
_unpackFileSystem.SetParameter(DECRYPTION_SERVICES, DecryptionServices);
|
||||
_unpackFileSystem.SetParameter(COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices);
|
||||
|
||||
// 使用指定的解压根目录
|
||||
_unpackFileSystem.OnCreate(packageName, UnpackFileSystemRoot);
|
||||
}
|
||||
```
|
||||
|
||||
### 方法委托关系
|
||||
|
||||
| DefaultBuildinFileSystem 方法 | 解压资源时的委托目标 |
|
||||
|------------------------------|-------------------|
|
||||
| `LoadBundleFile()` | `_unpackFileSystem.LoadBundleFile()` |
|
||||
| `GetBundleFilePath()` | `_unpackFileSystem.GetBundleFilePath()` |
|
||||
| `ReadBundleFileData()` | `_unpackFileSystem.ReadBundleFileData()` |
|
||||
| `ReadBundleFileText()` | `_unpackFileSystem.ReadBundleFileText()` |
|
||||
| `DownloadFileAsync()` | `_unpackFileSystem.DownloadFileAsync()` |
|
||||
| `ClearCacheFilesAsync()` | `_unpackFileSystem.ClearCacheFilesAsync()` |
|
||||
|
||||
---
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景 1:Android 加密资源
|
||||
|
||||
```
|
||||
问题:Android 平台无法直接从 APK 内读取文件进行解密
|
||||
解决:先解压到沙盒,再从沙盒读取并解密
|
||||
|
||||
流程:
|
||||
1. 检测到加密资源 → IsUnpackBundleFile() = true
|
||||
2. 首次加载 → NeedUnpack() = true
|
||||
3. 执行解压 → DownloadFileAsync() 从 APK 复制到沙盒
|
||||
4. 后续加载 → NeedUnpack() = false,直接从沙盒加载
|
||||
```
|
||||
|
||||
### 场景 2:Android 原生文件
|
||||
|
||||
```
|
||||
问题:RawBundle 需要通过文件路径访问,APK 内路径不可直接访问
|
||||
解决:解压到沙盒,返回沙盒内的文件路径
|
||||
|
||||
流程:
|
||||
1. 检测到 RawBundle → IsUnpackBundleFile() = true
|
||||
2. 首次访问 → 解压到 UnpackBundleFiles
|
||||
3. GetBundleFilePath() 返回沙盒路径
|
||||
4. 业务代码使用标准文件 API 访问
|
||||
```
|
||||
|
||||
### 场景 3:普通 AssetBundle
|
||||
|
||||
```
|
||||
情况:Android 平台的普通(未加密)AssetBundle
|
||||
处理:不需要解压,Unity 可以直接从 APK 内加载
|
||||
|
||||
流程:
|
||||
1. IsUnpackBundleFile() = false
|
||||
2. 直接使用 AssetBundle.LoadFromFile() 加载
|
||||
3. Unity 内部处理 APK 访问
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
IFileSystem
|
||||
└── DefaultCacheFileSystem
|
||||
└── DefaultUnpackFileSystem ← 仅重写目录名称
|
||||
|
||||
IRemoteServices
|
||||
└── DefaultUnpackRemoteServices ← 本地 WWW 路径服务
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置参数
|
||||
|
||||
DefaultUnpackFileSystem 继承 DefaultCacheFileSystem 的所有参数:
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `REMOTE_SERVICES` | `IRemoteServices` | 由 DefaultUnpackRemoteServices 提供 |
|
||||
| `INSTALL_CLEAR_MODE` | `EOverwriteInstallClearMode` | 覆盖安装清理模式 |
|
||||
| `FILE_VERIFY_LEVEL` | `EFileVerifyLevel` | 文件验证级别 |
|
||||
| `FILE_VERIFY_MAX_CONCURRENCY` | `int` | 验证并发数 |
|
||||
| `APPEND_FILE_EXTENSION` | `bool` | 追加文件扩展名 |
|
||||
| `DECRYPTION_SERVICES` | `IDecryptionServices` | 解密服务 |
|
||||
| `COPY_LOCAL_FILE_SERVICES` | `ICopyLocalFileServices` | 本地拷贝服务 |
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **内部组件**:DefaultUnpackFileSystem 是 DefaultBuildinFileSystem 的内部组件,不建议单独使用
|
||||
2. **平台限定**:解压功能仅在 Android 和 OpenHarmony 平台生效
|
||||
3. **存储占用**:解压会额外占用设备存储空间(相当于资源的两份拷贝)
|
||||
4. **首次加载**:需要解压的资源首次加载会有额外耗时
|
||||
5. **自动管理**:解压缓存由系统自动管理,包括覆盖安装时的清理
|
||||
6. **继承完整性**:继承了 DefaultCacheFileSystem 的所有功能,包括断点续传、多线程验证等
|
||||
|
||||
---
|
||||
|
||||
## 与其他文件系统对比
|
||||
|
||||
| 特性 | DefaultUnpackFileSystem | DefaultCacheFileSystem |
|
||||
|------|------------------------|----------------------|
|
||||
| 数据来源 | StreamingAssets (本地) | 远程服务器 |
|
||||
| 主/备用地址 | 相同(本地路径) | 不同(CDN 地址) |
|
||||
| 存储目录 | UnpackXxxFiles | XxxFiles |
|
||||
| 使用方式 | 作为内部组件 | 独立使用 |
|
||||
| 继承关系 | 子类 | 父类 |
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 402224e40b04b0d458f12f5925d229b7
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,504 @@
|
||||
# DefaultWebRemoteFileSystem Web远程文件系统
|
||||
|
||||
## 模块概述
|
||||
|
||||
DefaultWebRemoteFileSystem 是 YooAsset 的 **Web 远程文件系统**,专为从远程服务器直接加载资源而设计。该文件系统不缓存文件到本地,每次都从远程 URL 加载资源,适用于 WebGL 平台的跨域资源加载或特殊的网络资源场景。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **无本地缓存**:直接从远程 URL 加载,不写入本地文件
|
||||
- **跨域支持**:通过 `IRemoteServices` 支持跨域资源下载
|
||||
- **Unity 缓存控制**:可选择禁用 Unity 的 Web 请求缓存
|
||||
- **加密支持**:支持 `IWebDecryptionServices` 解密 Web 资源
|
||||
- **失败重试**:内置下载失败自动重试机制
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **轻量级** | 无缓存管理,结构简洁 |
|
||||
| **即时加载** | 每次从远程获取最新资源 |
|
||||
| **跨域兼容** | 支持 WebGL 平台的跨域限制处理 |
|
||||
| **可配置** | 支持 Unity Web 缓存控制和自定义解密 |
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
DefaultWebRemoteFileSystem/
|
||||
├── DefaultWebRemoteFileSystem.cs # 文件系统主类
|
||||
└── Operation/ # 操作类
|
||||
├── DWRFSInitializeOperation.cs # 初始化操作
|
||||
├── DWRFSRequestPackageVersionOperation.cs # 请求版本操作
|
||||
├── DWRFSLoadPackageManifestOperation.cs # 加载清单操作
|
||||
└── DWRFSLoadBundleOperation.cs # 加载资源包操作
|
||||
```
|
||||
|
||||
### 依赖的共享模块
|
||||
|
||||
DefaultWebRemoteFileSystem 依赖 `WebGame` 目录下的共享操作类:
|
||||
|
||||
```
|
||||
FileSystem/WebGame/Operation/
|
||||
├── LoadWebAssetBundleOperation.cs # Web 资源包加载基类
|
||||
├── LoadWebNormalAssetBundleOperation.cs # 普通资源包加载
|
||||
├── LoadWebEncryptAssetBundleOperation.cs # 加密资源包加载
|
||||
├── RequestWebPackageVersionOperation.cs # 请求版本文件
|
||||
├── RequestWebPackageHashOperation.cs # 请求哈希文件
|
||||
└── LoadWebPackageManifestOperation.cs # 加载清单文件
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心类说明
|
||||
|
||||
### DefaultWebRemoteFileSystem
|
||||
|
||||
Web 远程文件系统的主类,实现 `IFileSystem` 接口。
|
||||
|
||||
#### 基本属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `PackageName` | `string` | 包裹名称 |
|
||||
| `FileRoot` | `string` | 始终返回空字符串(无本地存储) |
|
||||
| `FileCount` | `int` | 始终返回 0(无本地文件) |
|
||||
| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 |
|
||||
|
||||
#### 自定义参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `DisableUnityWebCache` | `bool` | `false` | 禁用 Unity 的网络缓存 |
|
||||
| `RemoteServices` | `IRemoteServices` | - | 远程服务接口(必需) |
|
||||
| `DecryptionServices` | `IWebDecryptionServices` | `null` | Web 解密服务接口 |
|
||||
| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单服务接口 |
|
||||
|
||||
#### 核心方法
|
||||
|
||||
```csharp
|
||||
// 生命周期
|
||||
void OnCreate(string packageName, string packageRoot);
|
||||
void OnDestroy();
|
||||
void SetParameter(string name, object value);
|
||||
|
||||
// 异步操作
|
||||
FSInitializeFileSystemOperation InitializeFileSystemAsync();
|
||||
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
|
||||
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
|
||||
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
|
||||
FSClearCacheFilesOperation ClearCacheFilesAsync(...); // 直接返回完成
|
||||
|
||||
// 不支持的操作
|
||||
FSDownloadFileOperation DownloadFileAsync(...); // 抛出 NotImplementedException
|
||||
string GetBundleFilePath(...); // 抛出 NotImplementedException
|
||||
byte[] ReadBundleFileData(...); // 抛出 NotImplementedException
|
||||
string ReadBundleFileText(...); // 抛出 NotImplementedException
|
||||
|
||||
// 文件查询(固定返回值)
|
||||
bool Belong(PackageBundle bundle); // 始终返回 true
|
||||
bool Exists(PackageBundle bundle); // 始终返回 true
|
||||
bool NeedDownload(PackageBundle bundle);// 始终返回 false
|
||||
bool NeedUnpack(PackageBundle bundle); // 始终返回 false
|
||||
bool NeedImport(PackageBundle bundle); // 始终返回 false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 操作类说明
|
||||
|
||||
### DWRFSInitializeOperation
|
||||
|
||||
初始化操作,立即完成(无需任何初始化工作)。
|
||||
|
||||
```csharp
|
||||
internal override void InternalStart()
|
||||
{
|
||||
Status = EOperationStatus.Succeed; // 直接成功
|
||||
}
|
||||
```
|
||||
|
||||
### DWRFSRequestPackageVersionOperation
|
||||
|
||||
请求包裹版本操作,从远程服务器获取版本文件。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
RequestPackageVersion
|
||||
└── RequestWebPackageVersionOperation
|
||||
└── 请求 {PackageName}_Version.txt
|
||||
├── 成功 → PackageVersion = 文件内容 → Succeed
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
#### 请求地址轮换
|
||||
|
||||
```csharp
|
||||
// 轮流使用主地址和备用地址
|
||||
if (_requestCount % 2 == 0)
|
||||
url = _remoteServices.GetRemoteMainURL(fileName);
|
||||
else
|
||||
url = _remoteServices.GetRemoteFallbackURL(fileName);
|
||||
|
||||
// 可选:添加时间戳防止缓存
|
||||
if (_appendTimeTicks)
|
||||
return $"{url}?{System.DateTime.UtcNow.Ticks}";
|
||||
```
|
||||
|
||||
### DWRFSLoadPackageManifestOperation
|
||||
|
||||
加载资源清单操作,从远程下载并解析清单。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
RequestWebPackageHash
|
||||
└── RequestWebPackageHashOperation
|
||||
└── 请求 {PackageName}_{Version}.hash
|
||||
├── 成功 → PackageHash
|
||||
└── 失败 → Failed
|
||||
↓
|
||||
LoadWebPackageManifest
|
||||
└── LoadWebPackageManifestOperation
|
||||
└── 请求 {PackageName}_{Version}.bytes
|
||||
├── 验证哈希
|
||||
└── 反序列化清单
|
||||
├── 成功 → Manifest → Succeed
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
### DWRFSLoadAssetBundleOperation
|
||||
|
||||
加载资源包操作,从远程 URL 直接加载 AssetBundle。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadWebAssetBundle
|
||||
├── 未加密 → LoadWebNormalAssetBundleOperation
|
||||
│ └── UnityWebRequestAssetBundle.GetAssetBundle()
|
||||
│ ├── 成功 → AssetBundle → AssetBundleResult
|
||||
│ └── 失败 → TryAgain 或 Failed
|
||||
│
|
||||
└── 已加密 → LoadWebEncryptAssetBundleOperation
|
||||
└── DownloadBytesRequest
|
||||
└── 下载原始字节
|
||||
└── IWebDecryptionServices.LoadAssetBundle()
|
||||
├── 成功 → AssetBundle → AssetBundleResult
|
||||
└── 失败 → TryAgain 或 Failed
|
||||
```
|
||||
|
||||
#### 状态机枚举
|
||||
|
||||
```csharp
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
LoadWebAssetBundle, // 加载 Web 资源包
|
||||
Done // 完成
|
||||
}
|
||||
```
|
||||
|
||||
#### 同步加载限制
|
||||
|
||||
```csharp
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = "WebGL platform not support sync load method !";
|
||||
UnityEngine.Debug.LogError(Error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 共享 Web 操作类
|
||||
|
||||
### LoadWebNormalAssetBundleOperation
|
||||
|
||||
普通(未加密)AssetBundle 的 Web 加载操作。
|
||||
|
||||
```
|
||||
CreateRequest
|
||||
└── DownloadAssetBundleRequest
|
||||
├── URL: 主地址或备用地址(轮换)
|
||||
├── DisableUnityWebCache: 是否禁用缓存
|
||||
├── FileHash: 用于 Unity 缓存键
|
||||
└── UnityCRC: CRC 验证
|
||||
↓
|
||||
CheckRequest
|
||||
├── 成功 → Result = AssetBundle
|
||||
└── 失败 → TryAgain(重试)或 Failed
|
||||
```
|
||||
|
||||
#### Unity Web 缓存机制
|
||||
|
||||
```csharp
|
||||
// 使用 Unity 的内置缓存
|
||||
var args = new DownloadAssetBundleRequestArgs(
|
||||
url,
|
||||
timeout: 0,
|
||||
watchdogTime: 0,
|
||||
disableUnityWebCache: _disableUnityWebCache,
|
||||
cacheHash: _bundle.FileHash, // 缓存键
|
||||
unityCRC: _bundle.UnityCRC // CRC 验证
|
||||
);
|
||||
```
|
||||
|
||||
### LoadWebEncryptAssetBundleOperation
|
||||
|
||||
加密 AssetBundle 的 Web 加载操作。
|
||||
|
||||
```
|
||||
CreateRequest
|
||||
└── 检查 DecryptionServices
|
||||
├── null → Failed
|
||||
└── 有效 → DownloadBytesRequest
|
||||
↓
|
||||
CheckRequest
|
||||
├── 下载成功 → LoadEncryptedAssetBundle()
|
||||
│ └── IWebDecryptionServices.LoadAssetBundle(fileData)
|
||||
│ ├── 解密成功 → Result = AssetBundle
|
||||
│ └── 解密失败 → Failed
|
||||
└── 下载失败 → TryAgain 或 Failed
|
||||
```
|
||||
|
||||
#### 加密资源加载
|
||||
|
||||
```csharp
|
||||
private AssetBundle LoadEncryptedAssetBundle(byte[] fileData)
|
||||
{
|
||||
var fileInfo = new WebDecryptFileInfo();
|
||||
fileInfo.BundleName = _bundle.BundleName;
|
||||
fileInfo.FileLoadCRC = _bundle.UnityCRC;
|
||||
fileInfo.FileData = fileData; // 下载的原始字节
|
||||
var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo);
|
||||
return decryptResult.Result;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 失败重试机制
|
||||
|
||||
Web 加载操作内置失败重试机制:
|
||||
|
||||
```csharp
|
||||
// 检测下载结果
|
||||
if (_unityAssetBundleRequestOp.Status == EDownloadRequestStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
Result = _unityAssetBundleRequestOp.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_failedTryAgain > 0)
|
||||
{
|
||||
_steps = ESteps.TryAgain;
|
||||
YooLogger.Warning($"Failed download : {url} Try again !");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _unityAssetBundleRequestOp.Error;
|
||||
}
|
||||
}
|
||||
|
||||
// 重新尝试下载(1秒后)
|
||||
if (_steps == ESteps.TryAgain)
|
||||
{
|
||||
_tryAgainTimer += Time.unscaledDeltaTime;
|
||||
if (_tryAgainTimer > 1f)
|
||||
{
|
||||
_tryAgainTimer = 0f;
|
||||
_failedTryAgain--;
|
||||
_steps = ESteps.CreateRequest; // 重新创建请求
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础配置
|
||||
|
||||
```csharp
|
||||
// 创建远程服务接口
|
||||
class GameRemoteServices : IRemoteServices
|
||||
{
|
||||
public string GetRemoteMainURL(string fileName)
|
||||
{
|
||||
return $"https://cdn.example.com/bundles/{fileName}";
|
||||
}
|
||||
public string GetRemoteFallbackURL(string fileName)
|
||||
{
|
||||
return $"https://cdn-backup.example.com/bundles/{fileName}";
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 Web 远程文件系统参数
|
||||
var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 初始化包裹(WebGL 模式)
|
||||
var initParams = new WebPlayModeParameters();
|
||||
initParams.WebServerFileSystemParameters = webServerParams;
|
||||
initParams.WebRemoteFileSystemParameters = webRemoteParams;
|
||||
var initOp = package.InitializeAsync(initParams);
|
||||
```
|
||||
|
||||
### 禁用 Unity Web 缓存
|
||||
|
||||
```csharp
|
||||
var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 禁用 Unity 的 Web 请求缓存(始终获取最新资源)
|
||||
webRemoteParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, true);
|
||||
```
|
||||
|
||||
### 配置 Web 解密服务
|
||||
|
||||
```csharp
|
||||
// 自定义 Web 解密服务
|
||||
class GameWebDecryptionServices : IWebDecryptionServices
|
||||
{
|
||||
public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
|
||||
{
|
||||
// 解密下载的字节数据
|
||||
byte[] decryptedData = Decrypt(fileInfo.FileData);
|
||||
AssetBundle bundle = AssetBundle.LoadFromMemory(decryptedData);
|
||||
return new WebDecryptResult { Result = bundle };
|
||||
}
|
||||
}
|
||||
|
||||
var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
// 设置 Web 解密服务
|
||||
webRemoteParams.AddParameter(
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES,
|
||||
new GameWebDecryptionServices()
|
||||
);
|
||||
```
|
||||
|
||||
### 跨域资源加载
|
||||
|
||||
```csharp
|
||||
// 跨域远程服务
|
||||
class CrossDomainRemoteServices : IRemoteServices
|
||||
{
|
||||
private readonly string _mainDomain;
|
||||
private readonly string _fallbackDomain;
|
||||
|
||||
public CrossDomainRemoteServices(string mainDomain, string fallbackDomain)
|
||||
{
|
||||
_mainDomain = mainDomain;
|
||||
_fallbackDomain = fallbackDomain;
|
||||
}
|
||||
|
||||
public string GetRemoteMainURL(string fileName)
|
||||
{
|
||||
// 主 CDN 域名
|
||||
return $"https://{_mainDomain}/assets/{fileName}";
|
||||
}
|
||||
|
||||
public string GetRemoteFallbackURL(string fileName)
|
||||
{
|
||||
// 备用 CDN 域名
|
||||
return $"https://{_fallbackDomain}/assets/{fileName}";
|
||||
}
|
||||
}
|
||||
|
||||
// 使用跨域服务
|
||||
var remoteServices = new CrossDomainRemoteServices(
|
||||
mainDomain: "cdn-us.example.com",
|
||||
fallbackDomain: "cdn-eu.example.com"
|
||||
);
|
||||
|
||||
var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(
|
||||
remoteServices: remoteServices
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数常量
|
||||
|
||||
```csharp
|
||||
// Unity 缓存控制
|
||||
FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE // bool: 禁用 Unity Web 缓存
|
||||
|
||||
// 服务接口
|
||||
FileSystemParametersDefine.REMOTE_SERVICES // IRemoteServices: 远程服务接口
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES // IWebDecryptionServices: Web 解密服务
|
||||
FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices: 清单服务
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
IFileSystem
|
||||
└── DefaultWebRemoteFileSystem
|
||||
|
||||
FSInitializeFileSystemOperation
|
||||
└── DWRFSInitializeOperation
|
||||
|
||||
FSRequestPackageVersionOperation
|
||||
└── DWRFSRequestPackageVersionOperation
|
||||
|
||||
FSLoadPackageManifestOperation
|
||||
└── DWRFSLoadPackageManifestOperation
|
||||
|
||||
FSLoadBundleOperation
|
||||
└── DWRFSLoadAssetBundleOperation
|
||||
|
||||
AsyncOperationBase
|
||||
├── LoadWebAssetBundleOperation (abstract)
|
||||
│ ├── LoadWebNormalAssetBundleOperation
|
||||
│ └── LoadWebEncryptAssetBundleOperation
|
||||
├── RequestWebPackageVersionOperation
|
||||
├── RequestWebPackageHashOperation
|
||||
└── LoadWebPackageManifestOperation
|
||||
|
||||
BundleResult
|
||||
└── AssetBundleResult
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与其他文件系统对比
|
||||
|
||||
| 特性 | DefaultWebRemoteFileSystem | DefaultCacheFileSystem | DefaultWebServerFileSystem |
|
||||
|------|---------------------------|------------------------|---------------------------|
|
||||
| 本地缓存 | ❌ 无 | ✅ 有 | ❌ 无 |
|
||||
| 支持 RawBundle | ❌ | ✅ | ❌ |
|
||||
| 同步加载 | ❌ | ✅ | ❌ |
|
||||
| 断点续传 | ❌ | ✅ | ❌ |
|
||||
| 跨域支持 | ✅ | ✅ | ✅ |
|
||||
| 适用场景 | WebGL 跨域 | 常规游戏 | WebGL 同域 |
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **仅支持 AssetBundle**:不支持 RawBundle 类型的资源加载
|
||||
2. **不支持同步加载**:WebGL 平台限制,`WaitForAsyncComplete()` 会直接返回失败
|
||||
3. **无本地缓存**:每次加载都从远程获取,注意网络流量
|
||||
4. **部分方法未实现**:`DownloadFileAsync`、`GetBundleFilePath`、`ReadBundleFileData`、`ReadBundleFileText` 会抛出异常
|
||||
5. **远程服务必需**:必须配置 `IRemoteServices` 接口
|
||||
6. **Unity 缓存**:默认使用 Unity 的 Web 请求缓存,可通过参数禁用
|
||||
7. **加密资源**:加密资源需要配置 `IWebDecryptionServices`(注意是 Web 专用接口,非 `IDecryptionServices`)
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f6744d0bcd43f84ea4279925784afb2
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,525 @@
|
||||
# DefaultWebServerFileSystem Web服务器文件系统
|
||||
|
||||
## 模块概述
|
||||
|
||||
DefaultWebServerFileSystem 是 YooAsset 的 **Web 服务器文件系统**,专为 WebGL 平台的**同域资源加载**而设计。该文件系统从与 WebGL 构建相同的服务器(StreamingAssets 目录)加载资源,通过 Catalog 目录文件管理内置资源清单。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **同域加载**:从 WebGL 构建所在服务器加载资源
|
||||
- **Catalog 管理**:通过目录文件追踪可用资源
|
||||
- **路径映射**:自动将本地路径转换为 WWW 路径
|
||||
- **Unity 缓存控制**:可选择禁用 Unity 的 Web 请求缓存
|
||||
- **加密支持**:支持 `IWebDecryptionServices` 解密 Web 资源
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **WebGL 内置资源** | 加载与 WebGL 构建一起部署的资源 |
|
||||
| **资源追踪** | 通过 Catalog 文件精确知道哪些资源可用 |
|
||||
| **无跨域问题** | 从同一服务器加载,避免 CORS 问题 |
|
||||
| **与 Buildin 对应** | WebGL 版本的 DefaultBuildinFileSystem |
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
DefaultWebServerFileSystem/
|
||||
├── DefaultWebServerFileSystem.cs # 文件系统主类
|
||||
└── Operation/ # 操作类
|
||||
├── DWSFSInitializeOperation.cs # 初始化操作
|
||||
├── DWSFSRequestPackageVersionOperation.cs # 请求版本操作
|
||||
├── DWSFSLoadPackageManifestOperation.cs # 加载清单操作
|
||||
├── DWSFSLoadBundleOperation.cs # 加载资源包操作
|
||||
└── internal/ # 内部操作类
|
||||
├── LoadWebServerCatalogFileOperation.cs # 加载目录文件
|
||||
├── RequestWebServerPackageVersionOperation.cs # 请求版本文件
|
||||
├── RequestWebServerPackageHashOperation.cs # 请求哈希文件
|
||||
└── LoadWebServerPackageManifestOperation.cs # 加载清单文件
|
||||
```
|
||||
|
||||
### 依赖的共享模块
|
||||
|
||||
DefaultWebServerFileSystem 依赖 `WebGame` 目录下的共享操作类:
|
||||
|
||||
```
|
||||
FileSystem/WebGame/Operation/
|
||||
├── LoadWebAssetBundleOperation.cs # Web 资源包加载基类
|
||||
├── LoadWebNormalAssetBundleOperation.cs # 普通资源包加载
|
||||
└── LoadWebEncryptAssetBundleOperation.cs # 加密资源包加载
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心类说明
|
||||
|
||||
### DefaultWebServerFileSystem
|
||||
|
||||
Web 服务器文件系统的主类,实现 `IFileSystem` 接口。
|
||||
|
||||
#### 内部类
|
||||
|
||||
```csharp
|
||||
public class FileWrapper
|
||||
{
|
||||
public string FileName { private set; get; }
|
||||
|
||||
public FileWrapper(string fileName)
|
||||
{
|
||||
FileName = fileName;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 基本属性
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `PackageName` | `string` | 包裹名称 |
|
||||
| `FileRoot` | `string` | Web 包裹根目录 |
|
||||
| `FileCount` | `int` | 始终返回 0 |
|
||||
| `DownloadBackend` | `IDownloadBackend` | 下载后台接口 |
|
||||
|
||||
#### 自定义参数
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `DisableUnityWebCache` | `bool` | `false` | 禁用 Unity 的网络缓存 |
|
||||
| `DecryptionServices` | `IWebDecryptionServices` | `null` | Web 解密服务接口 |
|
||||
| `ManifestServices` | `IManifestRestoreServices` | `null` | 清单服务接口 |
|
||||
|
||||
#### 核心方法
|
||||
|
||||
```csharp
|
||||
// 生命周期
|
||||
void OnCreate(string packageName, string packageRoot);
|
||||
void OnDestroy();
|
||||
void SetParameter(string name, object value);
|
||||
|
||||
// 异步操作
|
||||
FSInitializeFileSystemOperation InitializeFileSystemAsync();
|
||||
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
|
||||
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
|
||||
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
|
||||
FSClearCacheFilesOperation ClearCacheFilesAsync(...); // 直接返回完成
|
||||
|
||||
// 不支持的操作
|
||||
FSDownloadFileOperation DownloadFileAsync(...); // 抛出 NotImplementedException
|
||||
string GetBundleFilePath(...); // 抛出 NotImplementedException
|
||||
byte[] ReadBundleFileData(...); // 抛出 NotImplementedException
|
||||
string ReadBundleFileText(...); // 抛出 NotImplementedException
|
||||
|
||||
// 文件查询(基于 Catalog)
|
||||
bool Belong(PackageBundle bundle); // 检查是否在 _wrappers 字典中
|
||||
bool Exists(PackageBundle bundle); // 检查是否在 _wrappers 字典中
|
||||
bool NeedDownload(PackageBundle bundle);// 始终返回 false
|
||||
bool NeedUnpack(PackageBundle bundle); // 始终返回 false
|
||||
bool NeedImport(PackageBundle bundle); // 始终返回 false
|
||||
```
|
||||
|
||||
#### 内部方法
|
||||
|
||||
```csharp
|
||||
// 路径获取
|
||||
string GetDefaultWebPackageRoot(string packageName); // 默认包裹根目录
|
||||
string GetWebFileLoadPath(PackageBundle bundle); // 资源文件加载路径
|
||||
string GetWebPackageVersionFilePath(); // 版本文件路径
|
||||
string GetWebPackageHashFilePath(string packageVersion); // 哈希文件路径
|
||||
string GetWebPackageManifestFilePath(string packageVersion); // 清单文件路径
|
||||
string GetCatalogBinaryFileLoadPath(); // Catalog 文件路径
|
||||
|
||||
// Catalog 管理
|
||||
bool RecordCatalogFile(string bundleGUID, FileWrapper wrapper);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Catalog 目录系统
|
||||
|
||||
DefaultWebServerFileSystem 使用 Catalog 文件追踪可用的内置资源,这与 DefaultBuildinFileSystem 的机制相同。
|
||||
|
||||
### Catalog 文件
|
||||
|
||||
| 文件 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| Catalog 二进制文件 | `{PackageRoot}/{PackageName}_buildin.bytes` | 资源目录信息 |
|
||||
|
||||
### Catalog 数据结构
|
||||
|
||||
```csharp
|
||||
// _wrappers 字典:BundleGUID → FileWrapper
|
||||
protected readonly Dictionary<string, FileWrapper> _wrappers;
|
||||
|
||||
// FileWrapper 包含文件名信息
|
||||
public class FileWrapper
|
||||
{
|
||||
public string FileName { private set; get; }
|
||||
}
|
||||
```
|
||||
|
||||
### Belong 与 Exists 判断
|
||||
|
||||
```csharp
|
||||
public virtual bool Belong(PackageBundle bundle)
|
||||
{
|
||||
// 检查 Catalog 中是否包含该资源
|
||||
return _wrappers.ContainsKey(bundle.BundleGUID);
|
||||
}
|
||||
|
||||
public virtual bool Exists(PackageBundle bundle)
|
||||
{
|
||||
// 同样基于 Catalog 判断
|
||||
return _wrappers.ContainsKey(bundle.BundleGUID);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 操作类说明
|
||||
|
||||
### DWSFSInitializeOperation
|
||||
|
||||
初始化操作,加载 Catalog 目录文件。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadCatalogFile
|
||||
└── LoadWebServerCatalogFileOperation
|
||||
└── 请求 {PackageName}_buildin.bytes
|
||||
├── 下载二进制数据
|
||||
└── 反序列化 Catalog
|
||||
├── 验证 PackageName
|
||||
└── 遍历 Wrappers
|
||||
└── RecordCatalogFile()
|
||||
├── 成功 → Succeed
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
### LoadWebServerCatalogFileOperation
|
||||
|
||||
加载 Web 服务器 Catalog 文件的内部操作。
|
||||
|
||||
```csharp
|
||||
// 关键流程
|
||||
if (_steps == ESteps.LoadCatalog)
|
||||
{
|
||||
var catalog = CatalogTools.DeserializeFromBinary(_webDataRequestOp.Result);
|
||||
|
||||
// 验证包裹名称
|
||||
if (catalog.PackageName != _fileSystem.PackageName)
|
||||
{
|
||||
Error = $"Catalog file package name {catalog.PackageName} cannot match...";
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录所有内置资源
|
||||
foreach (var wrapper in catalog.Wrappers)
|
||||
{
|
||||
var fileWrapper = new DefaultWebServerFileSystem.FileWrapper(wrapper.FileName);
|
||||
_fileSystem.RecordCatalogFile(wrapper.BundleGUID, fileWrapper);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DWSFSRequestPackageVersionOperation
|
||||
|
||||
请求包裹版本操作,从 Web 服务器获取版本文件。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
RequestPackageVersion
|
||||
└── RequestWebServerPackageVersionOperation
|
||||
└── 请求 {FileRoot}/{PackageName}_Version.txt
|
||||
├── 转换为 WWW 路径
|
||||
└── 下载文本内容
|
||||
├── 成功 → PackageVersion
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
### DWSFSLoadPackageManifestOperation
|
||||
|
||||
加载资源清单操作,从 Web 服务器加载并解析清单。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
RequestWebPackageHash
|
||||
└── RequestWebServerPackageHashOperation
|
||||
└── 请求 {PackageName}_{Version}.hash
|
||||
├── 成功 → PackageHash
|
||||
└── 失败 → Failed
|
||||
↓
|
||||
LoadWebPackageManifest
|
||||
└── LoadWebServerPackageManifestOperation
|
||||
├── 请求 {PackageName}_{Version}.bytes
|
||||
├── 验证哈希
|
||||
└── 反序列化清单
|
||||
├── 成功 → Manifest
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
### LoadWebServerPackageManifestOperation
|
||||
|
||||
加载清单文件的内部操作,包含哈希验证。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
RequestFileData
|
||||
└── DownloadBytesRequest
|
||||
└── 下载清单二进制数据
|
||||
↓
|
||||
VerifyFileData
|
||||
└── ManifestTools.VerifyManifestData()
|
||||
├── 验证成功 → LoadManifest
|
||||
└── 验证失败 → Failed
|
||||
↓
|
||||
LoadManifest
|
||||
└── DeserializeManifestOperation
|
||||
├── 反序列化成功 → Manifest → Succeed
|
||||
└── 反序列化失败 → Failed
|
||||
```
|
||||
|
||||
### DWSFSLoadAssetBundleOperation
|
||||
|
||||
加载资源包操作,从 Web 服务器加载 AssetBundle。
|
||||
|
||||
```
|
||||
状态流程:
|
||||
LoadWebAssetBundle
|
||||
├── 获取文件路径 → 转换为 WWW 路径
|
||||
│
|
||||
├── 未加密 → LoadWebNormalAssetBundleOperation
|
||||
│ └── UnityWebRequestAssetBundle
|
||||
│ ├── 成功 → AssetBundleResult
|
||||
│ └── 失败 → Failed
|
||||
│
|
||||
└── 已加密 → LoadWebEncryptAssetBundleOperation
|
||||
└── DownloadBytesRequest
|
||||
└── IWebDecryptionServices.LoadAssetBundle()
|
||||
├── 成功 → AssetBundleResult
|
||||
└── 失败 → Failed
|
||||
```
|
||||
|
||||
#### 路径转换
|
||||
|
||||
```csharp
|
||||
// 获取本地文件路径
|
||||
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
|
||||
|
||||
// 转换为 WWW 请求路径
|
||||
string mainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
|
||||
|
||||
// 主 URL 和备用 URL 相同(同域加载)
|
||||
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue);
|
||||
options.SetURL(mainURL, mainURL);
|
||||
```
|
||||
|
||||
#### 同步加载限制
|
||||
|
||||
```csharp
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = "WebGL platform not support sync load method !";
|
||||
UnityEngine.Debug.LogError(Error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 路径映射机制
|
||||
|
||||
DefaultWebServerFileSystem 使用路径缓存优化性能:
|
||||
|
||||
```csharp
|
||||
// 文件路径缓存
|
||||
protected readonly Dictionary<string, string> _webFilePathMapping = new Dictionary<string, string>(10000);
|
||||
|
||||
public string GetWebFileLoadPath(PackageBundle bundle)
|
||||
{
|
||||
if (_webFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
|
||||
{
|
||||
// 组合路径:{WebPackageRoot}/{FileName}
|
||||
filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName);
|
||||
_webFilePathMapping.Add(bundle.BundleGUID, filePath);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
```
|
||||
|
||||
### 默认路径
|
||||
|
||||
```csharp
|
||||
protected string GetDefaultWebPackageRoot(string packageName)
|
||||
{
|
||||
// 使用默认的内置资源根目录(StreamingAssets)
|
||||
string rootDirectory = YooAssetSettingsData.GetYooDefaultBuildinRoot();
|
||||
return PathUtility.Combine(rootDirectory, packageName);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与 DefaultWebRemoteFileSystem 对比
|
||||
|
||||
| 特性 | DefaultWebServerFileSystem | DefaultWebRemoteFileSystem |
|
||||
|------|---------------------------|---------------------------|
|
||||
| 用途 | WebGL 同域内置资源 | WebGL 跨域远程资源 |
|
||||
| Catalog 系统 | ✅ 有 | ❌ 无 |
|
||||
| Belong/Exists | 基于 Catalog 判断 | 始终返回 true |
|
||||
| 远程服务 | ❌ 不需要 | ✅ 需要 IRemoteServices |
|
||||
| URL 生成 | 本地路径转 WWW | 远程服务接口生成 |
|
||||
| 主/备用地址 | 相同(同域) | 不同(可配置) |
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础配置
|
||||
|
||||
```csharp
|
||||
// 创建 Web 服务器文件系统参数
|
||||
var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
||||
|
||||
// 初始化包裹(WebGL 模式)
|
||||
var initParams = new WebPlayModeParameters();
|
||||
initParams.WebServerFileSystemParameters = webServerParams;
|
||||
initParams.WebRemoteFileSystemParameters = webRemoteParams; // 可选:跨域资源
|
||||
var initOp = package.InitializeAsync(initParams);
|
||||
```
|
||||
|
||||
### 自定义包裹根目录
|
||||
|
||||
```csharp
|
||||
// 创建参数时指定自定义路径
|
||||
var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(
|
||||
packageRoot: "Assets/StreamingAssets/MyCustomPath/DefaultPackage"
|
||||
);
|
||||
```
|
||||
|
||||
### 禁用 Unity Web 缓存
|
||||
|
||||
```csharp
|
||||
var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
||||
|
||||
// 禁用 Unity 的 Web 请求缓存
|
||||
webServerParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, true);
|
||||
```
|
||||
|
||||
### 配置 Web 解密服务
|
||||
|
||||
```csharp
|
||||
// 自定义 Web 解密服务
|
||||
class GameWebDecryptionServices : IWebDecryptionServices
|
||||
{
|
||||
public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
|
||||
{
|
||||
byte[] decryptedData = Decrypt(fileInfo.FileData);
|
||||
AssetBundle bundle = AssetBundle.LoadFromMemory(decryptedData);
|
||||
return new WebDecryptResult { Result = bundle };
|
||||
}
|
||||
}
|
||||
|
||||
var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
||||
|
||||
// 设置 Web 解密服务
|
||||
webServerParams.AddParameter(
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES,
|
||||
new GameWebDecryptionServices()
|
||||
);
|
||||
```
|
||||
|
||||
### WebGL 双文件系统配置
|
||||
|
||||
```csharp
|
||||
// WebGL 典型配置:内置 + 远程
|
||||
var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
|
||||
var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(
|
||||
remoteServices: new GameRemoteServices()
|
||||
);
|
||||
|
||||
var initParams = new WebPlayModeParameters();
|
||||
initParams.WebServerFileSystemParameters = webServerParams; // 同域内置资源
|
||||
initParams.WebRemoteFileSystemParameters = webRemoteParams; // 跨域热更资源
|
||||
|
||||
var initOp = package.InitializeAsync(initParams);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数常量
|
||||
|
||||
```csharp
|
||||
// Unity 缓存控制
|
||||
FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE // bool: 禁用 Unity Web 缓存
|
||||
|
||||
// 服务接口
|
||||
FileSystemParametersDefine.DECRYPTION_SERVICES // IWebDecryptionServices: Web 解密服务
|
||||
FileSystemParametersDefine.MANIFEST_SERVICES // IManifestRestoreServices: 清单服务
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
IFileSystem
|
||||
└── DefaultWebServerFileSystem
|
||||
|
||||
FSInitializeFileSystemOperation
|
||||
└── DWSFSInitializeOperation
|
||||
|
||||
FSRequestPackageVersionOperation
|
||||
└── DWSFSRequestPackageVersionOperation
|
||||
|
||||
FSLoadPackageManifestOperation
|
||||
└── DWSFSLoadPackageManifestOperation
|
||||
|
||||
FSLoadBundleOperation
|
||||
└── DWSFSLoadAssetBundleOperation
|
||||
|
||||
AsyncOperationBase
|
||||
├── LoadWebServerCatalogFileOperation
|
||||
├── RequestWebServerPackageVersionOperation
|
||||
├── RequestWebServerPackageHashOperation
|
||||
├── LoadWebServerPackageManifestOperation
|
||||
└── LoadWebAssetBundleOperation (共享)
|
||||
├── LoadWebNormalAssetBundleOperation
|
||||
└── LoadWebEncryptAssetBundleOperation
|
||||
|
||||
BundleResult
|
||||
└── AssetBundleResult
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与 DefaultBuildinFileSystem 对比
|
||||
|
||||
| 特性 | DefaultWebServerFileSystem | DefaultBuildinFileSystem |
|
||||
|------|---------------------------|-------------------------|
|
||||
| 平台 | WebGL | 非 WebGL(移动端、PC) |
|
||||
| 加载方式 | UnityWebRequest | AssetBundle.LoadFromFile |
|
||||
| Catalog 系统 | ✅ 相同机制 | ✅ 相同机制 |
|
||||
| 同步加载 | ❌ 不支持 | ✅ 支持 |
|
||||
| 解包机制 | ❌ 无 | ✅ 有(Android APK) |
|
||||
| 文件访问 | WWW 路径 | 本地文件路径 |
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **WebGL 专用**:此文件系统专为 WebGL 平台设计,非 WebGL 平台应使用 DefaultBuildinFileSystem
|
||||
2. **仅支持 AssetBundle**:不支持 RawBundle 类型的资源加载
|
||||
3. **不支持同步加载**:WebGL 平台限制,`WaitForAsyncComplete()` 会直接返回失败
|
||||
4. **Catalog 必需**:初始化时必须成功加载 Catalog 文件,否则无法确定资源归属
|
||||
5. **同域加载**:资源文件必须与 WebGL 构建在同一服务器上
|
||||
6. **部分方法未实现**:`DownloadFileAsync`、`GetBundleFilePath`、`ReadBundleFileData`、`ReadBundleFileText` 会抛出异常
|
||||
7. **加密资源**:加密资源需要配置 `IWebDecryptionServices`(Web 专用接口)
|
||||
8. **路径缓存**:内部使用字典缓存路径映射,提升重复访问性能
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac4e3eb80a469df408bb2af7d57b3f8c
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
464
Assets/YooAsset/Runtime/FileSystem/README.md
Normal file
464
Assets/YooAsset/Runtime/FileSystem/README.md
Normal file
@@ -0,0 +1,464 @@
|
||||
# FileSystem 文件系统模块
|
||||
|
||||
## 模块概述
|
||||
|
||||
FileSystem 是 YooAsset 资源管理系统的**文件访问抽象层**,负责统一管理不同来源的资源文件访问。该模块采用策略模式设计,通过 `IFileSystem` 接口抽象不同的文件存储策略,支持编辑器模拟、内置资源、缓存资源、WebGL 等多种场景。
|
||||
|
||||
### 核心职责
|
||||
|
||||
- 统一的文件系统接口抽象
|
||||
- 资源包文件的加载和管理
|
||||
- 资源清单的请求和加载
|
||||
- 缓存文件的验证和清理
|
||||
- 资源下载的调度和管理
|
||||
|
||||
---
|
||||
|
||||
## 设计目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **统一抽象** | 通过 IFileSystem 接口统一不同来源的文件访问 |
|
||||
| **策略模式** | 可插拔的文件系统实现,支持自定义扩展 |
|
||||
| **多场景支持** | 编辑器、单机、联机、WebGL 等多种运行模式 |
|
||||
| **灵活配置** | 通过参数系统支持丰富的自定义配置 |
|
||||
|
||||
---
|
||||
|
||||
## 架构概念
|
||||
|
||||
### 系统架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ ResourcePackage │
|
||||
│ (资源包管理) │
|
||||
└─────────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────▼───────────────────────────────┐
|
||||
│ PlayModeImpl │
|
||||
│ (运行模式实现) │
|
||||
│ 管理多个 IFileSystem,按优先级查询 │
|
||||
└─────────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────▼───────────────────────────────┐
|
||||
│ IFileSystem │
|
||||
│ (文件系统接口) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ DefaultEditorFileSystem │ 编辑器模拟文件系统 │
|
||||
│ DefaultBuildinFileSystem │ 内置资源文件系统 │
|
||||
│ DefaultCacheFileSystem │ 缓存资源文件系统 │
|
||||
│ DefaultUnpackFileSystem │ 解压资源文件系统 │
|
||||
│ DefaultWebServerFileSystem │ WebGL 服务器文件系统 │
|
||||
│ DefaultWebRemoteFileSystem │ WebGL 远程文件系统 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────▼───────────────────────────────┐
|
||||
│ BundleResult │
|
||||
│ (资源包加载结果) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ AssetBundleResult │ Unity AssetBundle 加载结果 │
|
||||
│ RawBundleResult │ 原生文件加载结果 │
|
||||
│ VirtualBundleResult│ 虚拟资源包结果(编辑器模拟) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 核心组件
|
||||
|
||||
- **IFileSystem**: 文件系统核心接口,定义所有文件操作的契约
|
||||
- **FileSystemParameters**: 文件系统参数配置,支持自定义参数注入
|
||||
- **BundleResult**: 资源包加载结果抽象,封装不同类型的加载结果
|
||||
- **FSOperation**: 文件系统操作基类,定义异步操作的抽象
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
FileSystem/
|
||||
├── Interface/ # 接口定义
|
||||
│ └── IFileSystem.cs # 文件系统核心接口
|
||||
│
|
||||
├── Operation/ # 操作基类定义
|
||||
│ ├── FSInitializeFileSystemOperation.cs # 初始化操作
|
||||
│ ├── FSRequestPackageVersionOperation.cs # 请求版本操作
|
||||
│ ├── FSLoadPackageManifestOperation.cs # 加载清单操作
|
||||
│ ├── FSLoadBundleOperation.cs # 加载资源包操作
|
||||
│ ├── FSDownloadFileOperation.cs # 下载文件操作
|
||||
│ ├── FSClearCacheFilesOperation.cs # 清理缓存操作
|
||||
│ ├── FSLoadAssetOperation.cs # 加载资源操作
|
||||
│ ├── FSLoadAllAssetsOperation.cs # 加载所有资源操作
|
||||
│ ├── FSLoadSubAssetsOperation.cs # 加载子资源操作
|
||||
│ └── FSLoadSceneOperation.cs # 加载场景操作
|
||||
│
|
||||
├── BundleResult/ # 资源包加载结果
|
||||
│ ├── BundleResult.cs # 结果基类
|
||||
│ ├── AssetBundleResult/ # AssetBundle 结果实现
|
||||
│ ├── RawBundleResult/ # 原生文件结果实现
|
||||
│ └── VirtualBundleResult/ # 虚拟资源包结果实现
|
||||
│
|
||||
├── WebGame/ # WebGL 相关操作
|
||||
│ └── Operation/ # WebGL 专用操作类
|
||||
│
|
||||
├── FileSystemParameters.cs # 文件系统参数
|
||||
├── FileSystemParametersDefine.cs # 参数名称常量定义
|
||||
├── FileVerifyHelper.cs # 文件校验辅助类
|
||||
├── EFileVerifyLevel.cs # 文件校验等级枚举
|
||||
├── EFileVerifyResult.cs # 文件校验结果枚举
|
||||
└── EFileClearMode.cs # 文件清理模式枚举
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心接口
|
||||
|
||||
### IFileSystem(文件系统接口)
|
||||
|
||||
定义文件系统的核心契约,所有文件系统实现都必须实现此接口。
|
||||
|
||||
```csharp
|
||||
internal interface IFileSystem
|
||||
{
|
||||
// 基本属性
|
||||
string PackageName { get; } // 包裹名称
|
||||
string FileRoot { get; } // 文件根目录
|
||||
int FileCount { get; } // 文件数量
|
||||
|
||||
// 生命周期
|
||||
void OnCreate(string packageName, string packageRoot);
|
||||
void OnDestroy();
|
||||
void SetParameter(string name, object value);
|
||||
|
||||
// 异步操作
|
||||
FSInitializeFileSystemOperation InitializeFileSystemAsync();
|
||||
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
|
||||
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
|
||||
FSLoadBundleOperation LoadBundleFile(PackageBundle bundle);
|
||||
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options);
|
||||
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options);
|
||||
|
||||
// 文件查询
|
||||
bool Belong(PackageBundle bundle); // 查询文件归属
|
||||
bool Exists(PackageBundle bundle); // 查询文件是否存在
|
||||
bool NeedDownload(PackageBundle bundle);// 是否需要下载
|
||||
bool NeedUnpack(PackageBundle bundle); // 是否需要解压
|
||||
bool NeedImport(PackageBundle bundle); // 是否需要导入
|
||||
|
||||
// 文件访问
|
||||
string GetBundleFilePath(PackageBundle bundle);
|
||||
byte[] ReadBundleFileData(PackageBundle bundle);
|
||||
string ReadBundleFileText(PackageBundle bundle);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 操作类定义
|
||||
|
||||
### 文件系统操作基类
|
||||
|
||||
所有文件系统操作都继承自 `AsyncOperationBase`,提供异步执行能力。
|
||||
|
||||
| 操作类 | 说明 | 输出属性 |
|
||||
|--------|------|----------|
|
||||
| `FSInitializeFileSystemOperation` | 初始化文件系统 | - |
|
||||
| `FSRequestPackageVersionOperation` | 请求包裹版本 | `PackageVersion` |
|
||||
| `FSLoadPackageManifestOperation` | 加载资源清单 | `Manifest` |
|
||||
| `FSLoadBundleOperation` | 加载资源包文件 | `Result`, `DownloadProgress`, `DownloadedBytes` |
|
||||
| `FSDownloadFileOperation` | 下载文件 | `DownloadedBytes`, `DownloadProgress` |
|
||||
| `FSClearCacheFilesOperation` | 清理缓存文件 | - |
|
||||
|
||||
### 资源加载操作基类
|
||||
|
||||
| 操作类 | 说明 | 输出属性 |
|
||||
|--------|------|----------|
|
||||
| `FSLoadAssetOperation` | 加载单个资源 | `Result` (Object) |
|
||||
| `FSLoadAllAssetsOperation` | 加载所有资源 | `Result` (Object[]) |
|
||||
| `FSLoadSubAssetsOperation` | 加载子资源 | `Result` (Object[]) |
|
||||
| `FSLoadSceneOperation` | 加载场景 | `Result` (Scene) |
|
||||
|
||||
---
|
||||
|
||||
## BundleResult 资源包结果
|
||||
|
||||
### 基类定义
|
||||
|
||||
```csharp
|
||||
internal abstract class BundleResult
|
||||
{
|
||||
// 资源包管理
|
||||
public abstract void UnloadBundleFile();
|
||||
public abstract string GetBundleFilePath();
|
||||
public abstract byte[] ReadBundleFileData();
|
||||
public abstract string ReadBundleFileText();
|
||||
|
||||
// 资源加载
|
||||
public abstract FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo);
|
||||
public abstract FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo);
|
||||
public abstract FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo);
|
||||
public abstract FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad);
|
||||
}
|
||||
```
|
||||
|
||||
### 实现类型
|
||||
|
||||
| 类型 | 说明 | 使用场景 |
|
||||
|------|------|----------|
|
||||
| `AssetBundleResult` | Unity AssetBundle 结果 | 正常构建的 AssetBundle 文件 |
|
||||
| `RawBundleResult` | 原生文件结果 | 原生文件(非 AssetBundle) |
|
||||
| `VirtualBundleResult` | 虚拟资源包结果 | 编辑器模拟模式 |
|
||||
|
||||
---
|
||||
|
||||
## 枚举定义
|
||||
|
||||
### EFileVerifyLevel(文件校验等级)
|
||||
|
||||
```csharp
|
||||
public enum EFileVerifyLevel
|
||||
{
|
||||
Low = 1, // 仅验证文件存在
|
||||
Middle = 2, // 验证文件大小
|
||||
High = 3 // 验证文件大小和 CRC
|
||||
}
|
||||
```
|
||||
|
||||
### EFileVerifyResult(文件校验结果)
|
||||
|
||||
```csharp
|
||||
internal enum EFileVerifyResult
|
||||
{
|
||||
Exception = -7, // 验证异常
|
||||
CacheNotFound = -6, // 未找到缓存信息
|
||||
InfoFileNotExisted = -5, // 信息文件不存在
|
||||
DataFileNotExisted = -4, // 数据文件不存在
|
||||
FileNotComplete = -3, // 文件内容不足
|
||||
FileOverflow = -2, // 文件内容溢出
|
||||
FileCrcError = -1, // 文件 CRC 不匹配
|
||||
None = 0, // 默认状态
|
||||
Succeed = 1 // 验证成功
|
||||
}
|
||||
```
|
||||
|
||||
### EFileClearMode(文件清理模式)
|
||||
|
||||
```csharp
|
||||
public enum EFileClearMode
|
||||
{
|
||||
ClearAllBundleFiles, // 清理所有资源文件
|
||||
ClearUnusedBundleFiles, // 清理未使用的资源文件
|
||||
ClearBundleFilesByLocations,// 按地址清理资源文件
|
||||
ClearBundleFilesByTags, // 按标签清理资源文件
|
||||
ClearAllManifestFiles, // 清理所有清单文件
|
||||
ClearUnusedManifestFiles // 清理未使用的清单文件
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数系统
|
||||
|
||||
### FileSystemParameters(文件系统参数)
|
||||
|
||||
用于创建和配置文件系统实例。
|
||||
|
||||
```csharp
|
||||
public class FileSystemParameters
|
||||
{
|
||||
public string FileSystemClass { get; } // 文件系统类名
|
||||
public string PackageRoot { get; } // 包裹根目录
|
||||
|
||||
public void AddParameter(string name, object value);
|
||||
}
|
||||
```
|
||||
|
||||
### 参数名称常量
|
||||
|
||||
```csharp
|
||||
public class FileSystemParametersDefine
|
||||
{
|
||||
// 文件校验
|
||||
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
|
||||
public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY";
|
||||
|
||||
// 下载配置
|
||||
public const string DOWNLOAD_MAX_CONCURRENCY = "DOWNLOAD_MAX_CONCURRENCY";
|
||||
public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DOWNLOAD_MAX_REQUEST_PER_FRAME";
|
||||
public const string DOWNLOAD_WATCH_DOG_TIME = "DOWNLOAD_WATCH_DOG_TIME";
|
||||
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "RESUME_DOWNLOAD_MINMUM_SIZE";
|
||||
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
|
||||
|
||||
// 服务接口
|
||||
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
|
||||
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
|
||||
public const string MANIFEST_SERVICES = "MANIFEST_SERVICES";
|
||||
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
|
||||
|
||||
// 功能开关
|
||||
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
|
||||
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
|
||||
public const string DISABLE_ONDEMAND_DOWNLOAD = "DISABLE_ONDEMAND_DOWNLOAD";
|
||||
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
|
||||
|
||||
// 模拟模式
|
||||
public const string VIRTUAL_WEBGL_MODE = "VIRTUAL_WEBGL_MODE";
|
||||
public const string VIRTUAL_DOWNLOAD_MODE = "VIRTUAL_DOWNLOAD_MODE";
|
||||
public const string VIRTUAL_DOWNLOAD_SPEED = "VIRTUAL_DOWNLOAD_SPEED";
|
||||
public const string ASYNC_SIMULATE_MIN_FRAME = "ASYNC_SIMULATE_MIN_FRAME";
|
||||
public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME";
|
||||
|
||||
// 其他
|
||||
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
|
||||
public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST";
|
||||
public const string UNPACK_FILE_SYSTEM_ROOT = "UNPACK_FILE_SYSTEM_ROOT";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 创建文件系统参数
|
||||
|
||||
```csharp
|
||||
// 编辑器文件系统
|
||||
var editorParams = FileSystemParameters.CreateDefaultEditorFileSystemParameters(
|
||||
packageRoot: "Assets/GameRes/Bundles"
|
||||
);
|
||||
|
||||
// 内置文件系统
|
||||
var buildinParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(
|
||||
decryptionServices: new MyDecryptionServices()
|
||||
);
|
||||
|
||||
// 缓存文件系统
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(
|
||||
remoteServices: new MyRemoteServices(),
|
||||
decryptionServices: new MyDecryptionServices()
|
||||
);
|
||||
|
||||
// WebGL 服务器文件系统
|
||||
var webServerParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(
|
||||
disableUnityWebCache: true
|
||||
);
|
||||
|
||||
// WebGL 远程文件系统
|
||||
var webRemoteParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(
|
||||
remoteServices: new MyRemoteServices(),
|
||||
disableUnityWebCache: true
|
||||
);
|
||||
```
|
||||
|
||||
### 添加自定义参数
|
||||
|
||||
```csharp
|
||||
var cacheParams = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
|
||||
|
||||
// 设置文件校验级别
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, EFileVerifyLevel.High);
|
||||
|
||||
// 设置下载并发数
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY, 16);
|
||||
|
||||
// 设置看门狗时间
|
||||
cacheParams.AddParameter(FileSystemParametersDefine.DOWNLOAD_WATCH_DOG_TIME, 30);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件系统实现
|
||||
|
||||
| 文件系统 | 说明 | 适用场景 |
|
||||
|----------|------|----------|
|
||||
| `DefaultEditorFileSystem` | 编辑器模拟文件系统 | 编辑器开发,快速迭代 |
|
||||
| `DefaultBuildinFileSystem` | 内置资源文件系统 | StreamingAssets 内置资源 |
|
||||
| `DefaultCacheFileSystem` | 缓存资源文件系统 | 下载并缓存的远程资源 |
|
||||
| `DefaultUnpackFileSystem` | 解压资源文件系统 | 从内置解压到沙盒的资源 |
|
||||
| `DefaultWebServerFileSystem` | WebGL 服务器文件系统 | WebGL 本地服务器资源 |
|
||||
| `DefaultWebRemoteFileSystem` | WebGL 远程文件系统 | WebGL 远程 CDN 资源 |
|
||||
|
||||
---
|
||||
|
||||
## 设计模式
|
||||
|
||||
### 策略模式
|
||||
|
||||
通过 `IFileSystem` 接口实现可插拔的文件系统:
|
||||
|
||||
```
|
||||
IFileSystem (接口)
|
||||
│
|
||||
├── DefaultEditorFileSystem
|
||||
├── DefaultBuildinFileSystem
|
||||
├── DefaultCacheFileSystem
|
||||
│ └── DefaultUnpackFileSystem (继承)
|
||||
├── DefaultWebServerFileSystem
|
||||
└── DefaultWebRemoteFileSystem
|
||||
```
|
||||
|
||||
### 工厂模式
|
||||
|
||||
`FileSystemParameters` 通过反射创建文件系统实例:
|
||||
|
||||
```csharp
|
||||
internal IFileSystem CreateFileSystem(string packageName)
|
||||
{
|
||||
Type classType = Type.GetType(FileSystemClass);
|
||||
var instance = (IFileSystem)Activator.CreateInstance(classType, true);
|
||||
|
||||
foreach (var param in CreateParameters)
|
||||
instance.SetParameter(param.Key, param.Value);
|
||||
|
||||
instance.OnCreate(packageName, PackageRoot);
|
||||
return instance;
|
||||
}
|
||||
```
|
||||
|
||||
### 模板方法模式
|
||||
|
||||
`BundleResult` 定义资源加载的算法骨架,子类实现具体加载逻辑:
|
||||
|
||||
```
|
||||
BundleResult (抽象基类)
|
||||
│
|
||||
├── AssetBundleResult → AssetBundle.LoadAssetAsync
|
||||
├── RawBundleResult → 直接读取文件
|
||||
└── VirtualBundleResult → AssetDatabase.LoadAssetAtPath
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类继承关系
|
||||
|
||||
```
|
||||
AsyncOperationBase
|
||||
│
|
||||
├── FSInitializeFileSystemOperation
|
||||
├── FSRequestPackageVersionOperation
|
||||
├── FSLoadPackageManifestOperation
|
||||
├── FSLoadBundleOperation
|
||||
│ └── FSLoadBundleCompleteOperation
|
||||
├── FSDownloadFileOperation
|
||||
├── FSClearCacheFilesOperation
|
||||
│ └── FSClearCacheFilesCompleteOperation
|
||||
├── FSLoadAssetOperation
|
||||
├── FSLoadAllAssetsOperation
|
||||
├── FSLoadSubAssetsOperation
|
||||
└── FSLoadSceneOperation
|
||||
|
||||
BundleResult
|
||||
│
|
||||
├── AssetBundleResult
|
||||
├── RawBundleResult
|
||||
└── VirtualBundleResult
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **文件系统选择**:根据运行模式选择合适的文件系统组合
|
||||
2. **参数配置**:合理配置校验等级和并发数,平衡性能和安全性
|
||||
3. **自定义扩展**:可通过实现 `IFileSystem` 接口创建自定义文件系统
|
||||
4. **WebGL 限制**:WebGL 平台不支持持久化缓存,需使用专用文件系统
|
||||
5. **解密服务**:加密资源需要提供对应的解密服务实现
|
||||
7
Assets/YooAsset/Runtime/FileSystem/README.md.meta
Normal file
7
Assets/YooAsset/Runtime/FileSystem/README.md.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3775825eb24ba6c46b557a3c96a09397
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user