mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-14 19:40:47 +00:00
代码重构
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// 外部友元
|
||||
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Extension.Editor")]
|
||||
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]
|
||||
@@ -36,7 +36,8 @@ namespace YooAsset.Editor
|
||||
// 清空首包资源目录
|
||||
if (copyOption == EBundledCopyOption.ClearAndCopyAll || copyOption == EBundledCopyOption.ClearAndCopyByTags)
|
||||
{
|
||||
EditorFileUtility.ClearFolder(bundledRootDirectory);
|
||||
EditorFileUtility.DeleteDirectory(bundledRootDirectory);
|
||||
EditorFileUtility.CreateDirectory(bundledRootDirectory);
|
||||
}
|
||||
|
||||
// 拷贝补丁清单文件
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace YooAsset.Editor
|
||||
[Serializable]
|
||||
public class EditorAssetInfo : IComparable<EditorAssetInfo>
|
||||
{
|
||||
[NonSerialized]
|
||||
private string _fileExtension = null;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -118,28 +118,6 @@ namespace YooAsset.Editor
|
||||
File.Copy(sourcePath, destPath, overwrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空文件夹
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">要清理的文件夹路径</param>
|
||||
public static void ClearFolder(string directoryPath)
|
||||
{
|
||||
if (Directory.Exists(directoryPath) == false)
|
||||
return;
|
||||
|
||||
string[] allFiles = Directory.GetFiles(directoryPath);
|
||||
for (int i = 0; i < allFiles.Length; i++)
|
||||
{
|
||||
File.Delete(allFiles[i]);
|
||||
}
|
||||
|
||||
string[] allFolders = Directory.GetDirectories(directoryPath);
|
||||
for (int i = 0; i < allFolders.Length; i++)
|
||||
{
|
||||
Directory.Delete(allFolders[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件字节大小
|
||||
/// </summary>
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2018-2021 何冠峰
|
||||
Copyright 2021-2025 TuYoo Games
|
||||
Copyright 2021-2026 TuYoo Games
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// 内部友元
|
||||
[assembly: InternalsVisibleTo("YooAsset.Editor")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Test")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Test.Editor")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Tests")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Tests.Editor")]
|
||||
|
||||
// 外部友元
|
||||
[assembly: InternalsVisibleTo("YooAsset.MiniGame")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Extension")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.Extension.Editor")]
|
||||
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]
|
||||
@@ -8,7 +8,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 异步操作基类
|
||||
/// </summary>
|
||||
public abstract class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
|
||||
public abstract partial class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
|
||||
{
|
||||
private List<AsyncOperationBase> _children;
|
||||
private Action<AsyncOperationBase> _completedCallback;
|
||||
|
||||
@@ -25,5 +25,13 @@ namespace YooAsset
|
||||
/// 已失败
|
||||
/// </summary>
|
||||
Failed,
|
||||
|
||||
#if YOOASSET_LEGACY_API
|
||||
/// <summary>
|
||||
/// v2.3 兼容别名
|
||||
/// </summary>
|
||||
[System.Obsolete("Use Succeeded instead.")]
|
||||
Succeed = Succeeded,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// 按资源地址清理缓存文件
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ClearParameter 类型:string / string[] / List<string>
|
||||
/// ClearParameter 类型:string / array / list
|
||||
/// </remarks>
|
||||
internal class EvictionByLocationsPolicy : ICacheEvictionPolicy
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// 按标签清理缓存文件
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ClearParameter 类型:string / string[] / List<string>
|
||||
/// ClearParameter 类型:string / array / list
|
||||
/// </remarks>
|
||||
internal class EvictionByTagsPolicy : ICacheEvictionPolicy
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f79d08cddb5196408cff10f6750ae69
|
||||
guid: da061aaa46527ed44a052b269aeeaeb0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
191
Assets/YooAsset/Runtime/Compatibility/CompatibleDownloader.cs
Normal file
191
Assets/YooAsset/Runtime/Compatibility/CompatibleDownloader.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
// YooAsset v2.3 兼容层 - DownloaderOperation 兼容
|
||||
// 通过 partial class 为 DownloaderOperation 补充 v2.3 的旧式回调属性和 BeginDownload 方法。
|
||||
|
||||
using System;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
#region v2.3 委托和数据类型
|
||||
/// <summary>
|
||||
/// v2.3 下载器结束回调委托
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadCompleted event instead.")]
|
||||
public delegate void DownloaderFinish(DownloaderFinishData data);
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 下载进度更新回调委托
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadProgressChanged event instead.")]
|
||||
public delegate void DownloadUpdateDelegate(DownloadUpdateData data);
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 下载错误回调委托(重命名以避免与 v3 event DownloadError 冲突)
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadError event instead.")]
|
||||
public delegate void DownloadErrorDelegate(DownloadErrorData data);
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 开始下载文件回调委托
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadFileStarted event instead.")]
|
||||
public delegate void DownloadFileBeginDelegate(DownloadFileData data);
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 下载器结束数据
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadCompletedEventArgs instead.")]
|
||||
public struct DownloaderFinishData
|
||||
{
|
||||
public string PackageName;
|
||||
public bool Succeed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 下载进度更新数据
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadProgressChangedEventArgs instead.")]
|
||||
public struct DownloadUpdateData
|
||||
{
|
||||
public string PackageName;
|
||||
public float Progress;
|
||||
public int TotalDownloadCount;
|
||||
public int CurrentDownloadCount;
|
||||
public long TotalDownloadBytes;
|
||||
public long CurrentDownloadBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 下载错误数据
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadErrorEventArgs instead.")]
|
||||
public struct DownloadErrorData
|
||||
{
|
||||
public string PackageName;
|
||||
public string FileName;
|
||||
public string ErrorInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 下载文件数据
|
||||
/// </summary>
|
||||
[Obsolete("Use DownloadFileStartedEventArgs instead.")]
|
||||
public struct DownloadFileData
|
||||
{
|
||||
public string PackageName;
|
||||
public string FileName;
|
||||
public long FileSize;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public abstract partial class DownloaderOperation
|
||||
{
|
||||
private DownloaderFinish _downloadFinishCallback;
|
||||
private DownloadUpdateDelegate _downloadUpdateCallback;
|
||||
private DownloadErrorDelegate _downloadErrorCallback;
|
||||
private DownloadFileBeginDelegate _downloadFileBeginCallback;
|
||||
|
||||
private bool _finishBridged;
|
||||
private bool _updateBridged;
|
||||
private bool _errorBridged;
|
||||
private bool _fileBeginBridged;
|
||||
|
||||
[Obsolete("Use DownloadCompleted event instead.")]
|
||||
public DownloaderFinish DownloadFinishCallback
|
||||
{
|
||||
get => _downloadFinishCallback;
|
||||
set
|
||||
{
|
||||
_downloadFinishCallback = value;
|
||||
if (!_finishBridged && value != null)
|
||||
{
|
||||
_finishBridged = true;
|
||||
DownloadCompleted += args =>
|
||||
{
|
||||
_downloadFinishCallback?.Invoke(new DownloaderFinishData
|
||||
{
|
||||
PackageName = args.PackageName,
|
||||
Succeed = args.Succeeded
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use DownloadProgressChanged event instead.")]
|
||||
public DownloadUpdateDelegate DownloadUpdateCallback
|
||||
{
|
||||
get => _downloadUpdateCallback;
|
||||
set
|
||||
{
|
||||
_downloadUpdateCallback = value;
|
||||
if (!_updateBridged && value != null)
|
||||
{
|
||||
_updateBridged = true;
|
||||
DownloadProgressChanged += args =>
|
||||
{
|
||||
_downloadUpdateCallback?.Invoke(new DownloadUpdateData
|
||||
{
|
||||
PackageName = args.PackageName,
|
||||
Progress = args.Progress,
|
||||
TotalDownloadCount = args.TotalDownloadCount,
|
||||
CurrentDownloadCount = args.CurrentDownloadCount,
|
||||
TotalDownloadBytes = args.TotalDownloadBytes,
|
||||
CurrentDownloadBytes = args.CurrentDownloadBytes
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use DownloadError event instead.")]
|
||||
public DownloadErrorDelegate DownloadErrorCallback
|
||||
{
|
||||
get => _downloadErrorCallback;
|
||||
set
|
||||
{
|
||||
_downloadErrorCallback = value;
|
||||
if (!_errorBridged && value != null)
|
||||
{
|
||||
_errorBridged = true;
|
||||
DownloadError += args =>
|
||||
{
|
||||
_downloadErrorCallback?.Invoke(new DownloadErrorData
|
||||
{
|
||||
PackageName = args.PackageName,
|
||||
FileName = args.FileName,
|
||||
ErrorInfo = args.ErrorInfo
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use DownloadFileStarted event instead.")]
|
||||
public DownloadFileBeginDelegate DownloadFileBeginCallback
|
||||
{
|
||||
get => _downloadFileBeginCallback;
|
||||
set
|
||||
{
|
||||
_downloadFileBeginCallback = value;
|
||||
if (!_fileBeginBridged && value != null)
|
||||
{
|
||||
_fileBeginBridged = true;
|
||||
DownloadFileStarted += args =>
|
||||
{
|
||||
_downloadFileBeginCallback?.Invoke(new DownloadFileData
|
||||
{
|
||||
PackageName = args.PackageName,
|
||||
FileName = args.FileName,
|
||||
FileSize = args.FileSize
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use StartDownload() instead.")]
|
||||
public void BeginDownload() => StartDownload();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec9d17e765ccd4642aa3aa9ca0580799
|
||||
guid: 5c410769c5f99174897f030039b64116
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
293
Assets/YooAsset/Runtime/Compatibility/CompatibleFileSystem.cs
Normal file
293
Assets/YooAsset/Runtime/Compatibility/CompatibleFileSystem.cs
Normal file
@@ -0,0 +1,293 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
// YooAsset v2.3 兼容层 - 文件系统参数兼容
|
||||
// 通过 partial class 为 FileSystemParameters 补充 v2.3 旧工厂方法,
|
||||
// 并恢复 FileSystemParametersDefine、IRemoteServices、IManifestRestoreServices 等旧类型。
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
#region FileSystemParameters partial
|
||||
|
||||
public partial class FileSystemParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3 属性名,转发到 v3 的 FileSystemTypeName
|
||||
/// </summary>
|
||||
[Obsolete("Use FileSystemTypeName instead.")]
|
||||
public string FileSystemClass
|
||||
{
|
||||
get { return FileSystemTypeName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容 v2.3 REMOTE_SERVICES 参数对象
|
||||
/// </summary>
|
||||
[Obsolete("Use AddParameter(EFileSystemParameter.RemoteService, IRemoteService) instead.")]
|
||||
public void AddParameter(string paramName, IRemoteServices value)
|
||||
{
|
||||
if (paramName == FileSystemParametersDefine.REMOTE_SERVICES && value != null)
|
||||
AddParameter(paramName, new RemoteServicesAdapter(value));
|
||||
else
|
||||
AddParameter(paramName, (object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容 v2.3 MANIFEST_SERVICES 参数对象
|
||||
/// </summary>
|
||||
[Obsolete("Use AddParameter(EFileSystemParameter.ManifestDecryptor, IManifestDecryptor) instead.")]
|
||||
public void AddParameter(string paramName, IManifestRestoreServices value)
|
||||
{
|
||||
if (paramName == FileSystemParametersDefine.MANIFEST_SERVICES && value != null)
|
||||
AddParameter(paramName, new ManifestRestoreServicesAdapter(value));
|
||||
else
|
||||
AddParameter(paramName, (object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容 v2.3 INSTALL_CLEAR_MODE 枚举值
|
||||
/// </summary>
|
||||
[Obsolete("Use AddParameter(EFileSystemParameter.InstallCleanupMode, EInstallCleanupMode) instead.")]
|
||||
public void AddParameter(string paramName, EOverwriteInstallClearMode value)
|
||||
{
|
||||
if (paramName == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
|
||||
AddParameter(paramName, (EInstallCleanupMode)(int)value);
|
||||
else
|
||||
AddParameter(paramName, (object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 旧拼写入口,转发到 CreateDefaultBuiltinFileSystemParameters
|
||||
/// </summary>
|
||||
[Obsolete("Use CreateDefaultBuiltinFileSystemParameters instead. IDecryptionServices is no longer supported; pass null or migrate to IBundleDecryptor.")]
|
||||
public static FileSystemParameters CreateDefaultBuildinFileSystemParameters(IDecryptionServices decryptionServices = null, string packageRoot = null)
|
||||
{
|
||||
return CreateDefaultBuiltinFileSystemParameters(packageRoot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 缓存文件系统入口,转发到 CreateDefaultSandboxFileSystemParameters
|
||||
/// </summary>
|
||||
[Obsolete("Use CreateDefaultSandboxFileSystemParameters instead. IDecryptionServices is no longer supported; pass null or migrate to IBundleDecryptor.")]
|
||||
public static FileSystemParameters CreateDefaultCacheFileSystemParameters(IRemoteServices remoteServices, IDecryptionServices decryptionServices = null, string packageRoot = null)
|
||||
{
|
||||
var adapter = remoteServices != null ? new RemoteServicesAdapter(remoteServices) : null;
|
||||
return CreateDefaultSandboxFileSystemParameters(adapter, packageRoot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 WebServer 文件系统入口
|
||||
/// </summary>
|
||||
[Obsolete("Use CreateDefaultWebServerFileSystemParameters(bool) instead. IWebDecryptionServices is no longer supported.")]
|
||||
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebDecryptionServices decryptionServices, bool disableUnityWebCache = false)
|
||||
{
|
||||
return CreateDefaultWebServerFileSystemParameters(disableUnityWebCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 WebRemote 文件系统入口
|
||||
/// </summary>
|
||||
[Obsolete("Use CreateDefaultWebRemoteFileSystemParameters(IRemoteService, bool) instead. IWebDecryptionServices is no longer supported.")]
|
||||
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
|
||||
{
|
||||
var adapter = remoteServices != null ? new RemoteServicesAdapter(remoteServices) : null;
|
||||
return CreateDefaultWebRemoteFileSystemParameters(adapter, disableUnityWebCache);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FileSystemParametersDefine
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 文件系统参数常量定义
|
||||
/// </summary>
|
||||
[Obsolete("Use EFileSystemParameter enum instead.")]
|
||||
public static class FileSystemParametersDefine
|
||||
{
|
||||
public const string FILE_VERIFY_LEVEL = "FileVerifyLevel";
|
||||
public const string FILE_VERIFY_MAX_CONCURRENCY = "FileVerifyMaxConcurrency";
|
||||
public const string INSTALL_CLEAR_MODE = "InstallCleanupMode";
|
||||
public const string REMOTE_SERVICES = "RemoteService";
|
||||
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
|
||||
public const string MANIFEST_SERVICES = "ManifestDecryptor";
|
||||
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
|
||||
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
|
||||
public const string DISABLE_UNITY_WEB_CACHE = "DisableUnityWebCache";
|
||||
public const string DISABLE_ONDEMAND_DOWNLOAD = "DownloadDisableOndemand";
|
||||
public const string DOWNLOAD_MAX_CONCURRENCY = "DownloadMaxConcurrency";
|
||||
public const string DOWNLOAD_MAX_REQUEST_PER_FRAME = "DownloadMaxRequestPerFrame";
|
||||
public const string DOWNLOAD_WATCH_DOG_TIME = "DownloadWatchdogTimeout";
|
||||
public const string RESUME_DOWNLOAD_MINMUM_SIZE = "DownloadResumeMinimumSize";
|
||||
public const string RESUME_DOWNLOAD_RESPONSE_CODES = "RESUME_DOWNLOAD_RESPONSE_CODES";
|
||||
public const string VIRTUAL_WEBGL_MODE = "VirtualWebglMode";
|
||||
public const string VIRTUAL_DOWNLOAD_MODE = "VirtualDownloadMode";
|
||||
public const string VIRTUAL_DOWNLOAD_SPEED = "VirtualDownloadSpeed";
|
||||
public const string ASYNC_SIMULATE_MIN_FRAME = "AsyncSimulateMinFrame";
|
||||
public const string ASYNC_SIMULATE_MAX_FRAME = "AsyncSimulateMaxFrame";
|
||||
public const string COPY_BUILDIN_PACKAGE_MANIFEST = "CopyBuiltinPackageManifest";
|
||||
public const string COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT = "CopyBuiltinPackageManifestDestRoot";
|
||||
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
|
||||
public const string UNPACK_FILE_SYSTEM_ROOT = "UnpackFileSystemRoot";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region EOverwriteInstallClearMode
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 覆盖安装清理模式(v3 改为 EInstallCleanupMode)
|
||||
/// </summary>
|
||||
[Obsolete("Use EInstallCleanupMode instead.")]
|
||||
public enum EOverwriteInstallClearMode
|
||||
{
|
||||
None = 0,
|
||||
ClearAllCacheFiles = 1,
|
||||
ClearAllBundleFiles = 2,
|
||||
ClearAllManifestFiles = 3,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRemoteServices
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 远端资源地址查询服务接口
|
||||
/// </summary>
|
||||
[Obsolete("Implement IRemoteService instead.")]
|
||||
public interface IRemoteServices
|
||||
{
|
||||
string GetRemoteMainURL(string fileName);
|
||||
string GetRemoteFallbackURL(string fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 v2.3 IRemoteServices 适配为 v3 IRemoteService
|
||||
/// </summary>
|
||||
internal sealed class RemoteServicesAdapter : IRemoteService
|
||||
{
|
||||
private readonly IRemoteServices _legacy;
|
||||
|
||||
public RemoteServicesAdapter(IRemoteServices legacy)
|
||||
{
|
||||
_legacy = legacy;
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> GetRemoteUrls(string fileName)
|
||||
{
|
||||
var urls = new List<string>(2);
|
||||
string main = _legacy.GetRemoteMainURL(fileName);
|
||||
if (!string.IsNullOrEmpty(main))
|
||||
urls.Add(main);
|
||||
string fallback = _legacy.GetRemoteFallbackURL(fileName);
|
||||
if (!string.IsNullOrEmpty(fallback))
|
||||
urls.Add(fallback);
|
||||
return urls;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IManifestRestoreServices
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 资源清单文件处理服务接口
|
||||
/// </summary>
|
||||
[Obsolete("Implement IManifestDecryptor instead.")]
|
||||
public interface IManifestRestoreServices
|
||||
{
|
||||
byte[] RestoreManifest(byte[] fileData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 v2.3 IManifestRestoreServices 适配为 v3 IManifestDecryptor
|
||||
/// </summary>
|
||||
internal sealed class ManifestRestoreServicesAdapter : IManifestDecryptor
|
||||
{
|
||||
private readonly IManifestRestoreServices _legacy;
|
||||
|
||||
public ManifestRestoreServicesAdapter(IManifestRestoreServices legacy)
|
||||
{
|
||||
_legacy = legacy;
|
||||
}
|
||||
|
||||
public byte[] Decrypt(byte[] fileData)
|
||||
{
|
||||
return _legacy.RestoreManifest(fileData);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDecryptionServices / IWebDecryptionServices
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 解密文件信息(仅用于旧接口编译兼容)
|
||||
/// </summary>
|
||||
[Obsolete("v3 has split decryption into dedicated decryptor interfaces. Manual migration required.")]
|
||||
public struct DecryptFileInfo
|
||||
{
|
||||
public string BundleName;
|
||||
public string FileLoadPath;
|
||||
public uint FileLoadCRC;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 解密结果(仅用于旧接口编译兼容)
|
||||
/// </summary>
|
||||
[Obsolete("v3 has split decryption into dedicated decryptor interfaces. Manual migration required.")]
|
||||
public struct DecryptResult
|
||||
{
|
||||
public AssetBundle Result;
|
||||
public AssetBundleCreateRequest CreateRequest;
|
||||
public Stream ManagedStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 加密文件解密服务接口(仅用于编译兼容,无法自动转换为 v3 解密器)
|
||||
/// </summary>
|
||||
[Obsolete("v3 has split decryption into IBundleOffsetDecryptor, IBundleMemoryDecryptor, IBundleStreamDecryptor. Manual migration required.")]
|
||||
public interface IDecryptionServices
|
||||
{
|
||||
DecryptResult LoadAssetBundle(DecryptFileInfo fileInfo);
|
||||
DecryptResult LoadAssetBundleAsync(DecryptFileInfo fileInfo);
|
||||
DecryptResult LoadAssetBundleFallback(DecryptFileInfo fileInfo);
|
||||
byte[] ReadFileData(DecryptFileInfo fileInfo);
|
||||
string ReadFileText(DecryptFileInfo fileInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 Web 解密文件信息(仅用于旧接口编译兼容)
|
||||
/// </summary>
|
||||
[Obsolete("v3 no longer supports IWebDecryptionServices. Manual migration required.")]
|
||||
public struct WebDecryptFileInfo
|
||||
{
|
||||
public string BundleName;
|
||||
public uint FileLoadCRC;
|
||||
public byte[] FileData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 Web 解密结果(仅用于旧接口编译兼容)
|
||||
/// </summary>
|
||||
[Obsolete("v3 no longer supports IWebDecryptionServices. Manual migration required.")]
|
||||
public struct WebDecryptResult
|
||||
{
|
||||
public AssetBundle Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 Web 解密服务接口(仅用于编译兼容,无法自动转换为 v3 解密器)
|
||||
/// </summary>
|
||||
[Obsolete("v3 no longer supports IWebDecryptionServices. Manual migration required.")]
|
||||
public interface IWebDecryptionServices
|
||||
{
|
||||
WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b974d3d744622f3499d026f99074cd72
|
||||
guid: a0283a72bdff8b54b93d9807ba038dbf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
207
Assets/YooAsset/Runtime/Compatibility/CompatibleHandles.cs
Normal file
207
Assets/YooAsset/Runtime/Compatibility/CompatibleHandles.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
// YooAsset v2.3 兼容层 - Handle 类兼容
|
||||
// 通过 partial class 为各 Handle 类补充 v2.3 的旧属性和方法。
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3 下载状态结构体(v3 已移除)
|
||||
/// </summary>
|
||||
[Obsolete("DownloadStatus has been removed in v3.")]
|
||||
public struct DownloadStatus
|
||||
{
|
||||
public bool IsDone;
|
||||
public float Progress;
|
||||
public long TotalBytes;
|
||||
public long DownloadedBytes;
|
||||
|
||||
public static DownloadStatus CreateDefaultStatus()
|
||||
{
|
||||
return new DownloadStatus();
|
||||
}
|
||||
}
|
||||
|
||||
#region HandleBase -- LastError / Task / GetDownloadStatus
|
||||
public abstract partial class HandleBase
|
||||
{
|
||||
private TaskCompletionSource<object> _taskCompletionSource;
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.LastError
|
||||
/// </summary>
|
||||
[Obsolete("Use Error instead.")]
|
||||
public string LastError => Error;
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.Task (System.Threading.Tasks.Task)
|
||||
/// </summary>
|
||||
[Obsolete("Use 'await handle' directly instead.")]
|
||||
public Task Task
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CheckValidWithWarning() == false)
|
||||
return null;
|
||||
|
||||
if (_taskCompletionSource == null)
|
||||
{
|
||||
_taskCompletionSource = new TaskCompletionSource<object>();
|
||||
if (Provider.IsDone)
|
||||
{
|
||||
_taskCompletionSource.TrySetResult(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Provider.Completed += delegate (AsyncOperationBase op)
|
||||
{
|
||||
_taskCompletionSource.TrySetResult(null);
|
||||
};
|
||||
}
|
||||
}
|
||||
return _taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.GetDownloadStatus()
|
||||
/// </summary>
|
||||
[Obsolete("GetDownloadStatus is no longer supported in v3.")]
|
||||
public DownloadStatus GetDownloadStatus()
|
||||
{
|
||||
return DownloadStatus.CreateDefaultStatus();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SceneHandle -- UnSuspend / UnloadAsync
|
||||
public sealed partial class SceneHandle
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3: sceneHandle.UnSuspend() -> v3: AllowSceneActivation()
|
||||
/// </summary>
|
||||
[Obsolete("Use AllowSceneActivation() instead.")]
|
||||
public bool UnSuspend() => AllowSceneActivation();
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: sceneHandle.UnloadAsync() -> v3: UnloadSceneAsync()
|
||||
/// </summary>
|
||||
[Obsolete("Use UnloadSceneAsync() instead.")]
|
||||
public UnloadSceneOperation UnloadAsync() => UnloadSceneAsync();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RawFileHandle -- GetRawFileData / GetRawFileText
|
||||
public sealed partial class RawFileHandle
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3: rawFileHandle.GetRawFileData()
|
||||
/// </summary>
|
||||
[Obsolete("Read file manually via GetRawFilePath().")]
|
||||
public byte[] GetRawFileData()
|
||||
{
|
||||
if (CheckValidWithWarning() == false) return null;
|
||||
return System.IO.File.ReadAllBytes(GetRawFilePath());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: rawFileHandle.GetRawFileText()
|
||||
/// </summary>
|
||||
[Obsolete("Read file manually via GetRawFilePath().")]
|
||||
public string GetRawFileText()
|
||||
{
|
||||
if (CheckValidWithWarning() == false) return null;
|
||||
return System.IO.File.ReadAllText(GetRawFilePath());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AssetHandle -- Instantiate 多重载
|
||||
public sealed partial class AssetHandle
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateSync(parent)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateSync(InstantiateOptions) instead.")]
|
||||
public GameObject InstantiateSync(Transform parent)
|
||||
{
|
||||
var options = new InstantiateOptions(true, parent, false);
|
||||
return InstantiateSync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateSync(parent, worldPositionStays)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateSync(InstantiateOptions) instead.")]
|
||||
public GameObject InstantiateSync(Transform parent, bool worldPositionStays)
|
||||
{
|
||||
var options = new InstantiateOptions(true, parent, worldPositionStays);
|
||||
return InstantiateSync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateSync(position, rotation)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateSync(InstantiateOptions) instead.")]
|
||||
public GameObject InstantiateSync(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
var options = new InstantiateOptions(true, position, rotation);
|
||||
return InstantiateSync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateSync(position, rotation, parent)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateSync(InstantiateOptions) instead.")]
|
||||
public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent)
|
||||
{
|
||||
var options = new InstantiateOptions(true, parent, position, rotation);
|
||||
return InstantiateSync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateAsync(parent, actived)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateAsync(InstantiateOptions) instead.")]
|
||||
public InstantiateOperation InstantiateAsync(Transform parent, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, parent, false);
|
||||
return InstantiateAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateAsync(parent, worldPositionStays, actived)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateAsync(InstantiateOptions) instead.")]
|
||||
public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, parent, worldPositionStays);
|
||||
return InstantiateAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateAsync(position, rotation, actived)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateAsync(InstantiateOptions) instead.")]
|
||||
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, position, rotation);
|
||||
return InstantiateAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: handle.InstantiateAsync(position, rotation, parent, actived)
|
||||
/// </summary>
|
||||
[Obsolete("Use InstantiateAsync(InstantiateOptions) instead.")]
|
||||
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, parent, position, rotation);
|
||||
return InstantiateAsync(options);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41ab464f315df234fb40b0c24e97ee23
|
||||
guid: 2c3bc780b23878f4f952d53fe28bf325
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
219
Assets/YooAsset/Runtime/Compatibility/CompatibleOperation.cs
Normal file
219
Assets/YooAsset/Runtime/Compatibility/CompatibleOperation.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
// YooAsset v2.3 兼容层 - Operation 类型
|
||||
// 提供 v2.3 的 InitializeParameters 类族、Operation 包装类、ImportFileInfo 和 GameAsyncOperation。
|
||||
|
||||
using System;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
#region InitializeParameters
|
||||
/// <summary>
|
||||
/// v2.3 初始化参数基类
|
||||
/// </summary>
|
||||
[Obsolete("Use specific Options classes (e.g. EditorSimulateModeOptions) instead.")]
|
||||
public abstract class InitializeParameters
|
||||
{
|
||||
public int BundleLoadingMaxConcurrency = int.MaxValue;
|
||||
public bool AutoUnloadBundleWhenUnused = false;
|
||||
public bool WebGLForceSyncLoadAsset = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 编辑器模拟模式初始化参数
|
||||
/// </summary>
|
||||
[Obsolete("Use EditorSimulateModeOptions instead.")]
|
||||
public class EditorSimulateModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters EditorFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 离线运行模式初始化参数
|
||||
/// </summary>
|
||||
[Obsolete("Use OfflinePlayModeOptions instead.")]
|
||||
public class OfflinePlayModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters BuildinFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 联机运行模式初始化参数
|
||||
/// </summary>
|
||||
[Obsolete("Use HostPlayModeOptions instead.")]
|
||||
public class HostPlayModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters BuildinFileSystemParameters;
|
||||
public FileSystemParameters CacheFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 WebGL 运行模式初始化参数
|
||||
/// </summary>
|
||||
[Obsolete("Use WebPlayModeOptions instead.")]
|
||||
public class WebPlayModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters WebServerFileSystemParameters;
|
||||
public FileSystemParameters WebRemoteFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3 自定义运行模式初始化参数
|
||||
/// </summary>
|
||||
[Obsolete("Use CustomPlayModeOptions instead.")]
|
||||
public class CustomPlayModeParameters : InitializeParameters
|
||||
{
|
||||
public readonly System.Collections.Generic.List<FileSystemParameters> FileSystemParameterList = new System.Collections.Generic.List<FileSystemParameters>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LegacyOperationWrapper
|
||||
/// <summary>
|
||||
/// v2.3 Operation 包装基类,将 v3 的 AsyncOperationBase 转发为旧类型。
|
||||
/// </summary>
|
||||
[Obsolete("Use v3 operation types directly.")]
|
||||
public class LegacyOperationWrapper : AsyncOperationBase
|
||||
{
|
||||
private bool _isDone = false;
|
||||
protected readonly AsyncOperationBase _operation;
|
||||
|
||||
internal LegacyOperationWrapper(AsyncOperationBase op)
|
||||
{
|
||||
_operation = op;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_isDone)
|
||||
return;
|
||||
|
||||
if (IsWaitForCompletion)
|
||||
_operation.WaitForCompletion();
|
||||
|
||||
_operation.UpdateOperation();
|
||||
Progress = _operation.Progress;
|
||||
if (_operation.IsDone == false)
|
||||
return;
|
||||
|
||||
_isDone = true;
|
||||
if (_operation.Status == EOperationStatus.Succeeded)
|
||||
SetResult();
|
||||
else
|
||||
SetError(_operation.Error);
|
||||
}
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Legacy Operations
|
||||
[Obsolete("Use InitializePackageOperation instead.")]
|
||||
public class InitializationOperation : LegacyOperationWrapper
|
||||
{
|
||||
internal InitializationOperation(InitializePackageOperation op) : base(op) { }
|
||||
}
|
||||
|
||||
[Obsolete("Use DestroyPackageOperation instead.")]
|
||||
public class DestroyOperation : LegacyOperationWrapper
|
||||
{
|
||||
internal DestroyOperation(DestroyPackageOperation op) : base(op) { }
|
||||
}
|
||||
|
||||
[Obsolete("Use LoadPackageManifestOperation instead.")]
|
||||
public class UpdatePackageManifestOperation : LegacyOperationWrapper
|
||||
{
|
||||
internal UpdatePackageManifestOperation(LoadPackageManifestOperation op) : base(op) { }
|
||||
}
|
||||
|
||||
[Obsolete("Use PrefetchManifestOperation instead.")]
|
||||
public class PreDownloadContentOperation : LegacyOperationWrapper
|
||||
{
|
||||
private readonly PrefetchManifestOperation _prefetchOp;
|
||||
|
||||
internal PreDownloadContentOperation(PrefetchManifestOperation op) : base(op)
|
||||
{
|
||||
_prefetchOp = op;
|
||||
}
|
||||
|
||||
[Obsolete("Use PrefetchManifestOperation.CreateResourceDownloader(ResourceDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceDownloaderOptions(downloadingMaxNumber, failedTryAgain);
|
||||
return _prefetchOp.CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use PrefetchManifestOperation.CreateResourceDownloader(ResourceDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
string[] tags = new string[] { tag };
|
||||
var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain);
|
||||
return _prefetchOp.CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use PrefetchManifestOperation.CreateResourceDownloader(ResourceDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain);
|
||||
return _prefetchOp.CreateResourceDownloader(options);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ImportFileInfo
|
||||
/// <summary>
|
||||
/// v2.3 导入文件信息
|
||||
/// </summary>
|
||||
[Obsolete("Use ImportBundleInfo instead.")]
|
||||
public struct ImportFileInfo
|
||||
{
|
||||
public string FilePath;
|
||||
public string BundleName;
|
||||
public string BundleGUID;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GameAsyncOperation
|
||||
/// <summary>
|
||||
/// v2.3 游戏异步操作基类(v3 已移除)
|
||||
/// </summary>
|
||||
[Obsolete("GameAsyncOperation has been removed in v3. Use AsyncOperationBase directly.")]
|
||||
public abstract class GameAsyncOperation : AsyncOperationBase
|
||||
{
|
||||
protected override void InternalStart()
|
||||
{
|
||||
OnStart();
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
OnUpdate();
|
||||
}
|
||||
protected override void InternalAbort()
|
||||
{
|
||||
OnAbort();
|
||||
}
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
OnWaitForAsyncComplete();
|
||||
}
|
||||
|
||||
protected abstract void OnStart();
|
||||
protected abstract void OnUpdate();
|
||||
protected abstract void OnAbort();
|
||||
protected virtual void OnWaitForAsyncComplete() { }
|
||||
|
||||
protected new bool IsBusy
|
||||
{
|
||||
get { return AsyncOperationSystem.IsBusy; }
|
||||
}
|
||||
|
||||
protected void Abort()
|
||||
{
|
||||
AbortOperation();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19ed2b81fece5b84fa771a5eeb108572
|
||||
guid: f16ea24f57c29f74babb8169fb1fa7a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,334 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
// YooAsset v2.3 兼容层 - ResourcePackage 兼容方法
|
||||
// 通过 partial class 为 ResourcePackage 补充 v2.3 的旧接口。
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3 缓存清理模式(v3 改用字符串参数)
|
||||
/// </summary>
|
||||
[Obsolete("Use string-based ClearCacheOptions instead.")]
|
||||
public enum EFileClearMode
|
||||
{
|
||||
ClearAllBundleFiles,
|
||||
ClearUnusedBundleFiles,
|
||||
ClearBundleFilesByLocations,
|
||||
ClearBundleFilesByTags,
|
||||
ClearAllManifestFiles,
|
||||
ClearUnusedManifestFiles,
|
||||
}
|
||||
|
||||
public partial class ResourcePackage
|
||||
{
|
||||
#region 初始化 / 销毁
|
||||
[Obsolete("Use InitializePackageAsync(options) instead.")]
|
||||
public InitializationOperation InitializeAsync(InitializeParameters parameters)
|
||||
{
|
||||
if (parameters is EditorSimulateModeParameters esp)
|
||||
{
|
||||
var options = new EditorSimulateModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = esp.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = esp.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = esp.WebGLForceSyncLoadAsset;
|
||||
options.EditorFileSystemParameters = esp.EditorFileSystemParameters;
|
||||
var operation = InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is OfflinePlayModeParameters opp)
|
||||
{
|
||||
var options = new OfflinePlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = opp.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = opp.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = opp.WebGLForceSyncLoadAsset;
|
||||
options.BuiltinFileSystemParameters = opp.BuildinFileSystemParameters;
|
||||
var operation = InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is HostPlayModeParameters hpp)
|
||||
{
|
||||
var options = new HostPlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = hpp.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = hpp.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = hpp.WebGLForceSyncLoadAsset;
|
||||
options.BuiltinFileSystemParameters = hpp.BuildinFileSystemParameters;
|
||||
options.CacheFileSystemParameters = hpp.CacheFileSystemParameters;
|
||||
var operation = InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is WebPlayModeParameters wpp)
|
||||
{
|
||||
var options = new WebPlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = wpp.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = wpp.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = wpp.WebGLForceSyncLoadAsset;
|
||||
options.WebServerFileSystemParameters = wpp.WebServerFileSystemParameters;
|
||||
options.WebRemoteFileSystemParameters = wpp.WebRemoteFileSystemParameters;
|
||||
var operation = InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is CustomPlayModeParameters cpp)
|
||||
{
|
||||
var options = new CustomPlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = cpp.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = cpp.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = cpp.WebGLForceSyncLoadAsset;
|
||||
foreach (var fsp in cpp.FileSystemParameterList)
|
||||
options.FileSystemParameterList.Add(fsp);
|
||||
var operation = InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException($"Unsupported InitializeParameters type: {parameters.GetType().Name}");
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use DestroyPackageAsync() instead.")]
|
||||
public DestroyOperation DestroyAsync()
|
||||
{
|
||||
var operation = DestroyPackageAsync();
|
||||
var wrapper = new DestroyOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(AsyncOperationSystem.GlobalSchedulerName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 版本 / 清单
|
||||
[Obsolete("Use RequestPackageVersionAsync(RequestPackageVersionOptions) instead.")]
|
||||
public RequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
|
||||
{
|
||||
var options = new RequestPackageVersionOptions(appendTimeTicks, timeout);
|
||||
return RequestPackageVersionAsync(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use LoadPackageManifestAsync(LoadPackageManifestOptions) instead.")]
|
||||
public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout = 60)
|
||||
{
|
||||
var options = new LoadPackageManifestOptions(packageVersion, timeout);
|
||||
var operation = LoadPackageManifestAsync(options);
|
||||
var wrapper = new UpdatePackageManifestOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
[Obsolete("Use PrefetchManifestAsync(PrefetchManifestOptions) instead.")]
|
||||
public PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout = 60)
|
||||
{
|
||||
var options = new PrefetchManifestOptions(packageVersion, timeout);
|
||||
var op = PrefetchManifestAsync(options);
|
||||
var wrapper = new PreDownloadContentOperation(op);
|
||||
AsyncOperationSystem.StartOperation(PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 缓存清理
|
||||
[Obsolete("Use ClearCacheAsync(ClearCacheOptions) instead.")]
|
||||
public ClearCacheOperation ClearCacheFilesAsync(string fileClearMode, object clearParam = null)
|
||||
{
|
||||
var options = new ClearCacheOptions(fileClearMode, clearParam);
|
||||
return ClearCacheAsync(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use ClearCacheAsync(ClearCacheOptions) instead.")]
|
||||
public ClearCacheOperation ClearCacheFilesAsync(EFileClearMode clearMode, object clearParam = null)
|
||||
{
|
||||
var options = new ClearCacheOptions(clearMode.ToString(), clearParam);
|
||||
return ClearCacheAsync(options);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源卸载
|
||||
[Obsolete("Use UnloadUnusedAssetsAsync(UnloadUnusedAssetsOptions) instead.")]
|
||||
public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(int loopCount)
|
||||
{
|
||||
var options = new UnloadUnusedAssetsOptions(loopCount);
|
||||
return UnloadUnusedAssetsAsync(options);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源查询
|
||||
[Obsolete("Use GetDownloadSize() instead.")]
|
||||
public bool IsNeedDownloadFromRemote(string location)
|
||||
{
|
||||
return GetDownloadSize(location) > 0;
|
||||
}
|
||||
|
||||
[Obsolete("Use GetDownloadSize() instead.")]
|
||||
public bool IsNeedDownloadFromRemote(AssetInfo assetInfo)
|
||||
{
|
||||
return GetDownloadSize(assetInfo) > 0;
|
||||
}
|
||||
|
||||
[Obsolete("Use IsLocationValid() instead.")]
|
||||
public bool CheckLocationValid(string location)
|
||||
{
|
||||
return IsLocationValid(location);
|
||||
}
|
||||
|
||||
[Obsolete("Use GetAssetInfoByGuid() instead.")]
|
||||
public AssetInfo GetAssetInfoByGUID(string assetGUID)
|
||||
{
|
||||
return GetAssetInfoByGuid(assetGUID);
|
||||
}
|
||||
|
||||
[Obsolete("Use GetAssetInfoByGuid() instead.")]
|
||||
public AssetInfo GetAssetInfoByGUID(string assetGUID, Type type)
|
||||
{
|
||||
return GetAssetInfoByGuid(assetGUID, type);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源下载
|
||||
[Obsolete("Use CreateResourceDownloader(ResourceDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceDownloaderOptions(downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(ResourceDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
string[] tags = new string[] { tag };
|
||||
var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(ResourceDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
var options = new BundleDownloaderOptions(assetInfo, recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return CreateBundleDownloader(location, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
List<AssetInfo> assetInfos = new List<AssetInfo>(locations.Length);
|
||||
foreach (var location in locations)
|
||||
{
|
||||
var assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
assetInfos.Add(assetInfo);
|
||||
}
|
||||
var options = new BundleDownloaderOptions(assetInfos.ToArray(), recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return CreateBundleDownloader(locations, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
AssetInfo[] assetInfos = new AssetInfo[] { assetInfo };
|
||||
var options = new BundleDownloaderOptions(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return CreateBundleDownloader(assetInfo, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new BundleDownloaderOptions(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceDownloader(BundleDownloaderOptions) instead.")]
|
||||
public ResourceDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return CreateBundleDownloader(assetInfos, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源解压
|
||||
[Obsolete("Use CreateResourceUnpacker(ResourceUnpackerOptions) instead.")]
|
||||
public ResourceUnpackerOperation CreateResourceUnpacker(int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceUnpackerOptions(unpackingMaxNumber, failedTryAgain);
|
||||
return CreateResourceUnpacker(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceUnpacker(ResourceUnpackerOptions) instead.")]
|
||||
public ResourceUnpackerOperation CreateResourceUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
string[] tags = new string[] { tag };
|
||||
var options = new ResourceUnpackerOptions(tags, unpackingMaxNumber, failedTryAgain);
|
||||
return CreateResourceUnpacker(options);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceUnpacker(ResourceUnpackerOptions) instead.")]
|
||||
public ResourceUnpackerOperation CreateResourceUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceUnpackerOptions(tags, unpackingMaxNumber, failedTryAgain);
|
||||
return CreateResourceUnpacker(options);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源导入
|
||||
[Obsolete("Use CreateResourceImporter(BundleImporterOptions) instead.")]
|
||||
public ResourceImporterOperation CreateResourceImporter(string[] filePaths, int importerMaxNumber, int failedTryAgain)
|
||||
{
|
||||
ImportFileInfo[] fileInfos = new ImportFileInfo[filePaths.Length];
|
||||
for (int i = 0; i < filePaths.Length; i++)
|
||||
{
|
||||
ImportFileInfo fileInfo = new ImportFileInfo();
|
||||
fileInfo.FilePath = filePaths[i];
|
||||
fileInfos[i] = fileInfo;
|
||||
}
|
||||
return CreateResourceImporter(fileInfos, importerMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
[Obsolete("Use CreateResourceImporter(BundleImporterOptions) instead.")]
|
||||
public ResourceImporterOperation CreateResourceImporter(ImportFileInfo[] fileInfos, int importerMaxNumber, int failedTryAgain)
|
||||
{
|
||||
ImportBundleInfo[] bundleInfos = new ImportBundleInfo[fileInfos.Length];
|
||||
for (int i = 0; i < fileInfos.Length; i++)
|
||||
{
|
||||
bundleInfos[i] = new ImportBundleInfo(
|
||||
filePath: fileInfos[i].FilePath,
|
||||
bundleName: fileInfos[i].BundleName,
|
||||
bundleGuid: fileInfos[i].BundleGUID);
|
||||
}
|
||||
var options = new BundleImporterOptions(bundleInfos, importerMaxNumber, failedTryAgain);
|
||||
return CreateResourceImporter(options);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcb10923f246d8844b4980dcb84bec86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
83
Assets/YooAsset/Runtime/Compatibility/CompatibleYooAssets.cs
Normal file
83
Assets/YooAsset/Runtime/Compatibility/CompatibleYooAssets.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
#if YOOASSET_LEGACY_API
|
||||
// YooAsset v2.3 兼容层 - YooAssets 静态类兼容
|
||||
// 通过 partial class 为 YooAssets 补充 v2.3 的旧静态属性和方法。
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public static partial class YooAssets
|
||||
{
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.Initialized
|
||||
/// </summary>
|
||||
[Obsolete("Use IsInitialized instead.")]
|
||||
public static bool Initialized => IsInitialized;
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.GetAllPackages()
|
||||
/// </summary>
|
||||
[Obsolete("Use GetPackages() instead.")]
|
||||
public static List<ResourcePackage> GetAllPackages()
|
||||
{
|
||||
return GetPackages().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.TryGetPackage(string)
|
||||
/// </summary>
|
||||
[Obsolete("Use TryGetPackage(string, out ResourcePackage) instead.")]
|
||||
public static ResourcePackage TryGetPackage(string packageName)
|
||||
{
|
||||
TryGetPackage(packageName, out var package);
|
||||
return package;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.RemovePackage(ResourcePackage)
|
||||
/// </summary>
|
||||
[Obsolete("Use RemovePackage(string) instead.")]
|
||||
public static bool RemovePackage(ResourcePackage package)
|
||||
{
|
||||
try
|
||||
{
|
||||
RemovePackage(package.PackageName);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.SetOperationSystemMaxTimeSlice(long)
|
||||
/// </summary>
|
||||
[Obsolete("Use SetAsyncOperationMaxTimeSlice() instead.")]
|
||||
public static void SetOperationSystemMaxTimeSlice(long milliseconds)
|
||||
{
|
||||
SetAsyncOperationMaxTimeSlice(milliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.SetDownloadSystemUnityWebRequest(delegate)
|
||||
/// </summary>
|
||||
[Obsolete("This API has been removed in v3.")]
|
||||
public static void SetDownloadSystemUnityWebRequest(object createDelegate)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// v2.3: YooAssets.StartOperation(GameAsyncOperation)
|
||||
/// </summary>
|
||||
[Obsolete("GameAsyncOperation has been removed in v3.")]
|
||||
public static void StartOperation(GameAsyncOperation operation)
|
||||
{
|
||||
AsyncOperationSystem.StartOperation(AsyncOperationSystem.GlobalSchedulerName, operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93e9bc10b05be8b42a704832abed581d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
230
Assets/YooAsset/Runtime/Compatibility/MIGRATION_GUIDE.md
Normal file
230
Assets/YooAsset/Runtime/Compatibility/MIGRATION_GUIDE.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# YooAsset v2.3 → v3.x 迁移指南
|
||||
|
||||
本兼容层允许大部分 v2.3 业务代码在 v3.x 下**零修改编译通过**。所有兼容 API 均标记了 `[Obsolete]`,编译时会输出警告提示迁移到 v3 新接口。
|
||||
|
||||
## 启用兼容层
|
||||
|
||||
兼容代码默认**不参与编译**,需要手动添加编译宏才能启用:
|
||||
|
||||
**Unity Editor**:`Edit → Project Settings → Player → Scripting Define Symbols`,添加 `YOOASSET_LEGACY_API`
|
||||
|
||||
添加后重新编译即可生效。当所有业务代码已迁移到 v3 新接口后,移除该宏即可彻底关闭兼容层。
|
||||
|
||||
---
|
||||
|
||||
## 一、API 对照表(自动兼容,无需修改代码)
|
||||
|
||||
### 1.1 枚举与状态
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `EOperationStatus.Succeed` | `EOperationStatus.Succeeded` |
|
||||
| `EFileClearMode.ClearAllBundleFiles` | `"ClearAllBundleFiles"` (字符串) |
|
||||
| `EPlayMode.HostPlayMode` | 已移除(用 Options 类代替) |
|
||||
| `handle.GetDownloadStatus()` | 已移除 |
|
||||
|
||||
### 1.2 HandleBase
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `handle.LastError` | `handle.Error` |
|
||||
| `await handle.Task` | `await handle` |
|
||||
| `handle.GetDownloadStatus()` | 已移除 |
|
||||
|
||||
### 1.3 SceneHandle
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `sceneHandle.UnSuspend()` | `sceneHandle.AllowSceneActivation()` |
|
||||
| `sceneHandle.UnloadAsync()` | `sceneHandle.UnloadSceneAsync()` |
|
||||
|
||||
### 1.4 RawFileHandle
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `rawHandle.GetRawFileData()` | `File.ReadAllBytes(rawHandle.GetRawFilePath())` |
|
||||
| `rawHandle.GetRawFileText()` | `File.ReadAllText(rawHandle.GetRawFilePath())` |
|
||||
|
||||
### 1.5 AssetHandle 实例化
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `handle.InstantiateSync(parent)` | `handle.InstantiateSync(new InstantiateOptions(...))` |
|
||||
| `handle.InstantiateSync(parent, worldPositionStays)` | 同上 |
|
||||
| `handle.InstantiateSync(position, rotation)` | 同上 |
|
||||
| `handle.InstantiateSync(position, rotation, parent)` | 同上 |
|
||||
| `handle.InstantiateAsync(parent, actived)` | `handle.InstantiateAsync(new InstantiateOptions(...))` |
|
||||
| `handle.InstantiateAsync(parent, worldPositionStays, actived)` | 同上 |
|
||||
| `handle.InstantiateAsync(position, rotation, actived)` | 同上 |
|
||||
| `handle.InstantiateAsync(position, rotation, parent, actived)` | 同上 |
|
||||
|
||||
### 1.6 DownloaderOperation
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `downloader.BeginDownload()` | `downloader.StartDownload()` |
|
||||
| `downloader.DownloadFinishCallback = ...` | `downloader.DownloadCompleted += ...` |
|
||||
| `downloader.DownloadUpdateCallback = ...` | `downloader.DownloadProgressChanged += ...` |
|
||||
| `downloader.DownloadErrorCallback = ...` | `downloader.DownloadError += ...` |
|
||||
| `downloader.DownloadFileBeginCallback = ...` | `downloader.DownloadFileStarted += ...` |
|
||||
|
||||
> **注意**:v2.3 的 `DownloadError` 委托名与 v3 的 `DownloadError` event 冲突,已重命名为 `DownloadErrorDelegate`。如果你的旧代码中直接引用了 `DownloaderOperation.DownloadError` 委托类型,需要改为 `DownloadErrorDelegate`。
|
||||
|
||||
### 1.7 ResourcePackage
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `package.InitializeAsync(parameters)` | `package.InitializePackageAsync(options)` |
|
||||
| `package.DestroyAsync()` | `package.DestroyPackageAsync()` |
|
||||
| `package.RequestPackageVersionAsync(bool, int)` | `package.RequestPackageVersionAsync(options)` |
|
||||
| `package.UpdatePackageManifestAsync(version, timeout)` | `package.LoadPackageManifestAsync(options)` |
|
||||
| `package.PreDownloadContentAsync(version, timeout)` | `package.PrefetchManifestAsync(options)` |
|
||||
| `package.ClearCacheFilesAsync(mode, param)` | `package.ClearCacheAsync(options)` |
|
||||
| `package.UnloadUnusedAssetsAsync(loopCount)` | `package.UnloadUnusedAssetsAsync(options)` |
|
||||
| `package.IsNeedDownloadFromRemote(location)` | `package.GetDownloadSize(location) > 0` |
|
||||
| `package.CheckLocationValid(location)` | `package.IsLocationValid(location)` |
|
||||
| `package.GetAssetInfoByGUID(guid)` | `package.GetAssetInfoByGuid(guid)` |
|
||||
| `package.CreateResourceDownloader(maxNum, retry)` | `package.CreateResourceDownloader(options)` |
|
||||
| `package.CreateBundleDownloader(...)` | `package.CreateResourceDownloader(bundleOptions)` |
|
||||
| `package.CreateResourceUnpacker(maxNum, retry)` | `package.CreateResourceUnpacker(options)` |
|
||||
| `package.CreateResourceImporter(paths, maxNum, retry)` | `package.CreateResourceImporter(bundleImporterOptions)` |
|
||||
|
||||
### 1.8 YooAssets 静态类
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `YooAssets.Initialized` | `YooAssets.IsInitialized` |
|
||||
| `YooAssets.GetAllPackages()` | `YooAssets.GetPackages()` |
|
||||
| `YooAssets.TryGetPackage(name)` 返回 null | `YooAssets.TryGetPackage(name, out pkg)` |
|
||||
| `YooAssets.RemovePackage(package)` 传入实例 | `YooAssets.RemovePackage(packageName)` 传入字符串 |
|
||||
| `YooAssets.SetOperationSystemMaxTimeSlice(ms)` | `YooAssets.SetAsyncOperationMaxTimeSlice(ms)` |
|
||||
| `YooAssets.SetDownloadSystemUnityWebRequest(...)` | 已移除 |
|
||||
| `YooAssets.StartOperation(gameAsyncOp)` | 已移除 |
|
||||
|
||||
### 1.9 文件系统参数
|
||||
|
||||
| v2.3 写法 | v3 新写法 |
|
||||
|-----------|----------|
|
||||
| `params.FileSystemClass` | `params.FileSystemTypeName` |
|
||||
| `CreateDefaultBuildinFileSystemParameters(decryptSvc, root)` | `CreateDefaultBuiltinFileSystemParameters(root)` |
|
||||
| `CreateDefaultCacheFileSystemParameters(remoteSvc, decryptSvc, root)` | `CreateDefaultSandboxFileSystemParameters(remoteService, root)` |
|
||||
| `CreateDefaultWebServerFileSystemParameters(webDecryptSvc, disableCache)` | `CreateDefaultWebServerFileSystemParameters(disableCache)` |
|
||||
| `CreateDefaultWebRemoteFileSystemParameters(remoteSvc, webDecryptSvc, disableCache)` | `CreateDefaultWebRemoteFileSystemParameters(remoteService, disableCache)` |
|
||||
| `FileSystemParametersDefine.XXX` 常量 | `EFileSystemParameter.Xxx` 枚举 |
|
||||
| `IRemoteServices` | `IRemoteService` |
|
||||
| `IManifestRestoreServices` | `IManifestDecryptor` |
|
||||
| `EOverwriteInstallClearMode` | `EInstallCleanupMode` |
|
||||
| `AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteSvc)` | 自动包装为 `IRemoteService` |
|
||||
| `AddParameter(FileSystemParametersDefine.MANIFEST_SERVICES, manifestSvc)` | 自动包装为 `IManifestDecryptor` |
|
||||
| `AddParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, oldMode)` | 自动转换为 `EInstallCleanupMode` |
|
||||
|
||||
### 1.10 其他旧类型
|
||||
|
||||
| v2.3 类型 | v3 对应 |
|
||||
|----------|---------|
|
||||
| `InitializeParameters` 及子类 | `EditorSimulateModeOptions` 等 Options 类 |
|
||||
| `InitializationOperation` | `InitializePackageOperation` |
|
||||
| `DestroyOperation` | `DestroyPackageOperation` |
|
||||
| `UpdatePackageManifestOperation` | `LoadPackageManifestOperation` |
|
||||
| `PreDownloadContentOperation` | `PrefetchManifestOperation` |
|
||||
| `GameAsyncOperation` | 已移除(用 `AsyncOperationBase`) |
|
||||
| `ImportFileInfo` | `ImportBundleInfo` |
|
||||
| `DownloaderFinishData` | `DownloadCompletedEventArgs` |
|
||||
| `DownloadUpdateData` | `DownloadProgressChangedEventArgs` |
|
||||
| `DownloadErrorData` | `DownloadErrorEventArgs` |
|
||||
| `DownloadFileData` | `DownloadFileStartedEventArgs` |
|
||||
| `DownloadStatus` | 已移除 |
|
||||
|
||||
---
|
||||
|
||||
## 二、需要手动迁移的项(无法自动兼容)
|
||||
|
||||
### 2.1 默认包裹快捷 API(已彻底移除)
|
||||
|
||||
v2.3 中 `YooAssets.SetDefaultPackage()` 及其关联的约 50 个静态快捷方法已在 v3 中**完全移除,不提供兼容**:
|
||||
|
||||
```csharp
|
||||
// v2.3 写法 -- 不再支持
|
||||
YooAssets.SetDefaultPackage(package);
|
||||
YooAssets.LoadAssetAsync<GameObject>("Assets/Prefabs/Hero.prefab");
|
||||
|
||||
// v3 写法 -- 必须通过 ResourcePackage 实例调用
|
||||
var package = YooAssets.GetPackage("DefaultPackage");
|
||||
package.LoadAssetAsync<GameObject>("Assets/Prefabs/Hero.prefab");
|
||||
```
|
||||
|
||||
**迁移建议**:全局搜索 `YooAssets.Load`、`YooAssets.GetAssetInfo`、`YooAssets.SetDefaultPackage` 等调用,替换为 `package.Xxx(...)` 形式。
|
||||
|
||||
### 2.2 DownloadError 委托名冲突
|
||||
|
||||
v2.3 的 `DownloaderOperation.DownloadError` 委托类型与 v3 的 `DownloadError` event 同名,兼容层已将旧委托重命名为 `DownloadErrorDelegate`。
|
||||
|
||||
### 2.3 LoadSceneAsync 的 suspendLoad 参数语义反转
|
||||
|
||||
v2.3 的 `LoadSceneAsync(..., bool suspendLoad, ...)` 与 v3 的 `LoadSceneAsync(..., bool allowSceneActivation, ...)` 参数类型签名完全相同,仅参数名和语义相反(`suspendLoad=true` 等价于 `allowSceneActivation=false`)。由于方法签名冲突,无法通过兼容层自动处理。
|
||||
|
||||
```csharp
|
||||
// v2.3 写法
|
||||
package.LoadSceneAsync("scene", LoadSceneMode.Single, LocalPhysicsMode.None, suspendLoad: true, 100);
|
||||
|
||||
// v3 写法 -- 注意 bool 语义反转
|
||||
package.LoadSceneAsync("scene", LoadSceneMode.Single, LocalPhysicsMode.None, allowSceneActivation: false, 100);
|
||||
```
|
||||
|
||||
### 2.4 ClearCacheFilesOperation 类型名冲突
|
||||
|
||||
v2.3 的 `ClearCacheFilesOperation` 与 v3 内部同名类冲突,无法提供兼容包装类。如果旧代码中显式引用了该类型名,需改为 `ClearCacheOperation`。通过 `package.ClearCacheFilesAsync(...)` 调用并用 `var` 接收返回值的写法不受影响。
|
||||
|
||||
### 2.5 UnloadAllAssetsOptions 写法变更
|
||||
|
||||
v2.3 是 `class` + 公有可变字段,v3 是 `readonly struct` + 构造函数。此场景极少出现。
|
||||
|
||||
### 2.6 文件系统参数迁移
|
||||
|
||||
#### 解密服务接口重构(必须手动迁移)
|
||||
|
||||
v2.3 的 `IDecryptionServices` 和 `IWebDecryptionServices` 在 v3 中已拆分为多个专用接口:
|
||||
|
||||
| v2.3 | v3 |
|
||||
|------|-----|
|
||||
| `IDecryptionServices.LoadAssetBundle()` | `IBundleOffsetDecryptor` 或 `IBundleStreamDecryptor` |
|
||||
| `IDecryptionServices.LoadAssetBundleAsync()` | 同上 |
|
||||
| `IDecryptionServices.LoadAssetBundleFallback()` | `IBundleMemoryDecryptor` |
|
||||
| `IDecryptionServices.ReadFileData()` / `ReadFileText()` | 已移除 |
|
||||
| `IWebDecryptionServices` | 已移除,无替代 |
|
||||
|
||||
兼容层保留了 `IDecryptionServices`、`IWebDecryptionServices` 及相关 `DecryptFileInfo` / `DecryptResult` 类型签名以避免编译错误,但**不会自动转换为 v3 解密器**。旧工厂方法中传入的 `decryptionServices` 参数会被忽略。
|
||||
|
||||
```csharp
|
||||
// v2.3 写法
|
||||
var fsp = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(myDecryptSvc);
|
||||
|
||||
// 兼容层编译通过,但 myDecryptSvc 不生效!
|
||||
// 迁移方法:实现 IBundleOffsetDecryptor 等新接口,通过 EFileSystemParameter 添加
|
||||
var fsp = FileSystemParameters.CreateDefaultBuiltinFileSystemParameters();
|
||||
fsp.AddParameter(EFileSystemParameter.AssetbundleDecryptor, myNewDecryptor);
|
||||
```
|
||||
|
||||
#### 已移除的参数常量
|
||||
|
||||
以下 `FileSystemParametersDefine` 常量在 v3 中无稳定等价参数,兼容层保留了常量值但 v3 文件系统不会识别:
|
||||
|
||||
- `APPEND_FILE_EXTENSION` — 已移除
|
||||
- `DISABLE_CATALOG_FILE` — 已移除
|
||||
- `COPY_LOCAL_FILE_SERVICES` — 已移除
|
||||
- `RESUME_DOWNLOAD_RESPONSE_CODES` — 已移除
|
||||
|
||||
#### 旧内部文件系统类名
|
||||
|
||||
v2.3 中通过字符串引用的内部文件系统类名在 v3 中已变更:
|
||||
|
||||
| v2.3 类名 | v3 类名 |
|
||||
|-----------|---------|
|
||||
| `DefaultEditorFileSystem` | `EditorFileSystem` |
|
||||
| `DefaultBuildinFileSystem` | `BuiltinFileSystem` |
|
||||
| `DefaultCacheFileSystem` | `SandboxFileSystem` |
|
||||
| `DefaultWebServerFileSystem` | `WebServerFileSystem` |
|
||||
| `DefaultWebRemoteFileSystem` | `WebRemoteFileSystem` |
|
||||
|
||||
如果旧代码中手写了类名字符串(如 `new FileSystemParameters("YooAsset.DefaultCacheFileSystem", root)`),需改为 v3 工厂方法或更新类名。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2aba4dc1069712d4da0976a70c62e040
|
||||
DefaultImporter:
|
||||
guid: f0c6ef1d5368f6a4ca479c94b91ceb81
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -9,7 +9,9 @@ namespace YooAsset
|
||||
[Serializable]
|
||||
internal class DiagnosticPackageData
|
||||
{
|
||||
[NonSerialized]
|
||||
private readonly Dictionary<string, DiagnosticBundleInfo> _bundleInfoDict = new Dictionary<string, DiagnosticBundleInfo>();
|
||||
[NonSerialized]
|
||||
private bool _isParsed = false;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -19,24 +19,11 @@ namespace YooAsset
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
throw new YooInternalException("File path is null or empty.");
|
||||
|
||||
if (IsLocalFileUrl(filePath))
|
||||
return EscapeSpecialCharacters(filePath);
|
||||
|
||||
string url;
|
||||
|
||||
#if UNITY_WEBGL
|
||||
if (IsLocalFileUrl(filePath))
|
||||
url = filePath;
|
||||
#elif UNITY_ANDROID
|
||||
url = new System.Uri(filePath).ToString();
|
||||
#elif UNITY_OPENHARMONY
|
||||
// 注意:由于鸿蒙系统的特殊性,需要判断双形态
|
||||
if (UnityEngine.Application.streamingAssetsPath.StartsWith("jar:file://"))
|
||||
url = StringUtility.Format("jar:file://{0}", filePath);
|
||||
else
|
||||
url = new System.Uri(filePath).ToString();
|
||||
#else
|
||||
url = new System.Uri(filePath).ToString();
|
||||
#endif
|
||||
url = CreateLocalFileUrl(filePath);
|
||||
|
||||
return EscapeSpecialCharacters(url);
|
||||
}
|
||||
@@ -60,6 +47,20 @@ namespace YooAsset
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string CreateLocalFileUrl(string filePath)
|
||||
{
|
||||
#if UNITY_WEBGL
|
||||
return filePath;
|
||||
#elif UNITY_OPENHARMONY
|
||||
// 注意:由于鸿蒙系统的特殊性,需要判断双形态
|
||||
if (UnityEngine.Application.streamingAssetsPath.StartsWith("jar:file://"))
|
||||
return $"jar:file://{filePath}";
|
||||
else
|
||||
return new System.Uri(filePath).ToString();
|
||||
#else
|
||||
return new System.Uri(filePath).ToString();
|
||||
#endif
|
||||
}
|
||||
private static string EscapeSpecialCharacters(string url)
|
||||
{
|
||||
// 处理特殊字符:用户设备路径可能包含特殊字符导致 URL 无法正确识别
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 提供文件系统的创建参数与工厂方法
|
||||
/// </summary>
|
||||
public class FileSystemParameters
|
||||
public partial class FileSystemParameters
|
||||
{
|
||||
internal readonly Dictionary<string, object> _createParameters = new Dictionary<string, object>(100);
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace YooAsset
|
||||
|
||||
// 创建默认的下载后台接口
|
||||
if (DownloadBackend == null)
|
||||
DownloadBackend = new UnityWebRequestBackend(null);
|
||||
DownloadBackend = new UnityWebRequestBackend();
|
||||
|
||||
// 创建默认的下载重试策略
|
||||
if (DownloadRetryPolicy == null)
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 全资源句柄,用于加载资源包内所有资源对象。
|
||||
/// </summary>
|
||||
public sealed class AllAssetsHandle : HandleBase
|
||||
public sealed partial class AllAssetsHandle : HandleBase
|
||||
{
|
||||
private System.Action<AllAssetsHandle> _callback;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 资源句柄,用于管理单个资源对象的加载和访问。
|
||||
/// </summary>
|
||||
public sealed class AssetHandle : HandleBase
|
||||
public sealed partial class AssetHandle : HandleBase
|
||||
{
|
||||
private System.Action<AssetHandle> _callback;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 资源句柄基类,提供资源加载状态查询和释放功能。
|
||||
/// </summary>
|
||||
public abstract class HandleBase : IEnumerator, IDisposable
|
||||
public abstract partial class HandleBase : IEnumerator, IDisposable
|
||||
{
|
||||
private readonly AssetInfo _assetInfo;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 原生文件句柄,用于访问未经 Unity 处理的原始文件。
|
||||
/// </summary>
|
||||
public sealed class RawFileHandle : HandleBase
|
||||
public sealed partial class RawFileHandle : HandleBase
|
||||
{
|
||||
private System.Action<RawFileHandle> _callback;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 场景句柄,用于管理场景的加载、激活和卸载。
|
||||
/// </summary>
|
||||
public sealed class SceneHandle : HandleBase
|
||||
public sealed partial class SceneHandle : HandleBase
|
||||
{
|
||||
private System.Action<SceneHandle> _callback;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 子资源句柄,用于管理资源包内子资源对象的加载和访问。
|
||||
/// </summary>
|
||||
public sealed class SubAssetsHandle : HandleBase
|
||||
public sealed partial class SubAssetsHandle : HandleBase
|
||||
{
|
||||
private System.Action<SubAssetsHandle> _callback;
|
||||
|
||||
|
||||
@@ -35,10 +35,12 @@ namespace YooAsset
|
||||
_handle = handle;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.LoadObject;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -140,10 +142,12 @@ namespace YooAsset
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
var assetInfo = _handle.GetAssetInfo();
|
||||
|
||||
@@ -28,10 +28,12 @@ namespace YooAsset
|
||||
_resourceManager = resourceManager;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckOptions;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
|
||||
@@ -42,10 +42,12 @@ namespace YooAsset
|
||||
throw new YooInternalException($"Unexpected provider type: '{provider.GetType().Name}'.");
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckError;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -106,6 +108,7 @@ namespace YooAsset
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
return $"SceneName: {_provider.LoadedSceneName}";
|
||||
|
||||
@@ -22,11 +22,13 @@ namespace YooAsset
|
||||
_resourceManager = resourceManager;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.UnloadUnused;
|
||||
_loopCounter = _options.MaxLoopCount;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -51,10 +53,12 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalWaitForCompletion()
|
||||
{
|
||||
ExecuteBatch();
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
return $"MaxLoopCount: {_options.MaxLoopCount}";
|
||||
|
||||
@@ -28,10 +28,12 @@ namespace YooAsset
|
||||
_host = host;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -98,6 +100,7 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
return $"ClearMethod: {_options.ClearMethod}";
|
||||
|
||||
@@ -26,11 +26,12 @@ namespace YooAsset
|
||||
_resourcePackage = resourcePackage;
|
||||
_options = options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckInitStatus;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -99,6 +100,7 @@ namespace YooAsset
|
||||
SetResult();
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
return $"PackageVersion: {_resourcePackage.GetPackageVersion()}";
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 下载操作基类,提供资源下载、暂停、恢复和取消功能。
|
||||
/// </summary>
|
||||
public abstract class DownloaderOperation : AsyncOperationBase
|
||||
public abstract partial class DownloaderOperation : AsyncOperationBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
@@ -99,11 +99,13 @@ namespace YooAsset
|
||||
// 统计下载信息
|
||||
CalculateStatistics();
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
YooLogger.Log($"Beginning download of {TotalDownloadCount} files ({TotalDownloadBytes} bytes).");
|
||||
_steps = ESteps.Check;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
|
||||
@@ -29,10 +29,12 @@ namespace YooAsset
|
||||
_package = package;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.SetPlayMode;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -137,6 +139,7 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
return $"PlayMode: {_playMode}";
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public abstract class InitializePackageOptions
|
||||
{
|
||||
protected InitializePackageOptions() { }
|
||||
|
||||
/// <summary>
|
||||
/// 同时加载Bundle文件的最大并发数
|
||||
/// </summary>
|
||||
|
||||
@@ -28,10 +28,12 @@ namespace YooAsset
|
||||
_host = host;
|
||||
_parametersList = parametersList;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
|
||||
@@ -25,10 +25,12 @@ namespace YooAsset
|
||||
_host = host;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckParams;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
@@ -95,6 +97,7 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override string InternalGetDescription()
|
||||
{
|
||||
return $"PackageVersion: {_options.PackageVersion}";
|
||||
|
||||
@@ -30,10 +30,12 @@ namespace YooAsset
|
||||
_host = host;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckParams;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
|
||||
@@ -29,10 +29,12 @@ namespace YooAsset
|
||||
_host = host;
|
||||
_options = options;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.RequestPackageVersion;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
|
||||
@@ -72,11 +72,16 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public readonly List<int> ReferrerBundleIDs = new List<int>(10);
|
||||
[NonSerialized]
|
||||
private readonly HashSet<int> _referrerBundleIDs = new HashSet<int>();
|
||||
|
||||
[NonSerialized]
|
||||
private PackageManifest _manifest;
|
||||
[NonSerialized]
|
||||
private bool _isInitialized;
|
||||
[NonSerialized]
|
||||
private int _bundleType;
|
||||
[NonSerialized]
|
||||
private string _fileName;
|
||||
|
||||
|
||||
@@ -166,6 +171,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
#region 调试信息
|
||||
[NonSerialized]
|
||||
private List<string> _debugReferrerBundleNames;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -401,7 +401,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 将资源GUID转换为资源信息
|
||||
/// </summary>
|
||||
/// <param name="assetGUID">资源GUID</param>
|
||||
/// <param name="assetGuid">资源GUID</param>
|
||||
/// <param name="assetType">资源类型</param>
|
||||
/// <returns>返回资源信息对象,如果转换失败会返回一个无效的资源信息。</returns>
|
||||
public AssetInfo ConvertAssetGuidToAssetInfo(string assetGuid, System.Type assetType)
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 资源包裹类
|
||||
/// </summary>
|
||||
public class ResourcePackage
|
||||
public partial class ResourcePackage
|
||||
{
|
||||
private InitializePackageOperation _initializeOp;
|
||||
private ResourceManager _resourceManager;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cda191ef75dc59f408545d8f7d3644b0
|
||||
guid: 682ac5046f4686946b0003a449638651
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,61 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomPropertyDrawer(typeof(GameObjectReference))]
|
||||
public class GameObjectReferenceDrawer : PropertyDrawer
|
||||
{
|
||||
private const float LineSpacing = 2f;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty packageNameProp = property.FindPropertyRelative("_packageName");
|
||||
SerializedProperty assetGUIDProp = property.FindPropertyRelative("_assetGUID");
|
||||
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
{
|
||||
float lineHeight = EditorGUIUtility.singleLineHeight;
|
||||
Rect line = new Rect(position.x, position.y, position.width, lineHeight);
|
||||
|
||||
// 绘制 PackageName
|
||||
packageNameProp.stringValue = EditorGUI.TextField(line, "Package Name", packageNameProp.stringValue);
|
||||
|
||||
// 加载 GameObject
|
||||
string assetGUID = assetGUIDProp.stringValue;
|
||||
GameObject current = null;
|
||||
if (string.IsNullOrEmpty(assetGUID) == false)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
|
||||
if (string.IsNullOrEmpty(assetPath) == false)
|
||||
current = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||||
}
|
||||
|
||||
// 绘制 GameObject
|
||||
line.y += lineHeight + LineSpacing;
|
||||
GameObject newAsset = (GameObject)EditorGUI.ObjectField(line, "Game Object", current, typeof(GameObject), false);
|
||||
if (newAsset != current)
|
||||
{
|
||||
if (newAsset == null)
|
||||
{
|
||||
assetGUIDProp.stringValue = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
string newPath = AssetDatabase.GetAssetPath(newAsset);
|
||||
if (string.IsNullOrEmpty(newPath) == false)
|
||||
assetGUIDProp.stringValue = AssetDatabase.AssetPathToGUID(newPath);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制 AssetGUID
|
||||
line.y += lineHeight + LineSpacing;
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.TextField(line, "Asset GUID", assetGUIDProp.stringValue);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight * 3 + LineSpacing * 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53eb285fc3a7b614089a000f8c9c738c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,17 +1,31 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供构建缓存清理菜单入口
|
||||
/// </summary>
|
||||
internal class ClearBuildCacheWindow
|
||||
{
|
||||
private const string SBPEditorAssemblyName = "Unity.ScriptableBuildPipeline.Editor";
|
||||
private const string SBPBuildCacheTypeName = "UnityEditor.Build.Pipeline.Utilities.BuildCache";
|
||||
|
||||
[MenuItem("Tools/Clear Build Cache", false, 2)]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
// 清空SBP构建缓存
|
||||
UnityEditor.Build.Pipeline.Utilities.BuildCache.PurgeCache(false);
|
||||
var buildCacheType = Type.GetType($"{SBPBuildCacheTypeName}, {SBPEditorAssemblyName}");
|
||||
if (buildCacheType != null)
|
||||
{
|
||||
EditorAssemblyUtility.InvokePublicStaticMethod(buildCacheType, "PurgeCache", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Failed to find type: {SBPBuildCacheTypeName}");
|
||||
}
|
||||
|
||||
// 删除AssetDependDB文件
|
||||
string projectPath = YooAsset.Editor.EditorPathUtility.GetProjectPath();
|
||||
@@ -20,6 +34,8 @@ namespace YooAsset.Editor
|
||||
{
|
||||
File.Delete(databaseFilePath);
|
||||
}
|
||||
|
||||
Debug.Log("Clear build cache succeeded !");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@@ -6,16 +6,19 @@ using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class CreateBuildinCatalogWindow : EditorWindow
|
||||
/// <summary>
|
||||
/// 提供内置资源清单生成工具窗口
|
||||
/// </summary>
|
||||
public class CreateBuiltinCatalogWindow : EditorWindow
|
||||
{
|
||||
static CreateBuildinCatalogWindow _thisInstance;
|
||||
static CreateBuiltinCatalogWindow _thisInstance;
|
||||
|
||||
[MenuItem("Tools/内置清单生成工具(Catalog)", false, 101)]
|
||||
[MenuItem("Tools/Builtin Catalog Generator", false, 101)]
|
||||
static void ShowWindow()
|
||||
{
|
||||
if (_thisInstance == null)
|
||||
{
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(CreateBuildinCatalogWindow), false, "内置清单生成工具", true) as CreateBuildinCatalogWindow;
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(CreateBuiltinCatalogWindow), false, "Builtin Catalog Generator", true) as CreateBuiltinCatalogWindow;
|
||||
_thisInstance.minSize = new Vector2(800, 600);
|
||||
}
|
||||
_thisInstance.Show();
|
||||
@@ -27,7 +30,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("选择内置资源目录", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Select Builtin Resource Directory", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
string resultPath = EditorUtility.OpenFolderPanel("Find", "Assets/", "StreamingAssets");
|
||||
if (!string.IsNullOrEmpty(resultPath))
|
||||
@@ -38,7 +41,7 @@ namespace YooAsset.Editor
|
||||
|
||||
if (string.IsNullOrEmpty(_directoryRoot) == false)
|
||||
{
|
||||
if (GUILayout.Button("生成Catalog文件", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Generate Catalog File", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
CreateCatalogFile(_directoryRoot);
|
||||
}
|
||||
@@ -47,6 +50,13 @@ namespace YooAsset.Editor
|
||||
|
||||
private void CreateCatalogFile(string directoryRoot)
|
||||
{
|
||||
// 检查目录是否存在
|
||||
if (Directory.Exists(directoryRoot) == false)
|
||||
{
|
||||
Debug.LogError("Selected directory does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 搜索所有Package目录
|
||||
List<string> packageRoots = GetPackageRoots(directoryRoot);
|
||||
foreach (var packageRoot in packageRoots)
|
||||
@@ -55,26 +65,20 @@ namespace YooAsset.Editor
|
||||
string packageName = directoryInfo.Name;
|
||||
try
|
||||
{
|
||||
bool result = BuiltinCatalogHelper.CreateFile(null, packageName, packageRoot); //TODO 自行处理解密
|
||||
bool result = BuiltinCatalogHelper.CreateFile(null, packageName, packageRoot); // TODO: 根据业务需求处理清单解密。
|
||||
if (result == false)
|
||||
{
|
||||
Debug.LogError($"Create package {packageName} catalog file failed ! See the detail error in console !");
|
||||
Debug.LogError($"Failed to create a catalog file for package '{packageName}'. See Console for details.");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"Create package {packageName} catalog file failed ! {ex.Message}");
|
||||
Debug.LogError($"Failed to create a catalog file for package '{packageName}': {ex.Message}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
private List<string> GetPackageRoots(string rootPath)
|
||||
{
|
||||
// 检查目录是否存在
|
||||
if (Directory.Exists(rootPath) == false)
|
||||
{
|
||||
throw new DirectoryNotFoundException($"目录不存在: {rootPath}");
|
||||
}
|
||||
|
||||
// 搜索所有 .version 文件(包含子目录)
|
||||
string[] versionFiles = Directory.GetFiles(
|
||||
rootPath,
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@@ -6,16 +6,19 @@ using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供空资源清单生成工具窗口
|
||||
/// </summary>
|
||||
public class CreateEmptyCatalogWindow : EditorWindow
|
||||
{
|
||||
static CreateEmptyCatalogWindow _thisInstance;
|
||||
|
||||
[MenuItem("Tools/空清单生成工具(Catalog)", false, 102)]
|
||||
[MenuItem("Tools/Empty Catalog Generator", false, 102)]
|
||||
static void ShowWindow()
|
||||
{
|
||||
if (_thisInstance == null)
|
||||
{
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(CreateEmptyCatalogWindow), false, "空清单生成工具", true) as CreateEmptyCatalogWindow;
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(CreateEmptyCatalogWindow), false, "Empty Catalog Generator", true) as CreateEmptyCatalogWindow;
|
||||
_thisInstance.minSize = new Vector2(800, 600);
|
||||
}
|
||||
_thisInstance.Show();
|
||||
@@ -32,9 +35,9 @@ namespace YooAsset.Editor
|
||||
|
||||
if (string.IsNullOrEmpty(_packageName) == false)
|
||||
{
|
||||
if (GUILayout.Button("生成空的Catalog文件", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Generate Empty Catalog File", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
string outputPath = EditorDialogUtility.OpenFolderPanel("输出目录", "Assets/");
|
||||
string outputPath = EditorDialogUtility.OpenFolderPanel("Output Directory", "Assets/");
|
||||
if (string.IsNullOrEmpty(outputPath) == false)
|
||||
{
|
||||
CreateEmptyCatalogFile(outputPath);
|
||||
@@ -50,12 +53,12 @@ namespace YooAsset.Editor
|
||||
bool result = BuiltinCatalogHelper.CreateEmptyFile(_packageName, string.Empty, outputPath);
|
||||
if (result == false)
|
||||
{
|
||||
Debug.LogError($"Create package {_packageName} catalog file failed ! See the detail error in console !");
|
||||
Debug.LogError($"Failed to create a catalog file for package '{_packageName}'. See Console for details.");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"Create package {_packageName} catalog file failed ! {ex.Message}");
|
||||
Debug.LogError($"Failed to create a catalog file for package '{_packageName}': {ex.Message}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@ using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using YooAsset.Editor;
|
||||
|
||||
/// <summary>
|
||||
/// 提供自定义构建管线的编辑器视图
|
||||
/// </summary>
|
||||
[BuildPipelineAttribute("CustomBuildPipeline")]
|
||||
internal class CustomBuildPipelineViewer : LegacyBuildPipelineViewer
|
||||
{
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using YooAsset.Editor;
|
||||
|
||||
/// <summary>
|
||||
/// 按文件名生成资源定位地址
|
||||
/// </summary>
|
||||
[DisplayName("定位地址: 文件名.智能尾缀")]
|
||||
public class AddressByFileNameAndExt : IAddressRule
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string GetAssetAddress(AddressRuleData data)
|
||||
{
|
||||
var extension = Path.GetExtension(data.AssetPath);
|
||||
if (extension == ".asset")
|
||||
{
|
||||
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(data.AssetPath);
|
||||
if (asset == null)
|
||||
throw new InvalidOperationException($"Asset not found: '{data.AssetPath}'.");
|
||||
|
||||
var assetType = asset.GetType();
|
||||
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(data.AssetPath);
|
||||
return fileNameWithoutExtension + $".{assetType.Name.ToLowerInvariant()}";
|
||||
}
|
||||
|
||||
return Path.GetFileName(data.AssetPath);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using YooAsset.Editor;
|
||||
|
||||
[DisplayName("定位地址: 文件名.智能尾缀")]
|
||||
public class AddressByFileNameAndExt : IAddressRule
|
||||
{
|
||||
public string GetAssetAddress(AddressRuleData data)
|
||||
{
|
||||
var ext = Path.GetExtension(data.AssetPath);
|
||||
if (ext == ".asset")
|
||||
{
|
||||
var a = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(data.AssetPath);
|
||||
if (a == null) return ".errortype";
|
||||
var type = a.GetType();
|
||||
var dt = Path.GetFileNameWithoutExtension(data.AssetPath);
|
||||
return dt + $".{type.Name.ToLowerInvariant()}";
|
||||
}
|
||||
|
||||
return Path.GetFileName(data.AssetPath);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,24 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using YooAsset.Editor;
|
||||
|
||||
/// <summary>
|
||||
/// 将特效纹理按首字符分组到资源包
|
||||
/// </summary>
|
||||
[DisplayName("打包特效纹理(自定义)")]
|
||||
public class PackEffectTexture : IBundlePackRule
|
||||
{
|
||||
private const string PackDirectory = "Assets/Effect/Textures/";
|
||||
|
||||
/// <inheritdoc/>
|
||||
BundlePackRuleResult IBundlePackRule.GetPackRuleResult(BundlePackRuleData data)
|
||||
{
|
||||
string assetPath = data.AssetPath;
|
||||
if (assetPath.StartsWith(PackDirectory) == false)
|
||||
throw new Exception($"Only support folder : {PackDirectory}");
|
||||
throw new ArgumentException($"Only support folder: {PackDirectory}", nameof(data));
|
||||
|
||||
string assetName = Path.GetFileName(assetPath).ToLower();
|
||||
string firstChar = assetName.Substring(0, 1);
|
||||
@@ -24,9 +28,13 @@ public class PackEffectTexture : IBundlePackRule
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按视频资源路径生成原始文件资源包
|
||||
/// </summary>
|
||||
[DisplayName("打包视频(自定义)")]
|
||||
public class PackVideo : IBundlePackRule
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public BundlePackRuleResult GetPackRuleResult(BundlePackRuleData data)
|
||||
{
|
||||
string bundleName = RemoveExtension(data.AssetPath);
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if YOO_MACRO_SUPPORT
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class MacroDefine
|
||||
/// <summary>
|
||||
/// 提供 YooAsset 版本相关的脚本宏定义
|
||||
/// </summary>
|
||||
public static class MacroDefine
|
||||
{
|
||||
/// <summary>
|
||||
/// YooAsset版本宏定义
|
||||
/// YooAsset 版本宏定义集合
|
||||
/// </summary>
|
||||
public static readonly List<string> Macros = new List<string>()
|
||||
public static IReadOnlyList<string> Macros { get; } = new List<string>()
|
||||
{
|
||||
"YOO_ASSET_2",
|
||||
"YOO_ASSET_2_3",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -8,6 +8,9 @@ using UnityEditor;
|
||||
#if YOO_MACRO_SUPPORT
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 在生成 C# 工程文件时注入 YooAsset 版本宏定义
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
public class MacroProcessor : AssetPostprocessor
|
||||
{
|
||||
@@ -41,7 +44,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理宏定义
|
||||
/// 处理工程文件中的宏定义
|
||||
/// </summary>
|
||||
private static bool ProcessDefineConstants(XmlElement element)
|
||||
{
|
||||
@@ -76,7 +79,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测工程是否引用了YooAsset
|
||||
/// 检查工程是否引用了 YooAsset
|
||||
/// </summary>
|
||||
private static bool IsCSProjectReferenced(XmlElement element)
|
||||
{
|
||||
@@ -93,7 +96,11 @@ namespace YooAsset.Editor
|
||||
if (childNode.Name != "Reference" && childNode.Name != "ProjectReference")
|
||||
continue;
|
||||
|
||||
string include = childNode.Attributes["Include"].Value;
|
||||
XmlAttribute includeAttribute = childNode.Attributes["Include"];
|
||||
if (includeAttribute == null)
|
||||
continue;
|
||||
|
||||
string include = includeAttribute.Value;
|
||||
if (include.Contains("YooAsset"))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -9,10 +9,13 @@ using UnityEngine;
|
||||
#if YOO_MACRO_SUPPORT
|
||||
namespace YooAsset.Editor.Experiment
|
||||
{
|
||||
/// <summary>
|
||||
/// 通过 csc.rsp 文件注入 YooAsset 版本宏定义
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
public class RspGenerator
|
||||
{
|
||||
// csc.rsp文件路径
|
||||
// Unity 编译器响应文件路径
|
||||
private static string RspFilePath => Path.Combine(Application.dataPath, "csc.rsp");
|
||||
|
||||
static RspGenerator()
|
||||
@@ -21,9 +24,9 @@ namespace YooAsset.Editor.Experiment
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新csc.rsp文件
|
||||
/// 更新 csc.rsp 文件
|
||||
/// </summary>
|
||||
private static void UpdateRspFile(List<string> addMacros, List<string> removeMacros)
|
||||
private static void UpdateRspFile(IReadOnlyList<string> addMacros, IReadOnlyList<string> removeMacros)
|
||||
{
|
||||
var existingDefines = new HashSet<string>();
|
||||
var otherLines = new List<string>();
|
||||
@@ -34,24 +37,26 @@ namespace YooAsset.Editor.Experiment
|
||||
// 2. 添加新宏
|
||||
if (addMacros != null && addMacros.Count > 0)
|
||||
{
|
||||
addMacros.ForEach(x =>
|
||||
foreach (var x in addMacros)
|
||||
{
|
||||
if (existingDefines.Contains(x) == false)
|
||||
existingDefines.Add(x);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 移除指定宏
|
||||
if (removeMacros != null && removeMacros.Count > 0)
|
||||
{
|
||||
removeMacros.ForEach(x =>
|
||||
foreach (var x in removeMacros)
|
||||
{
|
||||
existingDefines.Remove(x);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 重新生成内容
|
||||
WriteRspFile(existingDefines, otherLines);
|
||||
bool changed = WriteRspFile(existingDefines, otherLines);
|
||||
if (changed == false)
|
||||
return;
|
||||
|
||||
// 5. 刷新AssetDatabase
|
||||
AssetDatabase.Refresh();
|
||||
@@ -59,7 +64,7 @@ namespace YooAsset.Editor.Experiment
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取csc.rsp文件,返回宏定义和其他行
|
||||
/// 读取 csc.rsp 文件中的宏定义和其他行
|
||||
/// </summary>
|
||||
private static void ReadRspFile(HashSet<string> defines, List<string> others)
|
||||
{
|
||||
@@ -90,9 +95,10 @@ namespace YooAsset.Editor.Experiment
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新写入csc.rsp文件
|
||||
/// 重新写入 csc.rsp 文件
|
||||
/// </summary>
|
||||
private static void WriteRspFile(HashSet<string> defines, List<string> others)
|
||||
/// <returns>文件内容发生变化时返回 true</returns>
|
||||
private static bool WriteRspFile(HashSet<string> defines, List<string> others)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (others != null && others.Count > 0)
|
||||
@@ -108,7 +114,16 @@ namespace YooAsset.Editor.Experiment
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(RspFilePath, sb.ToString());
|
||||
string newContent = sb.ToString();
|
||||
if (File.Exists(RspFilePath))
|
||||
{
|
||||
string oldContent = File.ReadAllText(RspFilePath);
|
||||
if (oldContent == newContent)
|
||||
return false;
|
||||
}
|
||||
|
||||
File.WriteAllText(RspFilePath, newContent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@@ -6,16 +6,19 @@ using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供补丁包差异比对工具窗口
|
||||
/// </summary>
|
||||
public class PackageComparatorWindow : EditorWindow
|
||||
{
|
||||
static PackageComparatorWindow _thisInstance;
|
||||
|
||||
[MenuItem("Tools/补丁包比对工具", false, 103)]
|
||||
[MenuItem("Tools/Patch Package Comparator", false, 103)]
|
||||
static void ShowWindow()
|
||||
{
|
||||
if (_thisInstance == null)
|
||||
{
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(PackageComparatorWindow), false, "补丁包比对工具", true) as PackageComparatorWindow;
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(PackageComparatorWindow), false, "Patch Package Comparator", true) as PackageComparatorWindow;
|
||||
_thisInstance.minSize = new Vector2(800, 600);
|
||||
}
|
||||
_thisInstance.Show();
|
||||
@@ -32,7 +35,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("选择补丁包1", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Select Patch Package 1", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
string resultPath = EditorUtility.OpenFilePanel("Find", "Assets/", "bytes");
|
||||
if (string.IsNullOrEmpty(resultPath))
|
||||
@@ -44,7 +47,7 @@ namespace YooAsset.Editor
|
||||
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("选择补丁包2", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Select Patch Package 2", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
string resultPath = EditorUtility.OpenFilePanel("Find", "Assets/", "bytes");
|
||||
if (string.IsNullOrEmpty(resultPath))
|
||||
@@ -56,17 +59,26 @@ namespace YooAsset.Editor
|
||||
|
||||
if (string.IsNullOrEmpty(_manifestPath1) == false && string.IsNullOrEmpty(_manifestPath2) == false)
|
||||
{
|
||||
if (GUILayout.Button("比对差异", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Compare Differences", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
try
|
||||
{
|
||||
ComparePackage(_changeList, _newList);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_changeList.Clear();
|
||||
_newList.Clear();
|
||||
Debug.LogError($"Failed to compare patch packages: {ex.Message}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
using (new EditorGUI.DisabledScope(false))
|
||||
{
|
||||
int totalCount = _changeList.Count;
|
||||
EditorGUILayout.Foldout(true, $"差异列表 ( {totalCount} )");
|
||||
EditorGUILayout.Foldout(true, $"Changed Bundles ( {totalCount} )");
|
||||
|
||||
EditorGUI.indentLevel = 1;
|
||||
_scrollPos1 = EditorGUILayout.BeginScrollView(_scrollPos1);
|
||||
@@ -84,7 +96,7 @@ namespace YooAsset.Editor
|
||||
using (new EditorGUI.DisabledScope(false))
|
||||
{
|
||||
int totalCount = _newList.Count;
|
||||
EditorGUILayout.Foldout(true, $"新增列表 ( {totalCount} )");
|
||||
EditorGUILayout.Foldout(true, $"New Bundles ( {totalCount} )");
|
||||
|
||||
EditorGUI.indentLevel = 1;
|
||||
_scrollPos2 = EditorGUILayout.BeginScrollView(_scrollPos2);
|
||||
@@ -104,13 +116,13 @@ namespace YooAsset.Editor
|
||||
changeList.Clear();
|
||||
newList.Clear();
|
||||
|
||||
// 加载补丁清单1
|
||||
// 加载基准补丁清单
|
||||
byte[] bytesData1 = FileUtility.ReadAllBytes(_manifestPath1);
|
||||
PackageManifest manifest1 = PackageManifestHelper.DeserializeManifestFromBinary(bytesData1, null); //TODO 自行处理解密
|
||||
PackageManifest manifest1 = PackageManifestHelper.DeserializeManifestFromBinary(bytesData1, null); // TODO: 根据业务需求处理清单解密。
|
||||
|
||||
// 加载补丁清单1
|
||||
// 加载待比对补丁清单
|
||||
byte[] bytesData2 = FileUtility.ReadAllBytes(_manifestPath2);
|
||||
PackageManifest manifest2 = PackageManifestHelper.DeserializeManifestFromBinary(bytesData2, null); //TODO 自行处理解密
|
||||
PackageManifest manifest2 = PackageManifestHelper.DeserializeManifestFromBinary(bytesData2, null); // TODO: 根据业务需求处理清单解密。
|
||||
|
||||
// 拷贝文件列表
|
||||
foreach (var bundle2 in manifest2.BundleList)
|
||||
@@ -132,7 +144,7 @@ namespace YooAsset.Editor
|
||||
changeList.Sort((x, y) => string.Compare(x.BundleName, y.BundleName));
|
||||
newList.Sort((x, y) => string.Compare(x.BundleName, y.BundleName));
|
||||
|
||||
Debug.Log("资源包差异比对完成!");
|
||||
Debug.Log("Package comparison completed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,19 @@ using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供补丁包导入工具窗口
|
||||
/// </summary>
|
||||
public class PackageImporterWindow : EditorWindow
|
||||
{
|
||||
static PackageImporterWindow _thisInstance;
|
||||
|
||||
[MenuItem("Tools/补丁包导入工具", false, 104)]
|
||||
[MenuItem("Tools/Patch Package Importer", false, 104)]
|
||||
static void ShowWindow()
|
||||
{
|
||||
if (_thisInstance == null)
|
||||
{
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(PackageImporterWindow), false, "补丁包导入工具", true) as PackageImporterWindow;
|
||||
_thisInstance = EditorWindow.GetWindow(typeof(PackageImporterWindow), false, "Patch Package Importer", true) as PackageImporterWindow;
|
||||
_thisInstance.minSize = new Vector2(800, 600);
|
||||
}
|
||||
_thisInstance.Show();
|
||||
@@ -26,7 +29,12 @@ namespace YooAsset.Editor
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("选择补丁包", GUILayout.MaxWidth(150)))
|
||||
_packageName = EditorGUILayout.TextField("Package Name", _packageName);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Select Patch Package", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
string resultPath = EditorUtility.OpenFilePanel("Find", "Assets/", "bytes");
|
||||
if (!string.IsNullOrEmpty(resultPath))
|
||||
@@ -37,54 +45,84 @@ namespace YooAsset.Editor
|
||||
|
||||
if (string.IsNullOrEmpty(_manifestPath) == false)
|
||||
{
|
||||
if (GUILayout.Button("导入补丁包(全部文件)", GUILayout.MaxWidth(150)))
|
||||
if (GUILayout.Button("Import Patch Package (All Files)", GUILayout.MaxWidth(150)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(_packageName))
|
||||
{
|
||||
Debug.LogError("Package name is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string streamingAssetsRoot = BundleBuilderHelper.GetStreamingAssetsRoot();
|
||||
EditorFileUtility.ClearFolder(streamingAssetsRoot);
|
||||
CopyPackageFiles(_manifestPath);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"Failed to import patch package '{_packageName}': {ex.Message}.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyPackageFiles(string manifestFilePath)
|
||||
{
|
||||
string manifestFileName = Path.GetFileNameWithoutExtension(manifestFilePath);
|
||||
string outputDirectory = Path.GetDirectoryName(manifestFilePath);
|
||||
string sourceRoot = Path.GetDirectoryName(manifestFilePath);
|
||||
if (string.IsNullOrEmpty(sourceRoot))
|
||||
throw new DirectoryNotFoundException("Patch package directory does not exist.");
|
||||
|
||||
string versionFileName = YooAssetConfiguration.GetPackageVersionFileName(_packageName);
|
||||
string versionSourcePath = Path.Combine(sourceRoot, versionFileName);
|
||||
string packageVersion = File.ReadAllText(versionSourcePath).Trim();
|
||||
string manifestFileName = YooAssetConfiguration.GetManifestBinaryFileName(_packageName, packageVersion);
|
||||
string hashFileName = YooAssetConfiguration.GetPackageHashFileName(_packageName, packageVersion);
|
||||
string selectedFileName = Path.GetFileName(manifestFilePath);
|
||||
if (selectedFileName != manifestFileName)
|
||||
throw new InvalidDataException($"Selected manifest file '{selectedFileName}' does not match expected manifest file '{manifestFileName}'.");
|
||||
|
||||
string destRoot = Path.Combine(BundleBuilderHelper.GetStreamingAssetsRoot(), _packageName);
|
||||
|
||||
// 清空旧目录
|
||||
EditorFileUtility.DeleteDirectory(destRoot);
|
||||
EditorFileUtility.CreateDirectory(destRoot);
|
||||
|
||||
// 拷贝核心文件
|
||||
{
|
||||
string sourcePath = $"{outputDirectory}/{manifestFileName}.bytes";
|
||||
string destPath = $"{BundleBuilderHelper.GetStreamingAssetsRoot()}/{_packageName}/{manifestFileName}.bytes";
|
||||
string sourcePath = Path.Combine(sourceRoot, manifestFileName);
|
||||
string destPath = Path.Combine(destRoot, manifestFileName);
|
||||
EditorFileUtility.CopyFile(sourcePath, destPath, true);
|
||||
}
|
||||
{
|
||||
string sourcePath = $"{outputDirectory}/{manifestFileName}.hash";
|
||||
string destPath = $"{BundleBuilderHelper.GetStreamingAssetsRoot()}/{_packageName}/{manifestFileName}.hash";
|
||||
string sourcePath = Path.Combine(sourceRoot, hashFileName);
|
||||
string destPath = Path.Combine(destRoot, hashFileName);
|
||||
EditorFileUtility.CopyFile(sourcePath, destPath, true);
|
||||
}
|
||||
{
|
||||
string fileName = YooAssetConfiguration.GetPackageVersionFileName(_packageName);
|
||||
string sourcePath = $"{outputDirectory}/{fileName}";
|
||||
string destPath = $"{BundleBuilderHelper.GetStreamingAssetsRoot()}/{_packageName}/{fileName}";
|
||||
string sourcePath = versionSourcePath;
|
||||
string destPath = Path.Combine(destRoot, versionFileName);
|
||||
EditorFileUtility.CopyFile(sourcePath, destPath, true);
|
||||
}
|
||||
|
||||
// 加载补丁清单
|
||||
byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath);
|
||||
PackageManifest manifest = PackageManifestHelper.DeserializeManifestFromBinary(bytesData, null); //TODO 自行处理解密
|
||||
PackageManifest manifest = PackageManifestHelper.DeserializeManifestFromBinary(bytesData, null); // TODO: 根据业务需求处理清单解密。
|
||||
|
||||
// 拷贝文件列表
|
||||
int fileCount = 0;
|
||||
foreach (var packageBundle in manifest.BundleList)
|
||||
{
|
||||
fileCount++;
|
||||
string sourcePath = $"{outputDirectory}/{packageBundle.GetFileName()}";
|
||||
string destPath = $"{BundleBuilderHelper.GetStreamingAssetsRoot()}/{_packageName}/{packageBundle.GetFileName()}";
|
||||
string fileName = packageBundle.GetFileName();
|
||||
string sourcePath = Path.Combine(sourceRoot, fileName);
|
||||
string destPath = Path.Combine(destRoot, fileName);
|
||||
EditorFileUtility.CopyFile(sourcePath, destPath, true);
|
||||
}
|
||||
|
||||
Debug.Log($"补丁包拷贝完成,一共拷贝了{fileCount}个资源文件");
|
||||
AssetDatabase.Refresh();
|
||||
Debug.Log($"Patch package copy completed. Copied {fileCount} bundle files.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,26 @@ using YooAsset.Editor;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 在应用构建前生成内置资源清单
|
||||
/// </summary>
|
||||
public class PreprocessBuildCatalog : UnityEditor.Build.IPreprocessBuildWithReport
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建预处理回调顺序
|
||||
/// </summary>
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// 在构建应用程序前自动生成内置资源目录文件。
|
||||
/// 原理:搜索StreamingAssets目录下的所有资源文件,将这些文件信息写入文件,然后在运行时做查询用途。
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
|
||||
{
|
||||
YooLogger.Log("Begin to create catalog file !");
|
||||
YooLogger.Log("Starting catalog file generation.");
|
||||
|
||||
string rootPath = BundleBuilderHelper.GetStreamingAssetsRoot();
|
||||
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
|
||||
if (rootDirectory.Exists == false)
|
||||
{
|
||||
Debug.LogWarning($"Can not found StreamingAssets root directory : {rootPath}");
|
||||
Debug.LogWarning("StreamingAssets root directory does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,18 +33,18 @@ namespace YooAsset
|
||||
foreach (var subDirectory in subDirectories)
|
||||
{
|
||||
string packageName = subDirectory.Name;
|
||||
string pacakgeDirectory = subDirectory.FullName;
|
||||
string packageDirectory = subDirectory.FullName;
|
||||
try
|
||||
{
|
||||
bool result = BuiltinCatalogHelper.CreateFile(null, packageName, pacakgeDirectory); //TODO 自行处理解密
|
||||
bool result = BuiltinCatalogHelper.CreateFile(null, packageName, packageDirectory); // TODO: 根据业务需求处理清单解密。
|
||||
if (result == false)
|
||||
{
|
||||
Debug.LogError($"Create package {packageName} catalog file failed ! See the detail error in console !");
|
||||
Debug.LogError($"Failed to create a catalog file for package '{packageName}'. See Console for details.");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"Create package {packageName} catalog file failed ! {ex.Message}");
|
||||
Debug.LogError($"Failed to create a catalog file for package '{packageName}': {ex.Message}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -7,28 +7,51 @@ using UnityEngine.Rendering;
|
||||
using UnityEditor;
|
||||
using YooAsset.Editor;
|
||||
|
||||
/// <summary>
|
||||
/// 封装 Unity 编辑器中的 ShaderVariantCollection 反射调用
|
||||
/// </summary>
|
||||
public static class ShaderVariantCollectionHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 清空当前编辑器记录的着色器变种集合
|
||||
/// </summary>
|
||||
public static void ClearCurrentShaderVariantCollection()
|
||||
{
|
||||
EditorAssemblyUtility.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "ClearCurrentShaderVariantCollection");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存当前编辑器记录的着色器变种集合
|
||||
/// </summary>
|
||||
/// <param name="savePath">保存目标路径</param>
|
||||
public static void SaveCurrentShaderVariantCollection(string savePath)
|
||||
{
|
||||
EditorAssemblyUtility.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "SaveCurrentShaderVariantCollection", savePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前着色器变种集合中的着色器数量
|
||||
/// </summary>
|
||||
/// <returns>着色器数量</returns>
|
||||
public static int GetCurrentShaderVariantCollectionShaderCount()
|
||||
{
|
||||
return (int)EditorAssemblyUtility.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionShaderCount");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前着色器变种集合中的变种数量
|
||||
/// </summary>
|
||||
/// <returns>变种数量</returns>
|
||||
public static int GetCurrentShaderVariantCollectionVariantCount()
|
||||
{
|
||||
return (int)EditorAssemblyUtility.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionVariantCount");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取着色器的变种总数量
|
||||
/// 获取指定着色器资源的变种总数量
|
||||
/// </summary>
|
||||
/// <param name="assetPath">着色器资源路径</param>
|
||||
/// <returns>变种总数量的字符串表示</returns>
|
||||
public static string GetShaderVariantCount(string assetPath)
|
||||
{
|
||||
Shader shader = AssetDatabase.LoadAssetAtPath<Shader>(assetPath);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -7,50 +7,70 @@ using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor;
|
||||
|
||||
/// <summary>
|
||||
/// 着色器变种集合的可序列化清单
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ShaderVariantCollectionManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个着色器变种的序列化信息
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ShaderVariantElement : IComparable<ShaderVariantElement>
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于稳定排序的组合键
|
||||
/// </summary>
|
||||
public string SortValue { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Pass type to use in this variant.
|
||||
/// 变种使用的渲染通道类型
|
||||
/// </summary>
|
||||
public PassType PassType;
|
||||
|
||||
/// <summary>
|
||||
/// Array of shader keywords to use in this variant.
|
||||
/// 变种使用的着色器关键字数组
|
||||
/// </summary>
|
||||
public string[] Keywords;
|
||||
|
||||
/// <summary>
|
||||
/// 生成排序键
|
||||
/// </summary>
|
||||
public void MakeSortValue()
|
||||
{
|
||||
string combineKeyword = string.Empty;
|
||||
for (int i = 0; i < Keywords.Length; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
combineKeyword = Keywords[0];
|
||||
combineKeyword = Keywords[i];
|
||||
else
|
||||
combineKeyword = $"{combineKeyword}+{Keywords[0]}";
|
||||
combineKeyword = $"{combineKeyword}+{Keywords[i]}";
|
||||
}
|
||||
|
||||
SortValue = $"{PassType}+{combineKeyword}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int CompareTo(ShaderVariantElement other)
|
||||
{
|
||||
return SortValue.CompareTo(other.SortValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单个着色器及其变种列表的序列化信息
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ShaderVariantInfo : IComparable<ShaderVariantInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于稳定排序的组合键
|
||||
/// </summary>
|
||||
public string SortValue { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 着色器资源路径.
|
||||
/// 着色器资源路径
|
||||
/// </summary>
|
||||
public string AssetPath;
|
||||
|
||||
@@ -69,10 +89,15 @@ public class ShaderVariantCollectionManifest
|
||||
/// </summary>
|
||||
public List<ShaderVariantElement> ShaderVariantElements = new List<ShaderVariantElement>(1000);
|
||||
|
||||
/// <summary>
|
||||
/// 生成排序键
|
||||
/// </summary>
|
||||
public void MakeSortValue()
|
||||
{
|
||||
SortValue = AssetPath + "+" + ShaderName;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int CompareTo(ShaderVariantInfo other)
|
||||
{
|
||||
return SortValue.CompareTo(other.SortValue);
|
||||
@@ -81,33 +106,36 @@ public class ShaderVariantCollectionManifest
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Number of shaders in this collection
|
||||
/// 清单中的着色器总数
|
||||
/// </summary>
|
||||
public int ShaderTotalCount;
|
||||
|
||||
/// <summary>
|
||||
/// Number of total varians in this collection
|
||||
/// 清单中的变种总数
|
||||
/// </summary>
|
||||
public int VariantTotalCount;
|
||||
|
||||
/// <summary>
|
||||
/// Shader variants info list.
|
||||
/// 着色器变种信息列表
|
||||
/// </summary>
|
||||
public List<ShaderVariantInfo> ShaderVariantInfos = new List<ShaderVariantInfo>(1000);
|
||||
|
||||
/// <summary>
|
||||
/// 添加着色器变种信息
|
||||
/// </summary>
|
||||
/// <param name="assetPath">着色器资源路径</param>
|
||||
/// <param name="shaderName">着色器名称</param>
|
||||
/// <param name="passType">渲染通道类型</param>
|
||||
/// <param name="keywords">着色器关键字数组</param>
|
||||
public void AddShaderVariant(string assetPath, string shaderName, PassType passType, string[] keywords)
|
||||
{
|
||||
// 排序Keyword列表
|
||||
List<string> temper = new List<string>(keywords);
|
||||
temper.Sort();
|
||||
List<string> sortedKeywords = new List<string>(keywords);
|
||||
sortedKeywords.Sort();
|
||||
|
||||
var info = GetOrCreateShaderVariantInfo(assetPath, shaderName);
|
||||
ShaderVariantElement element = new ShaderVariantElement();
|
||||
element.PassType = passType;
|
||||
element.Keywords = temper.ToArray();
|
||||
element.Keywords = sortedKeywords.ToArray();
|
||||
element.MakeSortValue();
|
||||
info.ShaderVariantElements.Add(element);
|
||||
info.ShaderVariantCount++;
|
||||
@@ -126,20 +154,22 @@ public class ShaderVariantCollectionManifest
|
||||
}
|
||||
|
||||
if (selectList.Count != 1)
|
||||
throw new Exception("Should never get here !");
|
||||
throw new InvalidOperationException($"Unexpected duplicate ShaderVariantInfo entries (count={selectList.Count}).");
|
||||
|
||||
return selectList[0];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 解析SVC文件并将数据写入到清单
|
||||
/// 从 ShaderVariantCollection 提取清单数据
|
||||
/// </summary>
|
||||
/// <param name="svc">待解析的着色器变种集合</param>
|
||||
/// <returns>提取后的着色器变种清单</returns>
|
||||
public static ShaderVariantCollectionManifest Extract(ShaderVariantCollection svc)
|
||||
{
|
||||
if (svc == null)
|
||||
throw new ArgumentNullException(nameof(svc));
|
||||
|
||||
var manifest = new ShaderVariantCollectionManifest();
|
||||
manifest.ShaderTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount();
|
||||
manifest.VariantTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionVariantCount();
|
||||
|
||||
using (var so = new SerializedObject(svc))
|
||||
{
|
||||
@@ -149,30 +179,23 @@ public class ShaderVariantCollectionManifest
|
||||
for (int i = 0; i < shaderArray.arraySize; ++i)
|
||||
{
|
||||
var shaderRef = shaderArray.FindPropertyRelative($"data[{i}].first");
|
||||
var shaderVariantsArray = shaderArray.FindPropertyRelative($"data[{i}].second.variants");
|
||||
if (shaderRef != null && shaderRef.propertyType == SerializedPropertyType.ObjectReference && shaderVariantsArray != null && shaderVariantsArray.isArray)
|
||||
{
|
||||
var shader = shaderRef.objectReferenceValue as Shader;
|
||||
if (shader == null)
|
||||
{
|
||||
throw new Exception("Invalid shader in ShaderVariantCollection file.");
|
||||
}
|
||||
throw new InvalidOperationException("Invalid shader in ShaderVariantCollection file.");
|
||||
|
||||
string shaderAssetPath = AssetDatabase.GetAssetPath(shader);
|
||||
string shaderName = shader.name;
|
||||
|
||||
// 添加变种信息
|
||||
var shaderVariantsArray = shaderArray.FindPropertyRelative($"data[{i}].second.variants");
|
||||
for (int j = 0; j < shaderVariantsArray.arraySize; ++j)
|
||||
{
|
||||
var propKeywords = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].keywords");
|
||||
var propPassType = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].passType");
|
||||
if (propKeywords != null && propPassType != null && propKeywords.propertyType == SerializedPropertyType.String)
|
||||
{
|
||||
string[] keywords = propKeywords.stringValue.Split(' ');
|
||||
PassType pathType = (PassType)propPassType.intValue;
|
||||
manifest.AddShaderVariant(shaderAssetPath, shaderName, pathType, keywords);
|
||||
}
|
||||
}
|
||||
|
||||
string[] keywords = propKeywords.stringValue.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
PassType passType = (PassType)propPassType.intValue;
|
||||
manifest.AddShaderVariant(shaderAssetPath, shaderName, passType, keywords);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,6 +208,13 @@ public class ShaderVariantCollectionManifest
|
||||
shaderVariantInfo.ShaderVariantElements.Sort();
|
||||
}
|
||||
|
||||
// 统计数量
|
||||
foreach (var shaderVariantInfo in manifest.ShaderVariantInfos)
|
||||
{
|
||||
manifest.VariantTotalCount += shaderVariantInfo.ShaderVariantElements.Count;
|
||||
}
|
||||
manifest.ShaderTotalCount = manifest.ShaderVariantInfos.Count;
|
||||
|
||||
return manifest;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
@@ -8,6 +8,9 @@ using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using YooAsset.Editor;
|
||||
|
||||
/// <summary>
|
||||
/// 收集资源包裹中材质产生的着色器变种
|
||||
/// </summary>
|
||||
public static class ShaderVariantCollector
|
||||
{
|
||||
private enum ESteps
|
||||
@@ -34,21 +37,33 @@ public static class ShaderVariantCollector
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 开始收集
|
||||
/// 启动着色器变种收集流程
|
||||
/// </summary>
|
||||
/// <param name="savePath">收集结果保存路径,扩展名必须为 .shadervariants。</param>
|
||||
/// <param name="packageName">参与收集的资源包裹名称</param>
|
||||
/// <param name="processMaxNum">每批处理的材质数量</param>
|
||||
/// <param name="completedCallback">收集完成后的回调</param>
|
||||
public static void Run(string savePath, string packageName, int processMaxNum, Action completedCallback)
|
||||
{
|
||||
if (_steps != ESteps.None)
|
||||
return;
|
||||
|
||||
if (EditorSceneUtility.HasDirtyScenes())
|
||||
{
|
||||
UnityEngine.Debug.LogError("Unsaved scenes detected. Save all scenes before collecting shader variants.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Path.HasExtension(savePath) == false)
|
||||
savePath = $"{savePath}.shadervariants";
|
||||
if (Path.GetExtension(savePath) != ".shadervariants")
|
||||
throw new System.Exception("Shader variant file extension is invalid.");
|
||||
throw new System.ArgumentException("Shader variant file extension is invalid.", nameof(savePath));
|
||||
if (string.IsNullOrEmpty(packageName))
|
||||
throw new System.Exception("Package name is null or empty !");
|
||||
throw new System.ArgumentNullException(nameof(packageName));
|
||||
if (processMaxNum <= 0)
|
||||
throw new System.ArgumentOutOfRangeException(nameof(processMaxNum), "Process capacity must be greater than zero.");
|
||||
|
||||
// 注意:先删除再保存,否则ShaderVariantCollection内容将无法及时刷新
|
||||
// Unity 对同名 ShaderVariantCollection 的刷新存在延迟,先删除旧资源再写入新结果。
|
||||
AssetDatabase.DeleteAsset(savePath);
|
||||
EditorFileUtility.CreateFileDirectory(savePath);
|
||||
_savePath = savePath;
|
||||
@@ -67,6 +82,17 @@ public static class ShaderVariantCollector
|
||||
}
|
||||
|
||||
private static void EditorUpdate()
|
||||
{
|
||||
try
|
||||
{
|
||||
InternalUpdate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Finish(false, ex);
|
||||
}
|
||||
}
|
||||
private static void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None)
|
||||
return;
|
||||
@@ -75,14 +101,14 @@ public static class ShaderVariantCollector
|
||||
{
|
||||
ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection();
|
||||
_steps = ESteps.CollectAllMaterial;
|
||||
return; //等待一帧
|
||||
return; // 等待一帧,让编辑器完成清理。
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CollectAllMaterial)
|
||||
{
|
||||
_allMaterials = GetAllMaterials();
|
||||
_steps = ESteps.CollectVariants;
|
||||
return; //等待一帧
|
||||
return; // 等待一帧,让材质列表收集结果稳定。
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CollectVariants)
|
||||
@@ -119,7 +145,7 @@ public static class ShaderVariantCollector
|
||||
|
||||
if (_steps == ESteps.WaitingDone)
|
||||
{
|
||||
// 注意:一定要延迟保存才会起效
|
||||
// Unity 需要等待若干帧后才能把当前变种集合写入资源文件。
|
||||
if (_elapsedTime.ElapsedMilliseconds > WaitMilliseconds)
|
||||
{
|
||||
_elapsedTime.Stop();
|
||||
@@ -129,9 +155,7 @@ public static class ShaderVariantCollector
|
||||
ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_savePath);
|
||||
CreateManifest();
|
||||
|
||||
UnityEngine.Debug.Log($"搜集SVC完毕!");
|
||||
EditorApplication.update -= EditorUpdate;
|
||||
_completedCallback?.Invoke();
|
||||
Finish(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +188,7 @@ public static class ShaderVariantCollector
|
||||
result.Add(assetPath);
|
||||
}
|
||||
}
|
||||
EditorDialogUtility.DisplayProgressBar("搜集所有材质球", ++progressValue, collectResult.CollectAssets.Count);
|
||||
EditorDialogUtility.DisplayProgressBar("Collect All Materials", ++progressValue, collectResult.CollectAssets.Count);
|
||||
}
|
||||
EditorDialogUtility.ClearProgressBar();
|
||||
|
||||
@@ -175,7 +199,7 @@ public static class ShaderVariantCollector
|
||||
{
|
||||
Camera camera = Camera.main;
|
||||
if (camera == null)
|
||||
throw new System.Exception("Not found main camera.");
|
||||
throw new System.InvalidOperationException("Main camera is missing.");
|
||||
|
||||
// 设置主相机
|
||||
float aspect = camera.aspect;
|
||||
@@ -208,13 +232,19 @@ public static class ShaderVariantCollector
|
||||
{
|
||||
x++;
|
||||
}
|
||||
EditorDialogUtility.DisplayProgressBar("照射所有材质球", ++progressValue, materials.Count);
|
||||
EditorDialogUtility.DisplayProgressBar("Render All Materials", ++progressValue, materials.Count);
|
||||
}
|
||||
EditorDialogUtility.ClearProgressBar();
|
||||
}
|
||||
private static GameObject CreateSphere(string assetPath, Vector3 position, int index)
|
||||
{
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
|
||||
if (material == null)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Material not found: '{assetPath}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var shader = material.shader;
|
||||
if (shader == null)
|
||||
return null;
|
||||
@@ -229,11 +259,12 @@ public static class ShaderVariantCollector
|
||||
{
|
||||
foreach (var go in _allSpheres)
|
||||
{
|
||||
if (go != null)
|
||||
GameObject.DestroyImmediate(go);
|
||||
}
|
||||
_allSpheres.Clear();
|
||||
|
||||
// 尝试释放编辑器加载的资源
|
||||
// 材质扫描会加载编辑器资源,收集结束后主动释放以降低内存占用。
|
||||
EditorUtility.UnloadUnusedAssetsImmediate(true);
|
||||
}
|
||||
private static void CreateManifest()
|
||||
@@ -251,4 +282,39 @@ public static class ShaderVariantCollector
|
||||
|
||||
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
private static void Finish(bool success, Exception exception = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (success)
|
||||
UnityEngine.Debug.Log("Shader variant collection completed.");
|
||||
else
|
||||
UnityEngine.Debug.LogError($"Shader variant collection failed: {exception}.");
|
||||
|
||||
_completedCallback?.Invoke();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
private static void Cleanup()
|
||||
{
|
||||
EditorApplication.update -= EditorUpdate;
|
||||
EditorDialogUtility.ClearProgressBar();
|
||||
|
||||
if (_elapsedTime != null)
|
||||
{
|
||||
_elapsedTime.Stop();
|
||||
_elapsedTime = null;
|
||||
}
|
||||
|
||||
DestroyAllSpheres();
|
||||
_savePath = null;
|
||||
_packageName = null;
|
||||
_processMaxNum = 0;
|
||||
_completedCallback = null;
|
||||
_allMaterials = null;
|
||||
_steps = ESteps.None;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,54 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
/// <summary>
|
||||
/// 保存着色器变种收集工具的编辑器偏好设置
|
||||
/// </summary>
|
||||
public class ShaderVariantCollectorSetting : ScriptableObject
|
||||
{
|
||||
private const string DefaultSavePath = "Assets/MyShaderVariants.shadervariants";
|
||||
|
||||
public static string GeFileSavePath(string packageName)
|
||||
/// <summary>
|
||||
/// 查询收集结果保存路径
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
/// <returns>收集结果保存路径</returns>
|
||||
public static string GetFileSavePath(string packageName)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_GeFileSavePath";
|
||||
string key = $"{Application.productName}_{packageName}_GetFileSavePath";
|
||||
return EditorPrefs.GetString(key, DefaultSavePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置收集结果保存路径
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
/// <param name="savePath">收集结果保存路径</param>
|
||||
public static void SetFileSavePath(string packageName, string savePath)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_GeFileSavePath";
|
||||
string key = $"{Application.productName}_{packageName}_GetFileSavePath";
|
||||
EditorPrefs.SetString(key, savePath);
|
||||
}
|
||||
|
||||
public static int GeProcessCapacity(string packageName)
|
||||
/// <summary>
|
||||
/// 查询单批处理容量
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
/// <returns>单批处理容量</returns>
|
||||
public static int GetProcessCapacity(string packageName)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_GeProcessCapacity";
|
||||
string key = $"{Application.productName}_{packageName}_GetProcessCapacity";
|
||||
return EditorPrefs.GetInt(key, 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置单批处理容量
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
/// <param name="capacity">单批处理容量</param>
|
||||
public static void SetProcessCapacity(string packageName, int capacity)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_GeProcessCapacity";
|
||||
string key = $"{Application.productName}_{packageName}_GetProcessCapacity";
|
||||
EditorPrefs.SetInt(key, capacity);
|
||||
}
|
||||
}
|
||||
@@ -1,140 +1,115 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using YooAsset.Editor;
|
||||
|
||||
/// <summary>
|
||||
/// 提供着色器变种收集工具窗口
|
||||
/// </summary>
|
||||
public class ShaderVariantCollectorWindow : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/着色器变种收集器", false, 100)]
|
||||
[MenuItem("Tools/Shader Variant Collector", false, 100)]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
ShaderVariantCollectorWindow window = GetWindow<ShaderVariantCollectorWindow>("着色器变种收集工具", true);
|
||||
ShaderVariantCollectorWindow window = GetWindow<ShaderVariantCollectorWindow>("Shader Variant Collector", true);
|
||||
window.minSize = new Vector2(800, 600);
|
||||
}
|
||||
|
||||
private Button _collectButton;
|
||||
private TextField _collectOutputField;
|
||||
private Label _currentShaderCountField;
|
||||
private Label _currentVariantCountField;
|
||||
private SliderInt _processCapacitySlider;
|
||||
private PopupField<string> _packageField;
|
||||
|
||||
private List<string> _packageNames;
|
||||
private int _packageIndex;
|
||||
private string _currentPackageName;
|
||||
private string _collectOutputPath;
|
||||
private int _processCapacity;
|
||||
|
||||
public void CreateGUI()
|
||||
private void OnEnable()
|
||||
{
|
||||
try
|
||||
{
|
||||
VisualElement root = this.rootVisualElement;
|
||||
|
||||
// 加载布局文件
|
||||
var visualAsset = UxmlLoader.LoadWindowUxml<ShaderVariantCollectorWindow>();
|
||||
if (visualAsset == null)
|
||||
return;
|
||||
|
||||
visualAsset.CloneTree(root);
|
||||
|
||||
// 包裹名称列表
|
||||
_packageNames = GetBuildPackageNames();
|
||||
_currentPackageName = _packageNames[0];
|
||||
|
||||
// 文件输出目录
|
||||
_collectOutputField = root.Q<TextField>("CollectOutput");
|
||||
_collectOutputField.SetValueWithoutNotify(ShaderVariantCollectorSetting.GeFileSavePath(_currentPackageName));
|
||||
_collectOutputField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
ShaderVariantCollectorSetting.SetFileSavePath(_currentPackageName, _collectOutputField.value);
|
||||
});
|
||||
|
||||
// 收集的包裹
|
||||
var packageContainer = root.Q("PackageContainer");
|
||||
if (_packageNames.Count > 0)
|
||||
{
|
||||
int defaultIndex = GetDefaultPackageIndex(_currentPackageName);
|
||||
_packageField = new PopupField<string>(_packageNames, defaultIndex);
|
||||
_packageField.label = "Package";
|
||||
_packageField.style.width = 350;
|
||||
_packageField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
_currentPackageName = _packageField.value;
|
||||
});
|
||||
packageContainer.Add(_packageField);
|
||||
_packageIndex = 0;
|
||||
_currentPackageName = _packageNames[_packageIndex];
|
||||
RefreshPackageSettings();
|
||||
}
|
||||
else
|
||||
}
|
||||
private void OnGUI()
|
||||
{
|
||||
_packageField = new PopupField<string>();
|
||||
_packageField.label = "Package";
|
||||
_packageField.style.width = 350;
|
||||
packageContainer.Add(_packageField);
|
||||
EditorGUILayout.Space(4);
|
||||
|
||||
bool hasPackages = _packageNames.Count > 0;
|
||||
|
||||
// Package
|
||||
EditorGUI.BeginDisabledGroup(!hasPackages);
|
||||
{
|
||||
int newIndex = EditorGUILayout.Popup("Package", _packageIndex, _packageNames.ToArray());
|
||||
if (newIndex != _packageIndex && hasPackages)
|
||||
{
|
||||
_packageIndex = newIndex;
|
||||
_currentPackageName = _packageNames[_packageIndex];
|
||||
RefreshPackageSettings();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// Save path
|
||||
string newPath = EditorGUILayout.TextField("Save Path", _collectOutputPath);
|
||||
if (newPath != _collectOutputPath)
|
||||
{
|
||||
_collectOutputPath = newPath;
|
||||
if (!string.IsNullOrEmpty(_currentPackageName))
|
||||
ShaderVariantCollectorSetting.SetFileSavePath(_currentPackageName, _collectOutputPath);
|
||||
}
|
||||
|
||||
// 容器值
|
||||
_processCapacitySlider = root.Q<SliderInt>("ProcessCapacity");
|
||||
_processCapacitySlider.SetValueWithoutNotify(ShaderVariantCollectorSetting.GeProcessCapacity(_currentPackageName));
|
||||
#if !UNITY_2020_3_OR_NEWER
|
||||
_processCapacitySlider.label = $"Capacity ({_processCapacitySlider.value})";
|
||||
_processCapacitySlider.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
ShaderVariantCollectorSetting.SetProcessCapacity(_currentPackageName, _processCapacitySlider.value);
|
||||
_processCapacitySlider.label = $"Capacity ({_processCapacitySlider.value})";
|
||||
});
|
||||
#else
|
||||
_processCapacitySlider.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
ShaderVariantCollectorSetting.SetProcessCapacity(_currentPackageName, _processCapacitySlider.value);
|
||||
});
|
||||
#endif
|
||||
// Shader / variant counts
|
||||
int shaderCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount();
|
||||
int variantCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionVariantCount();
|
||||
EditorGUILayout.LabelField("Current Shader Count", shaderCount.ToString());
|
||||
EditorGUILayout.LabelField("Current Variant Count", variantCount.ToString());
|
||||
|
||||
_currentShaderCountField = root.Q<Label>("CurrentShaderCount");
|
||||
_currentVariantCountField = root.Q<Label>("CurrentVariantCount");
|
||||
|
||||
// 变种收集按钮
|
||||
_collectButton = root.Q<Button>("CollectButton");
|
||||
_collectButton.clicked += CollectButton_clicked;
|
||||
}
|
||||
catch (Exception e)
|
||||
// Process capacity slider
|
||||
int newCapacity = EditorGUILayout.IntSlider("Capacity", _processCapacity, 10, 1000);
|
||||
if (newCapacity != _processCapacity)
|
||||
{
|
||||
Debug.LogError(e.ToString());
|
||||
}
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
if (_currentShaderCountField != null)
|
||||
{
|
||||
int currentShaderCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount();
|
||||
_currentShaderCountField.text = $"Current Shader Count : {currentShaderCount}";
|
||||
_processCapacity = newCapacity;
|
||||
if (!string.IsNullOrEmpty(_currentPackageName))
|
||||
ShaderVariantCollectorSetting.SetProcessCapacity(_currentPackageName, _processCapacity);
|
||||
}
|
||||
|
||||
if (_currentVariantCountField != null)
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
// Collect button
|
||||
EditorGUI.BeginDisabledGroup(!hasPackages);
|
||||
{
|
||||
int currentVariantCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionVariantCount();
|
||||
_currentVariantCountField.text = $"Current Variant Count : {currentVariantCount}";
|
||||
Color defaultColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(0.16f, 0.42f, 0.16f, 1f);
|
||||
if (GUILayout.Button("Collect", GUILayout.Height(50)))
|
||||
{
|
||||
CollectButtonClicked();
|
||||
}
|
||||
GUI.backgroundColor = defaultColor;
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUILayout.Space(4);
|
||||
}
|
||||
|
||||
private void CollectButton_clicked()
|
||||
private void CollectButtonClicked()
|
||||
{
|
||||
string savePath = ShaderVariantCollectorSetting.GeFileSavePath(_currentPackageName);
|
||||
int processCapacity = _processCapacitySlider.value;
|
||||
ShaderVariantCollector.Run(savePath, _currentPackageName, processCapacity, null);
|
||||
if (string.IsNullOrEmpty(_currentPackageName))
|
||||
{
|
||||
Debug.LogError("Package name is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建包裹相关
|
||||
private int GetDefaultPackageIndex(string packageName)
|
||||
{
|
||||
for (int index = 0; index < _packageNames.Count; index++)
|
||||
{
|
||||
if (_packageNames[index] == packageName)
|
||||
{
|
||||
return index;
|
||||
string savePath = ShaderVariantCollectorSetting.GetFileSavePath(_currentPackageName);
|
||||
ShaderVariantCollector.Run(savePath, _currentPackageName, _processCapacity, null);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
private void RefreshPackageSettings()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_currentPackageName))
|
||||
return;
|
||||
|
||||
_collectOutputPath = ShaderVariantCollectorSetting.GetFileSavePath(_currentPackageName);
|
||||
_processCapacity = ShaderVariantCollectorSetting.GetProcessCapacity(_currentPackageName);
|
||||
}
|
||||
private List<string> GetBuildPackageNames()
|
||||
{
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
|
||||
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;" />
|
||||
<ui:VisualElement name="CollectContainer">
|
||||
<ui:TextField picking-mode="Ignore" label="文件保存路径" name="CollectOutput" style="height: 22px;" />
|
||||
<ui:VisualElement name="PackageContainer" style="height: 24px;" />
|
||||
<ui:Label text="Current Shader Count" display-tooltip-when-elided="true" name="CurrentShaderCount" style="height: 20px; padding-left: 4px;" />
|
||||
<ui:Label text="Current Variant Count" display-tooltip-when-elided="true" name="CurrentVariantCount" style="height: 20px; padding-left: 4px;" />
|
||||
<ui:SliderInt picking-mode="Ignore" label="Capacity" value="9999" high-value="1000" name="ProcessCapacity" low-value="10" show-input-field="true" />
|
||||
<ui:Button text="开始搜集" display-tooltip-when-elided="true" name="CollectButton" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bff4878063eaf04dab8713e1e662ac5
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "YooAsset.Extension.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"YooAsset",
|
||||
"YooAsset.Editor",
|
||||
"YooAsset.Extension"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8e79e975991a7547b8ab3d52127065d
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fdc3ec5aeab28849a55f4ec8619e04c
|
||||
guid: 1a5b8e8a252caf44eabfaf319fb4b2dc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 演示如何使用 GameObjectReference 弱引用加载并实例化游戏对象
|
||||
/// </summary>
|
||||
public class AssetReferenceSample : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private GameObjectReference _reference;
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
if (_reference.RuntimeKeyIsValid() == false)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
AssetHandle handle = _reference.LoadAssetAsync();
|
||||
yield return handle;
|
||||
|
||||
if (handle.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
GameObject instance = handle.InstantiateSync(new InstantiateOptions(true, transform, false));
|
||||
if (instance == null)
|
||||
Debug.LogError($"Failed to instantiate GameObject reference '{_reference.AssetGUID}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Failed to load GameObject reference '{_reference.AssetGUID}': {handle.Error}.");
|
||||
}
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
_reference.ReleaseAsset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 游戏对象弱引用,序列化时只保存资源 GUID
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class GameObjectReference
|
||||
{
|
||||
[SerializeField]
|
||||
private string _packageName = "DefaultPackage";
|
||||
|
||||
[SerializeField]
|
||||
private string _assetGUID = "";
|
||||
|
||||
[NonSerialized]
|
||||
private AssetHandle _handle;
|
||||
|
||||
/// <summary>
|
||||
/// 资源所属的包裹名称
|
||||
/// </summary>
|
||||
public string PackageName => _packageName;
|
||||
|
||||
/// <summary>
|
||||
/// 资源 GUID
|
||||
/// </summary>
|
||||
public string AssetGUID => _assetGUID;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查运行时引用键是否有效
|
||||
/// </summary>
|
||||
public bool RuntimeKeyIsValid()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_packageName) || string.IsNullOrEmpty(_assetGUID))
|
||||
return false;
|
||||
|
||||
var package = YooAssets.GetPackage(_packageName);
|
||||
var assetInfo = package.GetAssetInfoByGuid(_assetGUID, typeof(GameObject));
|
||||
return assetInfo.IsValid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载引用的游戏对象
|
||||
/// </summary>
|
||||
/// <returns>加载操作句柄</returns>
|
||||
public AssetHandle LoadAssetAsync()
|
||||
{
|
||||
if (_handle != null)
|
||||
throw new InvalidOperationException("GameObject reference has already been loaded. Release it first.");
|
||||
|
||||
if (string.IsNullOrEmpty(_packageName))
|
||||
throw new ArgumentException("Package name is not set.", nameof(_packageName));
|
||||
if (string.IsNullOrEmpty(_assetGUID))
|
||||
throw new ArgumentException("Asset GUID is not set.", nameof(_assetGUID));
|
||||
|
||||
var package = YooAssets.GetPackage(_packageName);
|
||||
var assetInfo = package.GetAssetInfoByGuid(_assetGUID, typeof(GameObject));
|
||||
_handle = package.LoadAssetAsync(assetInfo);
|
||||
return _handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放已加载的资源句柄
|
||||
/// </summary>
|
||||
public void ReleaseAsset()
|
||||
{
|
||||
if (_handle == null)
|
||||
return;
|
||||
|
||||
_handle.Release();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15552077c0d6ff441a4cd62af62b7d5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,502 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
#region InitializeParameters
|
||||
/// <summary>
|
||||
/// 初始化参数
|
||||
/// </summary>
|
||||
public abstract class InitializeParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// 同时加载Bundle文件的最大并发数
|
||||
/// </summary>
|
||||
public int BundleLoadingMaxConcurrency = int.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// 当资源引用计数为零的时候自动释放资源包
|
||||
/// </summary>
|
||||
public bool AutoUnloadBundleWhenUnused = false;
|
||||
|
||||
/// <summary>
|
||||
/// WebGL平台强制同步加载资源对象
|
||||
/// </summary>
|
||||
public bool WebGLForceSyncLoadAsset = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行模式的初始化参数
|
||||
/// </summary>
|
||||
public class EditorSimulateModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters EditorFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离线运行模式的初始化参数
|
||||
/// </summary>
|
||||
public class OfflinePlayModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters BuiltinFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 联机运行模式的初始化参数
|
||||
/// </summary>
|
||||
public class HostPlayModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters BuiltinFileSystemParameters;
|
||||
public FileSystemParameters CacheFileSystemParameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WebGL运行模式的初始化参数
|
||||
/// </summary>
|
||||
public class WebPlayModeParameters : InitializeParameters
|
||||
{
|
||||
public FileSystemParameters WebServerFileSystemParameters;
|
||||
public FileSystemParameters WebRemoteFileSystemParameters;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InitializationOperation
|
||||
public class InitializationOperation : AsyncOperationBase
|
||||
{
|
||||
private bool _isDone = false;
|
||||
private readonly InitializePackageOperation _operation;
|
||||
|
||||
internal InitializationOperation(InitializePackageOperation op)
|
||||
{
|
||||
_operation = op;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_isDone)
|
||||
return;
|
||||
|
||||
_operation.UpdateOperation();
|
||||
if (_operation.IsDone == false)
|
||||
return;
|
||||
|
||||
_isDone = true;
|
||||
if (_operation.Status == EOperationStatus.Succeeded)
|
||||
SetResult();
|
||||
else
|
||||
SetError(_operation.Error);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DestroyOperation
|
||||
public class DestroyOperation : AsyncOperationBase
|
||||
{
|
||||
private bool _isDone = false;
|
||||
private readonly DestroyPackageOperation _operation;
|
||||
|
||||
internal DestroyOperation(DestroyPackageOperation op)
|
||||
{
|
||||
_operation = op;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_isDone)
|
||||
return;
|
||||
|
||||
_operation.UpdateOperation();
|
||||
if (_operation.IsDone == false)
|
||||
return;
|
||||
|
||||
_isDone = true;
|
||||
if (_operation.Status == EOperationStatus.Succeeded)
|
||||
SetResult();
|
||||
else
|
||||
SetError(_operation.Error);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdatePackageManifestOperation
|
||||
public class UpdatePackageManifestOperation : AsyncOperationBase
|
||||
{
|
||||
private bool _isDone = false;
|
||||
private readonly LoadPackageManifestOperation _operation;
|
||||
|
||||
internal UpdatePackageManifestOperation(LoadPackageManifestOperation op)
|
||||
{
|
||||
_operation = op;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_isDone)
|
||||
return;
|
||||
|
||||
_operation.UpdateOperation();
|
||||
if (_operation.IsDone == false)
|
||||
return;
|
||||
|
||||
_isDone = true;
|
||||
if (_operation.Status == EOperationStatus.Succeeded)
|
||||
SetResult();
|
||||
else
|
||||
SetError(_operation.Error);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ImportFileInfo
|
||||
public struct ImportFileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地文件路径
|
||||
/// </summary>
|
||||
public string FilePath;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包名称
|
||||
/// </summary>
|
||||
public string BundleName;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包GUID
|
||||
/// </summary>
|
||||
public string BundleGuid;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static class CompatibleResourcePackage
|
||||
{
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static InitializationOperation InitializeAsync(this ResourcePackage package, InitializeParameters parameters)
|
||||
{
|
||||
if (parameters is EditorSimulateModeParameters)
|
||||
{
|
||||
var initializeParameters = parameters as EditorSimulateModeParameters;
|
||||
var options = new EditorSimulateModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset;
|
||||
options.EditorFileSystemParameters = initializeParameters.EditorFileSystemParameters;
|
||||
var operation = package.InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(package.PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is OfflinePlayModeParameters)
|
||||
{
|
||||
var initializeParameters = parameters as OfflinePlayModeParameters;
|
||||
var options = new OfflinePlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset;
|
||||
options.BuiltinFileSystemParameters = initializeParameters.BuiltinFileSystemParameters;
|
||||
var operation = package.InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(package.PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is HostPlayModeParameters)
|
||||
{
|
||||
var initializeParameters = parameters as HostPlayModeParameters;
|
||||
var options = new HostPlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset;
|
||||
options.BuiltinFileSystemParameters = initializeParameters.BuiltinFileSystemParameters;
|
||||
options.CacheFileSystemParameters = initializeParameters.CacheFileSystemParameters;
|
||||
var operation = package.InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(package.PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else if (parameters is WebPlayModeParameters)
|
||||
{
|
||||
var initializeParameters = parameters as WebPlayModeParameters;
|
||||
var options = new WebPlayModeOptions();
|
||||
options.BundleLoadingMaxConcurrency = initializeParameters.BundleLoadingMaxConcurrency;
|
||||
options.AutoUnloadBundleWhenUnused = initializeParameters.AutoUnloadBundleWhenUnused;
|
||||
options.WebGLForceSyncLoadAsset = initializeParameters.WebGLForceSyncLoadAsset;
|
||||
options.WebServerFileSystemParameters = initializeParameters.WebServerFileSystemParameters;
|
||||
options.WebRemoteFileSystemParameters = initializeParameters.WebRemoteFileSystemParameters;
|
||||
var operation = package.InitializePackageAsync(options);
|
||||
var wrapper = new InitializationOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(package.PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static DestroyOperation DestroyAsync(this ResourcePackage package)
|
||||
{
|
||||
var operation = package.DestroyPackageAsync();
|
||||
var wrapper = new DestroyOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(package.PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static RequestPackageVersionOperation RequestPackageVersionAsync(this ResourcePackage package, bool appendTimeTicks = true, int timeout = 60)
|
||||
{
|
||||
var options = new RequestPackageVersionOptions(appendTimeTicks, timeout);
|
||||
return package.RequestPackageVersionAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static UpdatePackageManifestOperation UpdatePackageManifestAsync(this ResourcePackage package, string packageVersion, int timeout = 60)
|
||||
{
|
||||
var options = new LoadPackageManifestOptions(packageVersion, timeout);
|
||||
var operation = package.LoadPackageManifestAsync(options);
|
||||
var wrapper = new UpdatePackageManifestOperation(operation);
|
||||
AsyncOperationSystem.StartOperation(package.PackageName, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static PrefetchManifestOperation PreDownloadContentAsync(this ResourcePackage package, string packageVersion, int timeout = 60)
|
||||
{
|
||||
var options = new PrefetchManifestOptions(packageVersion, timeout);
|
||||
return package.PrefetchManifestAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ClearCacheOperation ClearCacheFilesAsync(this ResourcePackage package, string fileClearMode, object clearParam = null)
|
||||
{
|
||||
var options = new ClearCacheOptions(fileClearMode, clearParam);
|
||||
return package.ClearCacheAsync(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(this ResourcePackage package, int loopCount)
|
||||
{
|
||||
var options = new UnloadUnusedAssetsOptions(loopCount);
|
||||
return package.UnloadUnusedAssetsAsync(options);
|
||||
}
|
||||
|
||||
#region 资源下载
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateResourceDownloader(this ResourcePackage package, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceDownloaderOptions(downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateResourceDownloader(this ResourcePackage package, string tag, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
string[] tags = new string[] { tag };
|
||||
var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateResourceDownloader(this ResourcePackage package, string[] tags, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceDownloaderOptions(tags, downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string location, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var assetInfo = package.ConvertLocationToAssetInfo(location, null);
|
||||
var options = new BundleDownloaderOptions(assetInfo, recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string location, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return package.CreateBundleDownloader(location, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string[] locations, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
List<AssetInfo> assetInfos = new List<AssetInfo>(locations.Length);
|
||||
foreach (var location in locations)
|
||||
{
|
||||
var assetInfo = package.ConvertLocationToAssetInfo(location, null);
|
||||
assetInfos.Add(assetInfo);
|
||||
}
|
||||
|
||||
var options = new BundleDownloaderOptions(assetInfos.ToArray(), recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, string[] locations, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return package.CreateBundleDownloader(locations, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo assetInfo, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
AssetInfo[] assetInfos = new AssetInfo[] { assetInfo };
|
||||
var options = new BundleDownloaderOptions(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo assetInfo, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return package.CreateBundleDownloader(assetInfo, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo[] assetInfos, bool recursiveDownload, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new BundleDownloaderOptions(assetInfos, recursiveDownload, downloadingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceDownloader(options);
|
||||
}
|
||||
public static ResourceDownloaderOperation CreateBundleDownloader(this ResourcePackage package, AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
return package.CreateBundleDownloader(assetInfos, false, downloadingMaxNumber, failedTryAgain);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源解压
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceUnpackerOperation CreateResourceUnpacker(this ResourcePackage package, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceUnpackerOptions(unpackingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceUnpacker(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceUnpackerOperation CreateResourceUnpacker(this ResourcePackage package, string tag, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
string[] tags = new string[] { tag };
|
||||
var options = new ResourceUnpackerOptions(tags, unpackingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceUnpacker(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceUnpackerOperation CreateResourceUnpacker(this ResourcePackage package, string[] tags, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
var options = new ResourceUnpackerOptions(tags, unpackingMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceUnpacker(options);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 资源导入
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceImporterOperation CreateResourceImporter(this ResourcePackage package, string[] filePaths, int importerMaxNumber, int failedTryAgain)
|
||||
{
|
||||
ImportFileInfo[] fileInfos = new ImportFileInfo[filePaths.Length];
|
||||
for (int i = 0; i < filePaths.Length; i++)
|
||||
{
|
||||
ImportFileInfo fileInfo = new ImportFileInfo();
|
||||
fileInfo.FilePath = filePaths[i];
|
||||
fileInfos[i] = fileInfo;
|
||||
}
|
||||
|
||||
return package.CreateResourceImporter(fileInfos, importerMaxNumber, failedTryAgain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容Yoo2版本
|
||||
/// </summary>
|
||||
public static ResourceImporterOperation CreateResourceImporter(this ResourcePackage package, ImportFileInfo[] fileInfos, int importerMaxNumber, int failedTryAgain)
|
||||
{
|
||||
ImportBundleInfo[] bundleInfos = new ImportBundleInfo[fileInfos.Length];
|
||||
for (int i = 0; i < fileInfos.Length; i++)
|
||||
{
|
||||
bundleInfos[i] = new ImportBundleInfo(
|
||||
filePath: fileInfos[i].FilePath,
|
||||
bundleName: fileInfos[i].BundleName,
|
||||
bundleGuid: fileInfos[i].BundleGuid);
|
||||
}
|
||||
|
||||
var options = new BundleImporterOptions(bundleInfos, importerMaxNumber, failedTryAgain);
|
||||
return package.CreateResourceImporter(options);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public static class CompatibleAssetHandle
|
||||
{
|
||||
public static GameObject InstantiateSync(this AssetHandle handle, Transform parent)
|
||||
{
|
||||
var options = new InstantiateOptions(true, parent, false);
|
||||
return handle.InstantiateSync(options);
|
||||
}
|
||||
public static GameObject InstantiateSync(this AssetHandle handle, Transform parent, bool worldPositionStays)
|
||||
{
|
||||
var options = new InstantiateOptions(true, parent, worldPositionStays);
|
||||
return handle.InstantiateSync(options);
|
||||
}
|
||||
public static GameObject InstantiateSync(this AssetHandle handle, Vector3 position, Quaternion rotation)
|
||||
{
|
||||
var options = new InstantiateOptions(true, position, rotation);
|
||||
return handle.InstantiateSync(options);
|
||||
}
|
||||
public static GameObject InstantiateSync(this AssetHandle handle, Vector3 position, Quaternion rotation, Transform parent)
|
||||
{
|
||||
var options = new InstantiateOptions(true, parent, position, rotation);
|
||||
return handle.InstantiateSync(options);
|
||||
}
|
||||
|
||||
public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Transform parent, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, parent, false);
|
||||
return handle.InstantiateAsync(options);
|
||||
}
|
||||
public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Transform parent, bool worldPositionStays, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, parent, worldPositionStays);
|
||||
return handle.InstantiateAsync(options);
|
||||
}
|
||||
public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Vector3 position, Quaternion rotation, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, position, rotation);
|
||||
return handle.InstantiateAsync(options);
|
||||
}
|
||||
public static InstantiateOperation InstantiateAsync(this AssetHandle handle, Vector3 position, Quaternion rotation, Transform parent, bool actived = true)
|
||||
{
|
||||
var options = new InstantiateOptions(actived, parent, position, rotation);
|
||||
return handle.InstantiateAsync(options);
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,16 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 提供资源句柄的扩展方法
|
||||
/// </summary>
|
||||
public static class AssetHandleExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 等待异步执行完毕
|
||||
/// 等待资源加载操作完成
|
||||
/// </summary>
|
||||
/// <param name="thisHandle">等待完成的资源句柄</param>
|
||||
/// <returns>已完成等待的资源句柄</returns>
|
||||
public static AssetHandle WaitForAsyncOperationComplete(this AssetHandle thisHandle)
|
||||
{
|
||||
thisHandle.WaitForAsyncComplete();
|
||||
|
||||
@@ -3,8 +3,16 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 提供资源句柄基类的扩展方法
|
||||
/// </summary>
|
||||
public static class HandleBaseExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查句柄是否已成功完成
|
||||
/// </summary>
|
||||
/// <param name="thisHandle">待检查的句柄</param>
|
||||
/// <returns>句柄已完成且状态为成功时返回 true。</returns>
|
||||
public static bool IsSucceed(this HandleBase thisHandle)
|
||||
{
|
||||
return thisHandle.IsDone && thisHandle.Status == EOperationStatus.Succeeded;
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝内置清单文件到沙盒目录
|
||||
/// </summary>
|
||||
public class CopyBuildinManifestOperation : AsyncOperationBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckHashFile,
|
||||
UnpackHashFile,
|
||||
CheckManifestFile,
|
||||
UnpackManifestFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly string _packageName;
|
||||
private readonly string _packageVersion;
|
||||
private readonly IDownloadBackend _backend;
|
||||
private IDownloadFileRequest _hashFileRequest;
|
||||
private IDownloadFileRequest _manifestFileRequest;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
public CopyBuildinManifestOperation(string packageName, string packageVersion)
|
||||
{
|
||||
_packageName = packageName;
|
||||
_packageVersion = packageVersion;
|
||||
_backend = new UnityWebRequestBackend();
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CheckHashFile;
|
||||
}
|
||||
protected override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.CheckHashFile)
|
||||
{
|
||||
string hashFilePath = GetCacheHashFilePath();
|
||||
if (File.Exists(hashFilePath))
|
||||
{
|
||||
_steps = ESteps.CheckManifestFile;
|
||||
return;
|
||||
}
|
||||
|
||||
_steps = ESteps.UnpackHashFile;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.UnpackHashFile)
|
||||
{
|
||||
if(_hashFileRequest == null)
|
||||
{
|
||||
string sourcePath = GetBuildinHashFilePath();
|
||||
string destPath = GetCacheHashFilePath();
|
||||
string url = DownloadUrlHelper.ToLocalFileUrl(sourcePath);
|
||||
var args = new DownloadFileRequestArgs(url, 60, 0, destPath);
|
||||
_hashFileRequest = _backend.CreateFileRequest(args);
|
||||
_hashFileRequest.SendRequest();
|
||||
}
|
||||
|
||||
if (_hashFileRequest.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_hashFileRequest.Status == EDownloadRequestStatus.Succeeded)
|
||||
{
|
||||
_steps = ESteps.CheckManifestFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_hashFileRequest.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CheckManifestFile)
|
||||
{
|
||||
string manifestFilePath = GetCacheManifestFilePath();
|
||||
if (File.Exists(manifestFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
return;
|
||||
}
|
||||
|
||||
_steps = ESteps.UnpackManifestFile;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.UnpackManifestFile)
|
||||
{
|
||||
if (_manifestFileRequest == null)
|
||||
{
|
||||
string sourcePath = GetBuildinManifestFilePath();
|
||||
string destPath = GetCacheManifestFilePath();
|
||||
string url = DownloadUrlHelper.ToLocalFileUrl(sourcePath);
|
||||
var args = new DownloadFileRequestArgs(url, 60, 0, destPath);
|
||||
_manifestFileRequest = _backend.CreateFileRequest(args);
|
||||
_manifestFileRequest.SendRequest();
|
||||
}
|
||||
|
||||
if (_manifestFileRequest.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_manifestFileRequest.Status == EDownloadRequestStatus.Succeeded)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
SetError(_manifestFileRequest.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetBuildinYooRoot()
|
||||
{
|
||||
return YooAssetConfiguration.GetDefaultBuiltinRoot();
|
||||
}
|
||||
private string GetBuildinHashFilePath()
|
||||
{
|
||||
string fileRoot = GetBuildinYooRoot();
|
||||
string fileName = YooAssetConfiguration.GetPackageHashFileName(_packageName, _packageVersion);
|
||||
return PathUtility.Combine(fileRoot, _packageName, fileName);
|
||||
}
|
||||
private string GetBuildinManifestFilePath()
|
||||
{
|
||||
string fileRoot = GetBuildinYooRoot();
|
||||
string fileName = YooAssetConfiguration.GetManifestBinaryFileName(_packageName, _packageVersion);
|
||||
return PathUtility.Combine(fileRoot, _packageName, fileName);
|
||||
}
|
||||
|
||||
private string GetCacheYooRoot()
|
||||
{
|
||||
return YooAssetConfiguration.GetDefaultCacheRoot();
|
||||
}
|
||||
private string GetCacheHashFilePath()
|
||||
{
|
||||
string fileRoot = GetCacheYooRoot();
|
||||
string fileName = YooAssetConfiguration.GetPackageHashFileName(_packageName, _packageVersion);
|
||||
return PathUtility.Combine(fileRoot, _packageName, fileName);
|
||||
}
|
||||
private string GetCacheManifestFilePath()
|
||||
{
|
||||
string fileRoot = GetCacheYooRoot();
|
||||
string fileName = YooAssetConfiguration.GetManifestBinaryFileName(_packageName, _packageVersion);
|
||||
return PathUtility.Combine(fileRoot, _packageName, fileName);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ public class GetBuildinPackageVersionOperation : AsyncOperationBase
|
||||
}
|
||||
|
||||
private readonly string _packageName;
|
||||
private readonly IDownloadBackend _backend;
|
||||
private IDownloadTextRequest _downloadTextRequest;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
@@ -26,10 +25,16 @@ public class GetBuildinPackageVersionOperation : AsyncOperationBase
|
||||
/// </summary>
|
||||
public string PackageVersion { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建内置资源清单版本查询操作实例
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
public GetBuildinPackageVersionOperation(string packageName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(packageName))
|
||||
throw new System.ArgumentNullException(nameof(packageName));
|
||||
|
||||
_packageName = packageName;
|
||||
_backend = new UnityWebRequestBackend();
|
||||
}
|
||||
protected override void InternalStart()
|
||||
{
|
||||
@@ -47,7 +52,7 @@ public class GetBuildinPackageVersionOperation : AsyncOperationBase
|
||||
string filePath = GetBuildinPackageVersionFilePath();
|
||||
string url = DownloadUrlHelper.ToLocalFileUrl(filePath);
|
||||
var args = new DownloadDataRequestArgs(url, 60, 0);
|
||||
_downloadTextRequest = _backend.CreateTextRequest(args);
|
||||
_downloadTextRequest = new UnityWebRequestText(args, null);
|
||||
_downloadTextRequest.SendRequest();
|
||||
}
|
||||
|
||||
@@ -67,6 +72,14 @@ public class GetBuildinPackageVersionOperation : AsyncOperationBase
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void InternalDispose()
|
||||
{
|
||||
if (_downloadTextRequest != null)
|
||||
{
|
||||
_downloadTextRequest.Dispose();
|
||||
_downloadTextRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetBuildinYooRoot()
|
||||
{
|
||||
|
||||
@@ -20,13 +20,20 @@ public class GetCacheBundleSizeOperation : AsyncOperationBase
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 总大小(单位:字节)
|
||||
/// 缓存文件总大小,单位为字节
|
||||
/// </summary>
|
||||
public long TotalSize = 0;
|
||||
public long TotalSize { private set; get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建缓存文件大小统计操作实例
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
public GetCacheBundleSizeOperation(string packageName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(packageName))
|
||||
throw new System.ArgumentNullException(nameof(packageName));
|
||||
|
||||
_packageName = packageName;
|
||||
}
|
||||
protected override void InternalStart()
|
||||
|
||||
@@ -4,6 +4,10 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 按资源标签加载一组资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">资源对象的 Unity 类型</typeparam>
|
||||
public class LoadAssetsByTagOperation<TObject> : AsyncOperationBase where TObject : UnityEngine.Object
|
||||
{
|
||||
private enum ESteps
|
||||
@@ -18,15 +22,26 @@ public class LoadAssetsByTagOperation<TObject> : AsyncOperationBase where TObjec
|
||||
private readonly string _tag;
|
||||
private ESteps _steps = ESteps.None;
|
||||
private List<AssetHandle> _handles;
|
||||
private List<TObject> _assetObjects;
|
||||
|
||||
/// <summary>
|
||||
/// 资源对象集合
|
||||
/// 加载成功的资源对象集合
|
||||
/// </summary>
|
||||
public List<TObject> AssetObjects { private set; get; }
|
||||
public IReadOnlyList<TObject> AssetObjects { get { return _assetObjects; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建按标签加载资源对象的操作实例
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
/// <param name="tag">资源标签</param>
|
||||
public LoadAssetsByTagOperation(string packageName, string tag)
|
||||
{
|
||||
if (string.IsNullOrEmpty(packageName))
|
||||
throw new System.ArgumentNullException(nameof(packageName));
|
||||
if (string.IsNullOrEmpty(tag))
|
||||
throw new System.ArgumentNullException(nameof(tag));
|
||||
|
||||
_packageName = packageName;
|
||||
_tag = tag;
|
||||
}
|
||||
@@ -65,7 +80,7 @@ public class LoadAssetsByTagOperation<TObject> : AsyncOperationBase where TObjec
|
||||
index++;
|
||||
}
|
||||
|
||||
AssetObjects = new List<TObject>(_handles.Count);
|
||||
_assetObjects = new List<TObject>(_handles.Count);
|
||||
foreach (var handle in _handles)
|
||||
{
|
||||
if (handle.Status == EOperationStatus.Succeeded)
|
||||
@@ -73,21 +88,21 @@ public class LoadAssetsByTagOperation<TObject> : AsyncOperationBase where TObjec
|
||||
var assetObject = handle.AssetObject as TObject;
|
||||
if (assetObject != null)
|
||||
{
|
||||
AssetObjects.Add(assetObject);
|
||||
_assetObjects.Add(assetObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
string error = $"资源类型转换失败:{handle.AssetObject.name}";
|
||||
Debug.LogError($"{error}");
|
||||
AssetObjects.Clear();
|
||||
string error = $"Asset type cast failed: {handle.AssetObject.name}";
|
||||
Debug.LogError(error);
|
||||
_assetObjects.Clear();
|
||||
SetFailed(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"{handle.Error}");
|
||||
AssetObjects.Clear();
|
||||
Debug.LogError(handle.Error);
|
||||
_assetObjects.Clear();
|
||||
SetFailed(handle.Error);
|
||||
return;
|
||||
}
|
||||
@@ -108,10 +123,13 @@ public class LoadAssetsByTagOperation<TObject> : AsyncOperationBase where TObjec
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源句柄
|
||||
/// 释放加载过程中创建的资源句柄
|
||||
/// </summary>
|
||||
public void ReleaseHandle()
|
||||
{
|
||||
if (_handles == null)
|
||||
return;
|
||||
|
||||
foreach (var handle in _handles)
|
||||
{
|
||||
handle.Release();
|
||||
|
||||
@@ -4,8 +4,21 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 提供资源包裹的游戏对象加载扩展方法
|
||||
/// </summary>
|
||||
public static class YooAssetsExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载并实例化游戏对象
|
||||
/// </summary>
|
||||
/// <param name="package">发起加载的资源包裹</param>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="position">实例化位置</param>
|
||||
/// <param name="rotation">实例化旋转</param>
|
||||
/// <param name="parent">实例化父节点</param>
|
||||
/// <param name="destroyGoOnRelease">释放句柄时是否销毁实例对象</param>
|
||||
/// <returns>游戏对象加载操作句柄</returns>
|
||||
public static LoadGameObjectOperation LoadGameObjectAsync(this ResourcePackage package, string location, Vector3 position, Quaternion rotation, Transform parent, bool destroyGoOnRelease = false)
|
||||
{
|
||||
var operation = new LoadGameObjectOperation(package.PackageName, location, position, rotation, parent, destroyGoOnRelease);
|
||||
@@ -14,6 +27,9 @@ public static class YooAssetsExtension
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载并实例化游戏对象的操作
|
||||
/// </summary>
|
||||
public class LoadGameObjectOperation : AsyncOperationBase
|
||||
{
|
||||
private enum ESteps
|
||||
@@ -25,7 +41,7 @@ public class LoadGameObjectOperation : AsyncOperationBase
|
||||
|
||||
private readonly string _packageName;
|
||||
private readonly string _location;
|
||||
private readonly Vector3 _positon;
|
||||
private readonly Vector3 _position;
|
||||
private readonly Quaternion _rotation;
|
||||
private readonly Transform _parent;
|
||||
private readonly bool _destroyGoOnRelease;
|
||||
@@ -33,16 +49,29 @@ public class LoadGameObjectOperation : AsyncOperationBase
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 加载的游戏对象
|
||||
/// 加载并实例化后的游戏对象
|
||||
/// </summary>
|
||||
public GameObject Go { private set; get; }
|
||||
|
||||
public GameObject GameObjectInstance { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建游戏对象加载操作实例
|
||||
/// </summary>
|
||||
/// <param name="packageName">资源包裹名称</param>
|
||||
/// <param name="location">资源定位地址</param>
|
||||
/// <param name="position">实例化位置</param>
|
||||
/// <param name="rotation">实例化旋转</param>
|
||||
/// <param name="parent">实例化父节点</param>
|
||||
/// <param name="destroyGoOnRelease">释放句柄时是否销毁实例对象</param>
|
||||
public LoadGameObjectOperation(string packageName, string location, Vector3 position, Quaternion rotation, Transform parent, bool destroyGoOnRelease = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(packageName))
|
||||
throw new System.ArgumentNullException(nameof(packageName));
|
||||
if (string.IsNullOrEmpty(location))
|
||||
throw new System.ArgumentNullException(nameof(location));
|
||||
|
||||
_packageName = packageName;
|
||||
_location = location;
|
||||
_positon = position;
|
||||
_position = position;
|
||||
_rotation = rotation;
|
||||
_parent = parent;
|
||||
_destroyGoOnRelease = destroyGoOnRelease;
|
||||
@@ -70,12 +99,12 @@ public class LoadGameObjectOperation : AsyncOperationBase
|
||||
|
||||
if (_handle.Status != EOperationStatus.Succeeded)
|
||||
{
|
||||
SetError(_handle.Error);
|
||||
SetError($"Failed to load GameObject '{_location}': {_handle.Error}.");
|
||||
_steps = ESteps.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
Go = _handle.InstantiateSync(_positon, _rotation, _parent);
|
||||
GameObjectInstance = _handle.InstantiateSync(new InstantiateOptions(true, _parent, _position, _rotation));
|
||||
SetResult();
|
||||
_steps = ESteps.Done;
|
||||
}
|
||||
@@ -83,7 +112,7 @@ public class LoadGameObjectOperation : AsyncOperationBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源句柄
|
||||
/// 释放加载过程中创建的资源句柄
|
||||
/// </summary>
|
||||
public void ReleaseHandle()
|
||||
{
|
||||
@@ -93,8 +122,8 @@ public class LoadGameObjectOperation : AsyncOperationBase
|
||||
|
||||
if (_destroyGoOnRelease)
|
||||
{
|
||||
if (Go != null)
|
||||
GameObject.Destroy(Go);
|
||||
if (GameObjectInstance != null)
|
||||
GameObject.Destroy(GameObjectInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using YooAsset;
|
||||
|
||||
public class OperationHelper
|
||||
/// <summary>
|
||||
/// 提供业务自定义操作的启动入口
|
||||
/// </summary>
|
||||
public static class OperationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始一个业务实现的自定义异步任务
|
||||
/// 启动业务自定义操作
|
||||
/// </summary>
|
||||
public static void StartOperation(AsyncOperationBase operation)
|
||||
/// <param name="packageName">调度器或资源包裹名称</param>
|
||||
/// <param name="operation">待启动的操作实例</param>
|
||||
public static void StartOperation(string packageName, AsyncOperationBase operation)
|
||||
{
|
||||
AsyncOperationSystem.StartOperation(AsyncOperationSystem.GlobalSchedulerName, operation);
|
||||
AsyncOperationSystem.StartOperation(packageName, operation);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.CustomEditor(typeof(GameObjectAssetReference), true)]
|
||||
public class GameObjectAssetReferenceInspector : UnityEditor.Editor
|
||||
{
|
||||
private bool _init = false;
|
||||
private GameObject _cacheObject;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
GameObjectAssetReference mono = (GameObjectAssetReference)target;
|
||||
|
||||
if (_init == false)
|
||||
{
|
||||
_init = true;
|
||||
if (string.IsNullOrEmpty(mono.AssetGUID) == false)
|
||||
{
|
||||
string assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(mono.AssetGUID);
|
||||
if (string.IsNullOrEmpty(assetPath) == false)
|
||||
{
|
||||
_cacheObject = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameObject go = (GameObject)UnityEditor.EditorGUILayout.ObjectField(_cacheObject, typeof(GameObject), false);
|
||||
if (go != _cacheObject)
|
||||
{
|
||||
_cacheObject = go;
|
||||
string assetPath = UnityEditor.AssetDatabase.GetAssetPath(go);
|
||||
mono.AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
|
||||
UnityEditor.EditorUtility.SetDirty(target);
|
||||
}
|
||||
|
||||
UnityEditor.EditorGUILayout.LabelField("Asset GUID", mono.AssetGUID);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public class GameObjectAssetReference : MonoBehaviour
|
||||
{
|
||||
[HideInInspector]
|
||||
public string AssetGUID = "";
|
||||
|
||||
private AssetHandle _handle;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
var package = YooAssets.GetPackage("DefaultPackage");
|
||||
var assetInfo = package.GetAssetInfoByGuid(AssetGUID);
|
||||
_handle = package.LoadAssetAsync(assetInfo);
|
||||
_handle.Completed += Handle_Completed;
|
||||
}
|
||||
public void OnDestroy()
|
||||
{
|
||||
if (_handle != null)
|
||||
{
|
||||
_handle.Release();
|
||||
_handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Handle_Completed(AssetHandle handle)
|
||||
{
|
||||
if (handle.Status == EOperationStatus.Succeeded)
|
||||
{
|
||||
handle.InstantiateSync(this.transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,13 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 演示操作生命周期监控的接入位置
|
||||
/// </summary>
|
||||
public static class OperationMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册操作生命周期回调
|
||||
/// </summary>
|
||||
public static void RegisterOperationCallback()
|
||||
{
|
||||
}
|
||||
|
||||
private static void OperationStartCallback(string packageName, AsyncOperationBase operation)
|
||||
{
|
||||
Debug.Log($"Operation start : {operation.GetType().Name}");
|
||||
}
|
||||
private static void OperationFinishCallback(string packageName, AsyncOperationBase operation)
|
||||
{
|
||||
Debug.Log($"Operation finish : {operation.GetType().Name}");
|
||||
// TODO: 当前版本不支持全局操作回调注册,请根据业务需求自行实现监控逻辑。
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,36 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.U2D;
|
||||
using YooAsset;
|
||||
|
||||
/// <summary>
|
||||
/// 响应 Unity 图集请求并通过资源包裹加载 SpriteAtlas
|
||||
/// </summary>
|
||||
public class SpriteAtlasLoader : MonoBehaviour
|
||||
{
|
||||
private Dictionary<string, SpriteAtlas> _loadedAtlas = new Dictionary<string, SpriteAtlas>(1000);
|
||||
private List<AssetHandle> _loadHandles = new List<AssetHandle>(1000);
|
||||
|
||||
/// <summary>
|
||||
/// 注册图集请求回调
|
||||
/// </summary>
|
||||
public void Awake()
|
||||
{
|
||||
SpriteAtlasManager.atlasRequested += RequestAtlas;
|
||||
}
|
||||
/// <summary>
|
||||
/// 注销图集请求回调并释放已加载图集句柄
|
||||
/// </summary>
|
||||
public void OnDestroy()
|
||||
{
|
||||
SpriteAtlasManager.atlasRequested -= RequestAtlas;
|
||||
|
||||
foreach (var handle in _loadHandles)
|
||||
{
|
||||
handle.Release();
|
||||
}
|
||||
_loadHandles.Clear();
|
||||
}
|
||||
|
||||
private void RequestAtlas(string atlasName, Action<SpriteAtlas> callback)
|
||||
@@ -33,7 +45,9 @@ public class SpriteAtlasLoader : MonoBehaviour
|
||||
var loadHandle = package.LoadAssetSync<SpriteAtlas>(atlasName);
|
||||
if (loadHandle.Status != EOperationStatus.Succeeded)
|
||||
{
|
||||
Debug.LogWarning($"Failed to load sprite atlas : {atlasName} ! {loadHandle.Error}");
|
||||
Debug.LogWarning($"Failed to load sprite atlas '{atlasName}': {loadHandle.Error}.");
|
||||
loadHandle.Release();
|
||||
callback.Invoke(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.U2D;
|
||||
|
||||
/// <summary>
|
||||
/// 记录 UI 面板依赖的图集资源
|
||||
/// </summary>
|
||||
public class PanelManifest : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 面板自动引用的图集
|
||||
/// 面板依赖的图集列表
|
||||
/// </summary>
|
||||
public List<SpriteAtlas> ReferencesAtlas = new List<SpriteAtlas>();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user