Compare commits

..

No commits in common. "main" and "1.3.7" have entirely different histories.
main ... 1.3.7

620 changed files with 12024 additions and 23027 deletions

17
.gitignore vendored
View File

@ -10,23 +10,8 @@
/[Ll]ogs/ /[Ll]ogs/
/[Mm]emoryCaptures/ /[Mm]emoryCaptures/
/Bundles/
/ProjectSettings/
/App/
/yoo/
/Assets/StreamingAssets
/Assets/StreamingAssets.meta
/Assets/Samples
/Assets/Samples.meta
/Packages
/UserSettings
# Asset meta data should only be ignored when the corresponding asset is also ignored # Asset meta data should only be ignored when the corresponding asset is also ignored
!/[Aa]ssets/**/*.meta
# Uncomment this line if you wish to ignore the asset store tools plugin # Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools* # /[Aa]ssets/AssetStoreTools*

View File

@ -2,813 +2,6 @@
All notable changes to this package will be documented in this file. All notable changes to this package will be documented in this file.
## [1.5.8] - 2024-8-14
### Fixed
- (#175) 修复了Mac平台URL路径有空格的情况会报Malformed URL错误。
- (#177) 修复了加载一个地址的主资源或子资源之后无法再加载另一种的问题。
- (#266) 修复了资源系统遍历IsBusy次数过多导致过多的耗时的问题。
- (#276) 修复了HostPlayMode模式下如果内置清单是最新版本每次运行都会触发拷贝行为。
- (#295) 修复了在安卓平台,华为和三星真机上有极小概率加载资源包失败 : Unable to open archive file。
### Added
- 新增资源导入器。
- 新增获取缓存文件信息的方法。
### Changed
- 支持鸿蒙操作系统。
- 支持资源下载器合并。
## [1.5.7] - 2023-10-07
### Changed
- WebGL平台支持创建下载器。
## [1.5.6-preview] - 2023-09-26
### Fixed
- (#172) 修复包裹初始化后package的状态不正确的问题。
## [1.5.5-preview] - 2023-09-25
### Fixed
- (#96) 修复了异步操作任务的完成回调在业务层触发异常时无法正常完成的问题。
- (#156) 修复了多个Package存在时服务器请求地址请求顺序不对的问题。
- (#163) 修复了Unity2019版本编译报错的问题。
- (#167) 修复了初始化时每次都会提示文件验证失败日志。
- (#171) 修复了IsNeedDownloadFromRemote里缺少判断依赖的资源是否下载 。
### Added
- 资源收集器里增加了AddressDisable规则。
- 资源收集器里FilterRuleData结构体增加了多个备选字段。
```c#
public struct FilterRuleData
{
public string AssetPath;
public string CollectPath;
public string GroupName;
public string UserData;
}
```
### Changed
- 可以设置自定义参数DefaultYooFolderName。
- 资源配置界面的分组不激活时,不再进行配置检测。
- SBP构建管线增加新构建参数用于修复图集资源冗余问题。
```c#
public class SBPBuildParameters
{
/// <summary>
/// 修复图集资源冗余问题
/// </summary>
public bool FixSpriteAtlasRedundancy = false;
}
```
## [1.5.4-preview] - 2023-08-25
优化了资源清单文件构建速度极大提升构建体验感谢yingnierxiao同学
### Fixed
- (#130) 修复了打包路径无效问题bug
- (#138) 修复了Unity不支持的格式的原生文件会报warning
### Added
- 新增了IBuildinQueryServices 接口。
### Changed
- 在开启可寻址模式下,默认支持通过资源路径加载资源对象。
- 优化了资源收集界面,增加了配置相关的警示提示。
- 优化了资源报告界面增加了BundleView界面里的builtin资源的列表显示。
- IQueryServices接口变更为IBuildinQueryServices接口
- EOperationStatus增加了正在处理的状态。
```c#
public enum EOperationStatus
{
None,
Processing,
Succeed,
Failed
}
```
## [1.5.3-preview] - 2023-07-28
### Fixed
- 修复了Unity2020以下版本的编辑器提示找不到"autoLoadAssetBundle"的编译错误。
### Added
- 新增了支持开发者分发资源的功能。
```c#
public interface IQueryServices
{
/// <summary>
/// 查询应用程序里的内置资源是否存在
/// </summary>
bool QueryStreamingAssets(string packageName, string fileName);
/// <summary>
/// 查询是否为开发者分发的资源
/// </summary>
bool QueryDeliveryFiles(string packageName, string fileName);
/// <summary>
/// 获取开发者分发的资源信息
/// </summary>
DeliveryFileInfo GetDeliveryFileInfo(string packageName, string fileName);
}
```
### Changed
- 针对资源清单更新方法传入参数的合法性检测。
- 编辑器下针对激活的资源清单有效性的检测。
## [1.5.2-preview] - 2023-07-18
重新设计了对WebGL平台的支持新增加了专属模式WebPlayMode
## [1.5.1] - 2023-07-12
### Fixed
- 修复了太空战机DEMO在生成内置文件清单的时候目录不存在引发的异常。
- 修复了在销毁Package时如果存在正在加载的bundle会导致后续加载该bundle报错的问题。
### Changed
- 真机上使用错误方法加载原生文件的时候给予正确的错误提示。
### Added
- 新增了HostPlayModeParameters.RemoteServices字段
```c#
/// <summary>
/// 远端资源地址查询服务类
/// </summary>
public IRemoteServices RemoteServices = null;
```
### Removed
- 移除了HostPlayModeParameters.DefaultHostServer字段
- 移除了HostPlayModeParameters.FallbackHostServer字段
## [1.5.0] - 2023-07-05
该版本重构了Persistent类导致沙盒目录和内置目录的存储结构发生了变化。
该版本支持按照Package自定义沙盒存储目录和内置存储目录。
**注意低版本升级用户请使用Space Shooter目录下的StreamingAssetsHelper插件覆盖到本地工程**
### Changed
- BuildParameters.OutputRoot重命名为BuildOutputRoot
- 变更了IQueryServices.QueryStreamingAssets(string packageName, string fileName)方法
### Added
- 新增了YooAssets.SetCacheSystemDisableCacheOnWebGL()方法
```c#
/// <summary>
/// 设置缓存系统参数禁用缓存在WebGL平台
/// </summary>
public static void SetCacheSystemDisableCacheOnWebGL()
```
- 新增了YooAssets.SetDownloadSystemRedirectLimit()方法
```c#
/// <summary>
/// 设置下载系统参数网络重定向次数Unity引擎默认值32
/// 注意:不支持设置为负值
/// </summary>
public static void SetDownloadSystemRedirectLimit(int redirectLimit)
```
- 新增了构建流程可扩展的方法。
```c#
public class AssetBundleBuilder
{
/// <summary>
/// 构建资源包
/// </summary>
public BuildResult Run(BuildParameters buildParameters, List<IBuildTask> buildPipeline)
}
```
- 新增了BuildParameters.StreamingAssetsRoot字段
```c#
public class BuildParameters
{
/// <summary>
/// 内置资源的根目录
/// </summary>
public string StreamingAssetsRoot;
}
```
- 新增了InitializeParameters.BuildinRootDirectory字段
```c#
/// <summary>
/// 内置文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string BuildinRootDirectory = string.Empty;
```
- 新增了InitializeParameters.SandboxRootDirectory字段
```c#
/// <summary>
/// 沙盒文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string SandboxRootDirectory = string.Empty;
```
- 新增了ResourcePackage.GetPackageBuildinRootDirectory()方法
```c#
/// <summary>
/// 获取包裹的内置文件根路径
/// </summary>
public string GetPackageBuildinRootDirectory()
```
- 新增了ResourcePackage.GetPackageSandboxRootDirectory()方法
```c#
/// <summary>
/// 获取包裹的沙盒文件根路径
/// </summary>
public string GetPackageSandboxRootDirectory()
```
- 新增了ResourcePackage.ClearPackageSandbox()方法
```c#
/// <summary>
/// 清空包裹的沙盒目录
/// </summary>
public void ClearPackageSandbox()
```
### Removed
- 移除了资源包构建流程任务节点可扩展功能。
- 移除了YooAssets.SetCacheSystemSandboxPath()方法
- 移除了YooAssets.GetStreamingAssetBuildinFolderName()方法
- 移除了YooAssets.GetSandboxRoot()方法
- 移除了YooAssets.ClearSandbox()方法
## [1.4.17] - 2023-06-27
### Changed
- 优化了缓存的信息文件写入方式
- 离线模式支持内置资源解压到沙盒
- 资源包构建流程任务节点支持可扩展
```c#
using YooAsset.Editor
[TaskAttribute(ETaskPipeline.AllPipeline, 100, "自定义任务节点")]
public class CustomTask : IBuildTask
```
- 资源收集界面增加了LocationToLower选项
- 资源收集界面增加了IncludeAssetGUID选项
- IShareAssetPackRule 重命名为 ISharedPackRule
### Added
- 新增了ResourcePackage.LoadAllAssetsAsync方法
```c#
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
```
- 新增了ResourcePackage.GetAssetInfoByGUID()方法
```c#
/// <summary>
/// 获取资源信息
/// </summary>
/// <param name="assetGUID">资源GUID</param>
public AssetInfo GetAssetInfoByGUID(string assetGUID)
```
- 新增了场景加载参数suspendLoad
```c#
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="suspendLoad">场景加载到90%自动挂起</param>
/// <param name="priority">优先级</param>
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100)
```
- Extension Sample 增加了GameObjectAssetReference示例脚本
- 新增加了ZeroRedundancySharedPackRule类零冗余的共享资源打包规则
- 新增加了FullRedundancySharedPackRule类全部冗余的共享资源打包规则
### Removed
- 移除了InitializeParameters.LocationToLower成员字段
- 移除了LoadSceneAsync方法里的activateOnLoad形参参数
- 移除了BuildParameters.AutoAnalyzeRedundancy成员字段
- 移除了DefaultShareAssetPackRule编辑器类
## [1.4.16] - 2023-06-14
### Changed
- 增加了自动分析冗余资源的开关
```c#
/// <summary>
/// 构建参数
/// </summary>
public class BuildParameters
{
/// <summary>
/// 自动分析冗余资源
/// </summary>
public bool AutoAnalyzeRedundancy = true;
}
```
- 太空战机DEMO启用了新的内置资源查询机制。
## [1.4.15] - 2023-06-09
### Fixed
- 修复了安卓平台,解压内置文件到沙盒失败后不再重新尝试的问题。
- 修复了验证远端下载文件,极小概率失败的问题。
- 修复了太空战机DEMO在IOS平台流解密失败的问题。
## [1.4.14] - 2023-05-26
### Fixed
- 修复了收集器对着色器未过滤的问题。
- 修复了内置着色器Tag特殊情况下未正确传染给依赖资源包的问题。
### Changed
- Unity2021版本及以上推荐使用可编程构建管线SBP
## [1.4.13] - 2023-05-12
### Changed
- 可寻址地址冲突时,打印冲突地址的资源路径。
- 销毁Package的时候清空该Package的缓存记录。
### Added
- 新增方法ResoucePackage.ClearAllCacheFilesAsync()
```c#
public class ResoucePackage
{
/// <summary>
/// 清理包裹本地所有的缓存文件
/// </summary>
public ClearAllCacheFilesOperation ClearAllCacheFilesAsync();
}
```
- 新增方法YooAssets.SetCacheSystemSandboxPath()
```c#
public class YooAssets
{
/// <summary>
/// 设置缓存系统参数,沙盒目录的存储路径
/// </summary>
public static void SetCacheSystemSandboxPath(string sandboxPath);
}
```
## [1.4.12] - 2023-04-22
### Changed
- 增加了对WEBGL平台加密选项的检测。
- 增加了YooAsset/Home Page菜单栏。
- 增加了鼠标右键创建配置的菜单。
- 增加了YooAssets.DestroyPackage()方法。
```c#
class YooAssets
{
/// <summary>
/// 销毁资源包
/// </summary>
/// <param name="package">资源包对象</param>
public static void DestroyPackage(string packageName);
}
```
- UpdatePackageManifestAsync方法增加了新参数autoSaveVersion
```c#
class ResourcePackage
{
/// <summary>
/// 向网络端请求并更新清单
/// </summary>
/// <param name="packageVersion">更新的包裹版本</param>
/// <param name="autoSaveVersion">更新成功后自动保存版本号,作为下次初始化的版本。</param>
/// <param name="timeout">超时时间默认值60秒</param>
public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion = true, int timeout = 60)
}
```
- BuildParameters类增加了新字段。
可以自定义共享资源文件的打包规则。
```c#
class BuildParameters
{
/// <summary>
/// 共享资源的打包规则
/// </summary>
public IShareAssetPackRule ShareAssetPackRule = null;
}
```
## [1.4.11] - 2023-04-14
### Fixed
- (#97)修复了着色器变种收集配置无法保存的问题。
- (#83)修复了资源收集界面Package列表没有实时刷新的问题。
- (#48)优化了场景卸载机制,在切换场景的时候不在主动卸载资源。
### Changed
- 增加了扩展属性
```c#
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
```
## [1.4.10] - 2023-04-08
### Fixed
- 修复了资源文件路径无效导致异常的问题。
- 修复了原生文件不支持ini格式文件的问题。
- 修复了通过代码途径导入XML配置的报错问题。
## [1.4.9] - 2023-03-29
### Fixed
- 修复了资源配置界面的GroupActiveRule保存无效的问题。
### Changed
- 优化了资源配置导入逻辑增加了对XML配置文件的合法性检测。
- 优化了UniTask的说明文档。
- 调整构建的输出目录结构。
- 调试窗口增加分屏功能。Unity2020.3+起效)
- 报告窗口增加分屏功能。Unity2020.3+起效)
- 编辑器模拟模式支持了虚拟资源包。
- 扩展了Instantiate方法。
```c#
public sealed class AssetOperationHandle
{
public GameObject InstantiateSync();
public GameObject InstantiateSync(Transform parent);
public GameObject InstantiateSync(Transform parent, bool worldPositionStays);
public GameObject InstantiateSync(Vector3 position, Quaternion rotation);
public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent);
}
```
### Added
- 优化了报告文件内容,增加了资源包内嵌的资源列表。
- 可寻址规则增加了AddressByFilePath类。
- 新增了新方法。
```c#
/// <summary>
/// 向远端请求并更新清单
/// </summary>
public class UpdatePackageManifestOperation : AsyncOperationBase
{
/// <summary>
/// 保存当前清单的版本,用于下次启动时自动加载的版本。
/// </summary>
public void SavePackageVersion();
}
```
- 新增了初始化参数。
```c#
/// <summary>
/// 下载失败尝试次数
/// 注意默认值为MaxValue
/// </summary>
public int DownloadFailedTryAgain = int.MaxValue;
```
- 新增了初始化参数。
```c#
/// <summary>
/// 资源加载每帧处理的最大时间片段
/// 注意默认值为MaxValue
/// </summary>
public long LoadingMaxTimeSlice = long.MaxValue;
```
### Removed
- 移除了代码里的Patch敏感字。
```c#
//PatchManifest.cs重命名为PackageManifest.cs
//AssetsPackage.cs重命名为ResourcePackage.cs
//YooAssets.CreateAssetsPackage()重命名为YooAssets.CreatePackage()
//YooAssets.GetAssetsPackage()重命名为YooAssets.GetPackage()
//YooAssets.TryGetAssetsPackage()重命名为YooAssets.TryGetPackage()
//YooAssets.HasAssetsPackage()重命名为YooAssets.HasPackage()
```
- 移除了初始化参数AssetLoadingMaxNumber
## [1.4.8] - 2023-03-10
### Fixed
- 修复了同步加载原生文件,程序卡死的问题。
- 修复了可编程构建管线,当项目里没有着色器,如果有引用内置着色器会导致打包失败的问题。
- 修复了在Unity2021.3版本下着色器收集界面错乱的问题。
### Changed
- 优化了打包逻辑,提高构建速度。
- 支持自定义日志处理,方便收集线上问题。
```c#
public class YooAssets
{
/// <summary>
/// 初始化资源系统
/// </summary>
/// <param name="logger">自定义日志处理</param>
public static void Initialize(ILogger logger = null)
}
```
## [1.4.7] - 2023-03-03
### Fixed
- 修复了在运行时资源引用链无效的问题。
- 修复了在构建过程中发生异常后进度条未消失的问题。
- 修复了使用SBP构建管线如果有原生文件会导致打包失败的问题。
### Changed
- 支持自定义下载请求
```c#
/// <summary>
/// 设置下载系统参数,自定义下载请求
/// </summary>
public static void SetDownloadSystemUnityWebRequest(DownloadRequestDelegate requestDelegate)
```
- 优化了打包时资源包引用关系计算的逻辑。
- 优化了缓存系统初始化逻辑,支持分帧获取所有缓存文件。
- 优化了缓存系统的存储目录结构,提高了文件夹查询速度。
- 优化了在资源收集界面点击查看Collector主资源列表卡顿问题。
- 优化了资源对象加载耗时统计的逻辑,现在更加准确了。
- 优化了资源加载器查询逻辑。
- 优化了资源下载系统,下载文件的验证支持了多线程。
- 着色器变种收集界面增加单次照射数量的控制。
## [1.4.6-preview] - 2023-02-22
### Changed
- EVerifyLevel新增Middle级别。
```c#
public enum EVerifyLevel
{
/// <summary>
/// 验证文件存在
/// </summary>
Low,
/// <summary>
/// 验证文件大小
/// </summary>
Middle,
/// <summary>
/// 验证文件大小和CRC
/// </summary>
High,
}
```
- 补丁清单的资源包列表新增引用链。
(解决复杂依赖关系下,错误卸载资源包的问题)
- 缓存系统支持后缀格式存储。
(解决原生文件没有后缀格式的问题)
- 收集界面增加用户自定义数据栏。
## [1.4.5-preview] - 2023-02-17
### Fixed
- (#67)修复了报告查看界面在Unity2021.3上的兼容性问题。
- (#66)修复了在Unity2021.3上编辑器模拟模式运行报错的问题。
### Changed
- 接口变更IPackRule
````c#
/// <summary>
/// 资源打包规则接口
/// </summary>
public interface IPackRule
{
/// <summary>
/// 获取打包规则结果
/// </summary>
PackRuleResult GetPackRuleResult(PackRuleData data);
/// <summary>
/// 是否为原生文件打包规则
/// </summary>
bool IsRawFilePackRule();
}
````
## [1.4.4-preview] - 2023-02-14
### Fixed
- (#65)修复了AssetBundle构建宏逻辑错误。
- 修复了AssetBundle加载宏逻辑错误。
## [1.4.3-preview] - 2023-02-10
全新的缓存系统!
### Fixed
- 修复了WebGL平台本地文件验证报错。
- 修复了WEBGL平台加载原生文件失败的问题。
- 修复了通过Handle句柄查询资源包下载进度为零的问题。
### Changed
- 着色器变种收集增加分批次处理功能。
- Unity2021版本开始不再支持内置构建管线。
### Removed
- 太空战机DEMO移除了BetterStreamingAssets插件。
## [1.4.2-preview] - 2023-01-03
### Fixed
- 修复了清单解析异步操作的进度条变化错误。
- 修复了更新资源清单错误计算超时时间的问题。
## [1.4.1-preview] - 2022-12-26
### Fixed
- 修复了开启UniqueBundleName选项后SBP构建报错的问题。
### Added
- 新增了AssetsPackage.PreDownloadPackageAsync()方法
````c#
/// <summary>
/// 预下载指定版本的包裹资源
/// </summary>
/// <param name="packageVersion">下载的包裹版本</param>
/// <param name="timeout">超时时间默认值60秒</param>
public PreDownloadPackageOperation PreDownloadPackageAsync(string packageVersion, int timeout = 60)
````
- 新增了OperationHandleBase.GetDownloadReport()方法
````c#
/// <summary>
/// 获取下载报告
/// </summary>
public DownloadReport GetDownloadReport();
````
### Changed
- 优化了资源清单更新流程,支持缓存下载的清单。
- 优化了清单文件的解析流程,支持分帧解析避免卡顿。
- 优化了缓存文件的验证流程,支持分帧处理。
- 初始化的时候支持覆盖安装检测,然后清理所有的缓存清单文件。
- ClearPackageUnusedCacheFilesAsync重名为ClearUnusedCacheFilesAsync
## [1.4.0-preview] - 2022-12-04
### Fixed
- (#46)修复了资源包初始化失败之后,再次初始化发生异常的问题。
- 修复了在初始化失败的之后销毁YooAssets会报异常的问题。
### Changed
- 优化了资源收集界面,可以选择显示中文别名。
- **优化了补丁清单序列化方式,由文本数据修改为二进制数据。**
- 资源操作句柄增加using支持。
## [1.3.7] - 2022-11-26 ## [1.3.7] - 2022-11-26
全新的太空战机Demo ! 全新的太空战机Demo !

View File

@ -1,8 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEditor; using UnityEditor;
@ -13,100 +11,93 @@ namespace YooAsset.Editor
private readonly BuildContext _buildContext = new BuildContext(); private readonly BuildContext _buildContext = new BuildContext();
/// <summary> /// <summary>
/// 构建资源包 /// 开始构建
/// </summary> /// </summary>
public BuildResult Run(BuildParameters buildParameters, List<IBuildTask> buildPipeline) public BuildResult Run(BuildParameters buildParameters)
{ {
// 清空旧数据
_buildContext.ClearAllContext();
// 检测构建参数是否为空 // 检测构建参数是否为空
if (buildParameters == null) if (buildParameters == null)
throw new Exception($"{nameof(buildParameters)} is null !"); throw new Exception($"{nameof(buildParameters)} is null !");
// 检测构建参数是否为空 // 检测可编程构建管线参数
if (buildPipeline.Count == 0) if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
throw new Exception($"Build pipeline is empty !"); {
if (buildParameters.SBPParameters == null)
throw new Exception($"{nameof(BuildParameters.SBPParameters)} is null !");
// 清空旧数据 if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
_buildContext.ClearAllContext(); throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");
}
// 构建参数 // 构建参数
var buildParametersContext = new BuildParametersContext(buildParameters); var buildParametersContext = new BuildParametersContext(buildParameters);
_buildContext.SetContextObject(buildParametersContext); _buildContext.SetContextObject(buildParametersContext);
// 初始化日志 // 是否显示LOG
BuildLogger.InitLogger(buildParameters.EnableLog); if (buildParameters.BuildMode == EBuildMode.SimulateBuild)
BuildRunner.EnableLog = false;
// 执行构建流程
var buildResult = BuildRunner.Run(buildPipeline, _buildContext);
if (buildResult.Success)
{
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
BuildLogger.Log($"{buildParameters.BuildMode} pipeline build succeed !");
}
else else
BuildRunner.EnableLog = true;
// 创建构建节点
List<IBuildTask> pipeline;
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{ {
BuildLogger.Warning($"{buildParameters.BuildMode} pipeline build failed !"); pipeline = new List<IBuildTask>
BuildLogger.Error($"Build task failed : {buildResult.FailedTask}");
BuildLogger.Error(buildResult.ErrorInfo);
}
return buildResult;
}
/// <summary>
/// 构建资源包
/// </summary>
public BuildResult Run(BuildParameters buildParameters)
{
var buildPipeline = GetDefaultBuildPipeline(buildParameters.BuildPipeline);
return Run(buildParameters, buildPipeline);
}
/// <summary>
/// 获取默认的构建流程
/// </summary>
private List<IBuildTask> GetDefaultBuildPipeline(EBuildPipeline buildPipeline)
{
// 获取任务节点的属性集合
if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
List<IBuildTask> pipeline = new List<IBuildTask>
{ {
new TaskPrepare(), //前期准备工作 new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表 new TaskGetBuildMap(), //获取构建列表
new TaskBuilding(), //开始执行构建 new TaskBuilding(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult(), //验证构建结果 new TaskVerifyBuildResult(), //验证构建结果
new TaskEncryption(), //加密资源文件 new TaskEncryption(), //加密资源文件
new TaskUpdateBundleInfo(), //更新资源包信息 new TaskUpdateBuildInfo(), //更新构建信息
new TaskCreateManifest(), //创建清单文件 new TaskCreatePatchManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件 new TaskCreateReport(), //创建报告文件
new TaskCreatePackage(), //制作 new TaskCreatePatchPackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件 new TaskCopyBuildinFiles(), //拷贝内置文件
}; };
return pipeline;
} }
else if (buildPipeline == EBuildPipeline.ScriptableBuildPipeline) else if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{ {
List<IBuildTask> pipeline = new List<IBuildTask> pipeline = new List<IBuildTask>
{ {
new TaskPrepare(), //前期准备工作 new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表 new TaskGetBuildMap(), //获取构建列表
new TaskBuilding_SBP(), //开始执行构建 new TaskBuilding_SBP(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult_SBP(), //验证构建结果 new TaskVerifyBuildResult_SBP(), //验证构建结果
new TaskEncryption(), //加密资源文件 new TaskEncryption(), //加密资源文件
new TaskUpdateBundleInfo(), //更新补丁信息 new TaskUpdateBuildInfo(), //更新构建信息
new TaskCreateManifest(), //创建清单文件 new TaskCreatePatchManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件 new TaskCreateReport(), //创建报告文件
new TaskCreatePackage(), //制作补丁包 new TaskCreatePatchPackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件 new TaskCopyBuildinFiles(), //拷贝内置文件
}; };
return pipeline;
} }
else else
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
// 执行构建流程
var buildResult = BuildRunner.Run(pipeline, _buildContext);
if (buildResult.Success)
{
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
Debug.Log($"{buildParameters.BuildMode} pipeline build succeed !");
}
else
{
Debug.LogWarning($"{buildParameters.BuildMode} pipeline build failed !");
Debug.LogError($"Build task failed : {buildResult.FailedTask}");
Debug.LogError($"Build task error : {buildResult.FailedInfo}");
}
return buildResult;
} }
} }
} }

View File

@ -11,7 +11,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 获取默认的输出根路录 /// 获取默认的输出根路录
/// </summary> /// </summary>
public static string GetDefaultBuildOutputRoot() public static string GetDefaultOutputRoot()
{ {
string projectPath = EditorTools.GetProjectPath(); string projectPath = EditorTools.GetProjectPath();
return $"{projectPath}/Bundles"; return $"{projectPath}/Bundles";
@ -20,9 +20,52 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 获取流文件夹路径 /// 获取流文件夹路径
/// </summary> /// </summary>
public static string GetDefaultStreamingAssetsRoot() public static string GetStreamingAssetsFolderPath()
{ {
return $"{Application.dataPath}/StreamingAssets/{YooAssetSettingsData.Setting.DefaultYooFolderName}/"; return $"{Application.dataPath}/StreamingAssets/{YooAssetSettings.StreamingAssetsBuildinFolder}/";
}
/// <summary>
/// 清空流文件夹
/// </summary>
public static void ClearStreamingAssetsFolder()
{
string streamingFolderPath = GetStreamingAssetsFolderPath();
EditorTools.ClearFolder(streamingFolderPath);
}
/// <summary>
/// 删除流文件夹内无关的文件
/// 删除.manifest文件和.meta文件
/// </summary>
public static void DeleteStreamingAssetsIgnoreFiles()
{
string streamingFolderPath = GetStreamingAssetsFolderPath();
if (Directory.Exists(streamingFolderPath))
{
string[] files = Directory.GetFiles(streamingFolderPath, "*.manifest", SearchOption.AllDirectories);
foreach (var file in files)
{
FileInfo info = new FileInfo(file);
info.Delete();
}
files = Directory.GetFiles(streamingFolderPath, "*.meta", SearchOption.AllDirectories);
foreach (var item in files)
{
FileInfo info = new FileInfo(item);
info.Delete();
}
}
}
/// <summary>
/// 获取构建管线的输出目录
/// </summary>
public static string MakePipelineOutputDirectory(string outputRoot, string buildPackage, BuildTarget buildTarget, EBuildMode buildMode)
{
string outputDirectory = $"{outputRoot}/{buildPackage}/{buildTarget}/{YooAssetSettings.OutputFolderName}";
return outputDirectory;
} }
} }
} }

View File

@ -3,7 +3,6 @@ using UnityEngine;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[CreateAssetMenu(fileName = "AssetBundleBuilderSetting", menuName = "YooAsset/Create AssetBundle Builder Settings")]
public class AssetBundleBuilderSetting : ScriptableObject public class AssetBundleBuilderSetting : ScriptableObject
{ {
/// <summary> /// <summary>

View File

@ -29,7 +29,7 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
private static void LoadSettingData() private static void LoadSettingData()
{ {
_setting = SettingLoader.LoadSettingData<AssetBundleBuilderSetting>(); _setting = EditorHelper.LoadSettingData<AssetBundleBuilderSetting>();
} }
/// <summary> /// <summary>

View File

@ -0,0 +1,215 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
namespace YooAsset.Editor
{
public static class AssetBundleBuilderTools
{
/// <summary>
/// 检测所有损坏的预制体文件
/// </summary>
public static void CheckCorruptionPrefab(List<string> searchDirectorys)
{
if (searchDirectorys.Count == 0)
throw new Exception("路径列表不能为空!");
// 获取所有资源列表
int checkCount = 0;
int invalidCount = 0;
string[] findAssets = EditorTools.FindAssets(EAssetSearchType.Prefab, searchDirectorys.ToArray());
foreach (string assetPath in findAssets)
{
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object));
if (prefab == null)
{
invalidCount++;
Debug.LogError($"发现损坏预制件:{assetPath}");
}
EditorTools.DisplayProgressBar("检测预制件文件是否损坏", ++checkCount, findAssets.Length);
}
EditorTools.ClearProgressBar();
if (invalidCount == 0)
Debug.Log($"没有发现损坏预制件");
}
/// <summary>
/// 检测所有动画控制器的冗余状态
/// </summary>
public static void FindRedundantAnimationState(List<string> searchDirectorys)
{
if (searchDirectorys.Count == 0)
throw new Exception("路径列表不能为空!");
// 获取所有资源列表
int checkCount = 0;
int findCount = 0;
string[] findAssets = EditorTools.FindAssets(EAssetSearchType.RuntimeAnimatorController, searchDirectorys.ToArray());
foreach (string assetPath in findAssets)
{
AnimatorController animator= AssetDatabase.LoadAssetAtPath<AnimatorController>(assetPath);
if (FindRedundantAnimationState(animator))
{
findCount++;
Debug.LogWarning($"发现冗余的动画控制器:{assetPath}");
}
EditorTools.DisplayProgressBar("检测冗余的动画控制器", ++checkCount, findAssets.Length);
}
EditorTools.ClearProgressBar();
if (findCount == 0)
Debug.Log($"没有发现冗余的动画控制器");
else
AssetDatabase.SaveAssets();
}
/// <summary>
/// 清理所有材质球的冗余属性
/// </summary>
public static void ClearMaterialUnusedProperty(List<string> searchDirectorys)
{
if (searchDirectorys.Count == 0)
throw new Exception("路径列表不能为空!");
// 获取所有资源列表
int checkCount = 0;
int removedCount = 0;
string[] findAssets = EditorTools.FindAssets(EAssetSearchType.Material, searchDirectorys.ToArray());
foreach (string assetPath in findAssets)
{
Material mat = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
if (ClearMaterialUnusedProperty(mat))
{
removedCount++;
Debug.LogWarning($"材质球已被处理:{assetPath}");
}
EditorTools.DisplayProgressBar("清理冗余的材质球", ++checkCount, findAssets.Length);
}
EditorTools.ClearProgressBar();
if (removedCount == 0)
Debug.Log($"没有发现冗余的材质球");
else
AssetDatabase.SaveAssets();
}
/// <summary>
/// 清理无用的材质球属性
/// </summary>
private static bool ClearMaterialUnusedProperty(Material mat)
{
bool removeUnused = false;
SerializedObject so = new SerializedObject(mat);
SerializedProperty sp = so.FindProperty("m_SavedProperties");
sp.Next(true);
do
{
if (sp.isArray == false)
continue;
for (int i = sp.arraySize - 1; i >= 0; --i)
{
var p1 = sp.GetArrayElementAtIndex(i);
if (p1.isArray)
{
for (int ii = p1.arraySize - 1; ii >= 0; --ii)
{
var p2 = p1.GetArrayElementAtIndex(ii);
var val = p2.FindPropertyRelative("first");
if (mat.HasProperty(val.stringValue) == false)
{
Debug.Log($"Material {mat.name} remove unused property : {val.stringValue}");
p1.DeleteArrayElementAtIndex(ii);
removeUnused = true;
}
}
}
else
{
var val = p1.FindPropertyRelative("first");
if (mat.HasProperty(val.stringValue) == false)
{
Debug.Log($"Material {mat.name} remove unused property : {val.stringValue}");
sp.DeleteArrayElementAtIndex(i);
removeUnused = true;
}
}
}
}
while (sp.Next(false));
so.ApplyModifiedProperties();
return removeUnused;
}
/// <summary>
/// 查找动画控制器里冗余的动画状态机
/// </summary>
private static bool FindRedundantAnimationState(AnimatorController animatorController)
{
if (animatorController == null)
return false;
string assetPath = AssetDatabase.GetAssetPath(animatorController);
// 查找使用的状态机名称
List<string> usedStateNames = new List<string>();
foreach (var layer in animatorController.layers)
{
foreach (var state in layer.stateMachine.states)
{
usedStateNames.Add(state.state.name);
}
}
List<string> allLines = new List<string>();
List<int> stateIndexList = new List<int>();
using (StreamReader reader = File.OpenText(assetPath))
{
string content;
while (null != (content = reader.ReadLine()))
{
allLines.Add(content);
if (content.StartsWith("AnimatorState:"))
{
stateIndexList.Add(allLines.Count - 1);
}
}
}
List<string> allStateNames = new List<string>();
foreach (var index in stateIndexList)
{
for (int i = index; i < allLines.Count; i++)
{
string content = allLines[i];
content = content.Trim();
if (content.StartsWith("m_Name"))
{
string[] splits = content.Split(':');
string name = splits[1].TrimStart(' '); //移除前面的空格
allStateNames.Add(name);
break;
}
}
}
bool foundRedundantState = false;
foreach (var stateName in allStateNames)
{
if (usedStateNames.Contains(stateName) == false)
{
Debug.LogWarning($"发现冗余的动画文件:{assetPath}={stateName}");
foundRedundantState = true;
}
}
return foundRedundantState;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3625d4b8b5b79324ebf7ec19a87677e7 guid: fe50795c51a46884088139b840c1557f
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -12,9 +12,9 @@ namespace YooAsset.Editor
public class AssetBundleBuilderWindow : EditorWindow public class AssetBundleBuilderWindow : EditorWindow
{ {
[MenuItem("YooAsset/AssetBundle Builder", false, 102)] [MenuItem("YooAsset/AssetBundle Builder", false, 102)]
public static void OpenWindow() public static void ShowExample()
{ {
AssetBundleBuilderWindow window = GetWindow<AssetBundleBuilderWindow>("资源包构建工具", true, WindowsDefine.DockedWindowTypes); AssetBundleBuilderWindow window = GetWindow<AssetBundleBuilderWindow>("资源包构建工具", true, EditorDefine.DockedWindowTypes);
window.minSize = new Vector2(800, 600); window.minSize = new Vector2(800, 600);
} }
@ -42,7 +42,7 @@ namespace YooAsset.Editor
VisualElement root = this.rootVisualElement; VisualElement root = this.rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleBuilderWindow>(); var visualAsset = EditorHelper.LoadWindowUXML<AssetBundleBuilderWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
@ -60,10 +60,10 @@ namespace YooAsset.Editor
// 加密服务类 // 加密服务类
_encryptionServicesClassTypes = GetEncryptionServicesClassTypes(); _encryptionServicesClassTypes = GetEncryptionServicesClassTypes();
_encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.Name).ToList(); _encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.FullName).ToList();
// 输出目录 // 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(); string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
_buildOutputField = root.Q<TextField>("BuildOutput"); _buildOutputField = root.Q<TextField>("BuildOutput");
_buildOutputField.SetValueWithoutNotify(defaultOutputRoot); _buildOutputField.SetValueWithoutNotify(defaultOutputRoot);
_buildOutputField.SetEnabled(false); _buildOutputField.SetEnabled(false);
@ -220,27 +220,15 @@ namespace YooAsset.Editor
private void RefreshWindow() private void RefreshWindow()
{ {
var buildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode; var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
var copyOption = AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption; var copyOption = AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption;
bool enableElement = buildMode == EBuildMode.ForceRebuild; bool enableElement = buildMode == EBuildMode.ForceRebuild;
bool tagsFiledVisible = copyOption == ECopyBuildinFileOption.ClearAndCopyByTags || copyOption == ECopyBuildinFileOption.OnlyCopyByTags; bool tagsFiledVisible = copyOption == ECopyBuildinFileOption.ClearAndCopyByTags || copyOption == ECopyBuildinFileOption.OnlyCopyByTags;
_encryptionField.SetEnabled(enableElement);
if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline) _compressionField.SetEnabled(enableElement);
{ _outputNameStyleField.SetEnabled(enableElement);
_compressionField.SetEnabled(enableElement); _copyBuildinFileOptionField.SetEnabled(enableElement);
_outputNameStyleField.SetEnabled(enableElement); _copyBuildinFileTagsField.SetEnabled(enableElement);
_copyBuildinFileOptionField.SetEnabled(enableElement);
_copyBuildinFileTagsField.SetEnabled(enableElement);
}
else
{
_compressionField.SetEnabled(true);
_outputNameStyleField.SetEnabled(true);
_copyBuildinFileOptionField.SetEnabled(true);
_copyBuildinFileTagsField.SetEnabled(true);
}
_copyBuildinFileTagsField.visible = tagsFiledVisible; _copyBuildinFileTagsField.visible = tagsFiledVisible;
} }
private void SaveBtn_clicked() private void SaveBtn_clicked()
@ -266,16 +254,15 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
private void ExecuteBuild() private void ExecuteBuild()
{ {
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters(); BuildParameters buildParameters = new BuildParameters();
buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot(); buildParameters.OutputRoot = defaultOutputRoot;
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildTarget = _buildTarget; buildParameters.BuildTarget = _buildTarget;
buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline; buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode; buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage; buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage;
buildParameters.PackageVersion = _buildVersionField.value; buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.VerifyBuildingResult = true; buildParameters.VerifyBuildingResult = true;
buildParameters.SharedPackRule = new ZeroRedundancySharedPackRule();
buildParameters.EncryptionServices = CreateEncryptionServicesInstance(); buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption; buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle; buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;

View File

@ -11,20 +11,19 @@ namespace YooAsset.Editor
public static string SimulateBuild(string packageName) public static string SimulateBuild(string packageName)
{ {
Debug.Log($"Begin to create simulate package : {packageName}"); Debug.Log($"Begin to create simulate package : {packageName}");
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters(); BuildParameters buildParameters = new BuildParameters();
buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot(); buildParameters.OutputRoot = defaultOutputRoot;
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.BuildMode = EBuildMode.SimulateBuild; buildParameters.BuildMode = EBuildMode.SimulateBuild;
buildParameters.PackageName = packageName; buildParameters.PackageName = packageName;
buildParameters.PackageVersion = "Simulate"; buildParameters.PackageVersion = "Simulate";
buildParameters.EnableLog = false;
AssetBundleBuilder builder = new AssetBundleBuilder(); AssetBundleBuilder builder = new AssetBundleBuilder();
var buildResult = builder.Run(buildParameters); var buildResult = builder.Run(buildParameters);
if (buildResult.Success) if (buildResult.Success)
{ {
string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}"; string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}";
return manifestFilePath; return manifestFilePath;
} }

View File

@ -7,6 +7,8 @@ namespace YooAsset.Editor
{ {
public class BuildAssetInfo public class BuildAssetInfo
{ {
private string _mainBundleName;
private string _shareBundleName;
private bool _isAddAssetTags = false; private bool _isAddAssetTags = false;
private readonly HashSet<string> _referenceBundleNames = new HashSet<string>(); private readonly HashSet<string> _referenceBundleNames = new HashSet<string>();
@ -15,11 +17,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public ECollectorType CollectorType { private set; get; } public ECollectorType CollectorType { private set; get; }
/// <summary>
/// 资源包完整名称
/// </summary>
public string BundleName { private set; get; }
/// <summary> /// <summary>
/// 可寻址地址 /// 可寻址地址
/// </summary> /// </summary>
@ -30,11 +27,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string AssetPath { private set; get; } public string AssetPath { private set; get; }
/// <summary>
/// 资源GUID
/// </summary>
public string AssetGUID { private set; get; }
/// <summary> /// <summary>
/// 是否为原生资源 /// 是否为原生资源
/// </summary> /// </summary>
@ -62,15 +54,14 @@ namespace YooAsset.Editor
public List<BuildAssetInfo> AllDependAssetInfos { private set; get; } public List<BuildAssetInfo> AllDependAssetInfos { private set; get; }
public BuildAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset) public BuildAssetInfo(ECollectorType collectorType, string mainBundleName, string address, string assetPath, bool isRawAsset)
{ {
_mainBundleName = mainBundleName;
CollectorType = collectorType; CollectorType = collectorType;
BundleName = bundleName;
Address = address; Address = address;
AssetPath = assetPath; AssetPath = assetPath;
IsRawAsset = isRawAsset; IsRawAsset = isRawAsset;
AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath); System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection)) if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
IsShaderAsset = true; IsShaderAsset = true;
@ -84,7 +75,6 @@ namespace YooAsset.Editor
AssetPath = assetPath; AssetPath = assetPath;
IsRawAsset = false; IsRawAsset = false;
AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath); System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection)) if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
IsShaderAsset = true; IsShaderAsset = true;
@ -143,12 +133,24 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool HasBundleName() public bool HasBundleName()
{ {
if (string.IsNullOrEmpty(BundleName)) string bundleName = GetBundleName();
if (string.IsNullOrEmpty(bundleName))
return false; return false;
else else
return true; return true;
} }
/// <summary>
/// 获取资源包名称
/// </summary>
public string GetBundleName()
{
if (CollectorType == ECollectorType.None)
return _shareBundleName;
else
return _mainBundleName;
}
/// <summary> /// <summary>
/// 添加关联的资源包名称 /// 添加关联的资源包名称
/// </summary> /// </summary>
@ -162,52 +164,50 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 计算共享资源的完整包名 /// 计算主资源或共享资源的完整包名
/// </summary> /// </summary>
public void CalculateShareBundleName(ISharedPackRule sharedPackRule, bool uniqueBundleName, string packageName, string shadersBundleName) public void CalculateFullBundleName(bool uniqueBundleName, string packageName)
{ {
if (CollectorType != ECollectorType.None) if (CollectorType == ECollectorType.None)
return;
if (IsRawAsset)
throw new Exception("Should never get here !");
if (IsShaderAsset)
{ {
BundleName = shadersBundleName; if (IsRawAsset)
} throw new Exception("Should never get here !");
else
{ if (IsShaderAsset)
if (_referenceBundleNames.Count > 1)
{ {
PackRuleResult packRuleResult = sharedPackRule.GetPackRuleResult(AssetPath); string shareBundleName = YooAssetSettingsData.GetUnityShadersBundleFullName();
BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName); _shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
} }
else else
{ {
// 注意被引用次数小于1的资源不需要设置资源包名称 if (_referenceBundleNames.Count > 1)
BundleName = string.Empty; {
IPackRule packRule = PackDirectory.StaticPackRule;
var bundleName = packRule.GetBundleName(new PackRuleData(AssetPath));
var shareBundleName = $"share_{bundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}";
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
}
}
if (uniqueBundleName)
{
if (string.IsNullOrEmpty(_shareBundleName) == false)
_shareBundleName = $"{packageName.ToLower()}_{_shareBundleName}";
}
}
else
{
if (IsRawAsset)
{
string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.RawFileVariant}";
_mainBundleName = EditorTools.GetRegularPath(mainBundleName).ToLower();
}
else
{
string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}";
_mainBundleName = EditorTools.GetRegularPath(mainBundleName).ToLower(); ;
} }
} }
} }
/// <summary>
/// 判断是否为冗余资源
/// </summary>
public bool IsRedundancyAsset()
{
if (HasBundleName())
return false;
return _referenceBundleNames.Count > 1;
}
/// <summary>
/// 获取关联资源包的数量
/// </summary>
public int GetReferenceBundleCount()
{
return _referenceBundleNames.Count;
}
} }
} }

View File

@ -8,54 +8,39 @@ namespace YooAsset.Editor
{ {
public class BuildBundleInfo public class BuildBundleInfo
{ {
#region 补丁文件的关键信息 public class BuildPatchInfo
/// <summary> {
/// Unity引擎生成的哈希值构建内容的哈希值 /// <summary>
/// </summary> /// 构建内容的哈希值
public string PackageUnityHash { set; get; } /// </summary>
public string ContentHash { set; get; }
/// <summary> /// <summary>
/// Unity引擎生成的CRC /// 文件哈希值
/// </summary> /// </summary>
public uint PackageUnityCRC { set; get; } public string PatchFileHash { set; get; }
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
/// </summary> /// </summary>
public string PackageFileHash { set; get; } public string PatchFileCRC { set; get; }
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
/// </summary> /// </summary>
public string PackageFileCRC { set; get; } public long PatchFileSize { set; get; }
/// <summary>
/// 文件哈希值
/// </summary>
public long PackageFileSize { set; get; }
/// <summary> /// <summary>
/// 构建输出的文件路径 /// 构建输出的文件路径
/// </summary> /// </summary>
public string BuildOutputFilePath { set; get; } public string BuildOutputFilePath { set; get; }
/// <summary>
/// 补丁包的源文件路径
/// </summary>
public string PackageSourceFilePath { set; get; }
/// <summary>
/// 补丁包的目标文件路径
/// </summary>
public string PackageDestFilePath { set; get; }
/// <summary>
/// 加密生成文件的路径
/// 注意:如果未加密该路径为空
/// </summary>
public string EncryptedFilePath { set; get; }
#endregion
/// <summary>
/// 补丁包输出文件路径
/// </summary>
public string PatchOutputFilePath { set; get; }
}
/// <summary> /// <summary>
/// 资源包名称 /// 资源包名称
@ -64,15 +49,26 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 参与构建的资源列表 /// 参与构建的资源列表
/// 注意:不包含零依赖资源和冗余资源 /// 注意:不包含零依赖资源
/// </summary> /// </summary>
public readonly List<BuildAssetInfo> AllMainAssets = new List<BuildAssetInfo>(); public readonly List<BuildAssetInfo> BuildinAssets = new List<BuildAssetInfo>();
/// <summary>
/// 补丁文件信息
/// </summary>
public readonly BuildPatchInfo PatchInfo = new BuildPatchInfo();
/// <summary> /// <summary>
/// Bundle文件的加载方法 /// Bundle文件的加载方法
/// </summary> /// </summary>
public EBundleLoadMethod LoadMethod { set; get; } public EBundleLoadMethod LoadMethod { set; get; }
/// <summary>
/// 加密生成文件的路径
/// 注意:如果未加密该路径为空
/// </summary>
public string EncryptedFilePath { set; get; }
/// <summary> /// <summary>
/// 是否为原生文件 /// 是否为原生文件
/// </summary> /// </summary>
@ -80,9 +76,9 @@ namespace YooAsset.Editor
{ {
get get
{ {
foreach (var assetInfo in AllMainAssets) foreach (var asset in BuildinAssets)
{ {
if (assetInfo.IsRawAsset) if (asset.IsRawAsset)
return true; return true;
} }
return false; return false;
@ -117,7 +113,7 @@ namespace YooAsset.Editor
if (IsContainsAsset(assetInfo.AssetPath)) if (IsContainsAsset(assetInfo.AssetPath))
throw new System.Exception($"Asset is existed : {assetInfo.AssetPath}"); throw new System.Exception($"Asset is existed : {assetInfo.AssetPath}");
AllMainAssets.Add(assetInfo); BuildinAssets.Add(assetInfo);
} }
/// <summary> /// <summary>
@ -125,7 +121,7 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool IsContainsAsset(string assetPath) public bool IsContainsAsset(string assetPath)
{ {
foreach (var assetInfo in AllMainAssets) foreach (var assetInfo in BuildinAssets)
{ {
if (assetInfo.AssetPath == assetPath) if (assetInfo.AssetPath == assetPath)
{ {
@ -140,8 +136,8 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string[] GetBundleTags() public string[] GetBundleTags()
{ {
List<string> result = new List<string>(AllMainAssets.Count); List<string> result = new List<string>(BuildinAssets.Count);
foreach (var assetInfo in AllMainAssets) foreach (var assetInfo in BuildinAssets)
{ {
foreach (var assetTag in assetInfo.BundleTags) foreach (var assetTag in assetInfo.BundleTags)
{ {
@ -155,33 +151,17 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 获取构建的资源路径列表 /// 获取构建的资源路径列表
/// </summary> /// </summary>
public string[] GetAllMainAssetPaths() public string[] GetBuildinAssetPaths()
{ {
return AllMainAssets.Select(t => t.AssetPath).ToArray(); return BuildinAssets.Select(t => t.AssetPath).ToArray();
} }
/// <summary> /// <summary>
/// 获取该资源包内的所有资源(包括零依赖资源和冗余资源) /// 获取所有写入补丁清单的资源
/// </summary> /// </summary>
public List<string> GetAllBuiltinAssetPaths() public BuildAssetInfo[] GetAllPatchAssetInfos()
{ {
var packAssets = GetAllMainAssetPaths(); return BuildinAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray();
List<string> result = new List<string>(packAssets);
foreach (var assetInfo in AllMainAssets)
{
if (assetInfo.AllDependAssetInfos == null)
continue;
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
{
// 注意:依赖资源里只添加零依赖资源和冗余资源
if (dependAssetInfo.HasBundleName() == false)
{
if (result.Contains(dependAssetInfo.AssetPath) == false)
result.Add(dependAssetInfo.AssetPath);
}
}
}
return result;
} }
/// <summary> /// <summary>
@ -193,33 +173,23 @@ namespace YooAsset.Editor
AssetBundleBuild build = new AssetBundleBuild(); AssetBundleBuild build = new AssetBundleBuild();
build.assetBundleName = BundleName; build.assetBundleName = BundleName;
build.assetBundleVariant = string.Empty; build.assetBundleVariant = string.Empty;
build.assetNames = GetAllMainAssetPaths(); build.assetNames = GetBuildinAssetPaths();
return build; return build;
} }
/// <summary> /// <summary>
/// 获取所有写入补丁清单的资源 /// 创建PatchBundle类
/// </summary> /// </summary>
public BuildAssetInfo[] GetAllManifestAssetInfos() internal PatchBundle CreatePatchBundle()
{ {
return AllMainAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray(); string fileHash = PatchInfo.PatchFileHash;
} string fileCRC = PatchInfo.PatchFileCRC;
long fileSize = PatchInfo.PatchFileSize;
/// <summary> bool isRawFile = IsRawFile;
/// 创建PackageBundle类 byte loadMethod = (byte)LoadMethod;
/// </summary> string[] tags = GetBundleTags();
internal PackageBundle CreatePackageBundle() PatchBundle patchBundle = new PatchBundle(BundleName, fileHash, fileCRC, fileSize, isRawFile, loadMethod, tags);
{ return patchBundle;
PackageBundle packageBundle = new PackageBundle();
packageBundle.BundleName = BundleName;
packageBundle.FileHash = PackageFileHash;
packageBundle.FileCRC = PackageFileCRC;
packageBundle.FileSize = PackageFileSize;
packageBundle.UnityCRC = PackageUnityCRC;
packageBundle.IsRawFile = IsRawFile;
packageBundle.LoadMethod = (byte)LoadMethod;
packageBundle.Tags = GetBundleTags();
return packageBundle;
} }
} }
} }

View File

@ -8,13 +8,6 @@ namespace YooAsset.Editor
{ {
public class BuildMapContext : IContextObject public class BuildMapContext : IContextObject
{ {
private readonly Dictionary<string, BuildBundleInfo> _bundleInfoDic = new Dictionary<string, BuildBundleInfo>(10000);
/// <summary>
/// 冗余的资源列表
/// </summary>
public readonly List<ReportRedundancyInfo> RedundancyInfos= new List<ReportRedundancyInfo>(1000);
/// <summary> /// <summary>
/// 参与构建的资源总数 /// 参与构建的资源总数
/// 说明:包括主动收集的资源以及其依赖的所有资源 /// 说明:包括主动收集的资源以及其依赖的所有资源
@ -22,20 +15,19 @@ namespace YooAsset.Editor
public int AssetFileCount; public int AssetFileCount;
/// <summary> /// <summary>
/// 收集命令 /// 是否启用可寻址资源定位
/// </summary> /// </summary>
public CollectCommand Command { set; get; } public bool EnableAddressable;
/// <summary> /// <summary>
/// 资源包信息列表 /// 资源包名唯一化
/// </summary> /// </summary>
public Dictionary<string, BuildBundleInfo>.ValueCollection Collection public bool UniqueBundleName;
{
get /// <summary>
{ /// 资源包列表
return _bundleInfoDic.Values; /// </summary>
} public readonly List<BuildBundleInfo> BundleInfos = new List<BuildBundleInfo>(1000);
}
/// <summary> /// <summary>
@ -43,11 +35,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public void PackAsset(BuildAssetInfo assetInfo) public void PackAsset(BuildAssetInfo assetInfo)
{ {
string bundleName = assetInfo.BundleName; string bundleName = assetInfo.GetBundleName();
if (string.IsNullOrEmpty(bundleName)) if (string.IsNullOrEmpty(bundleName))
throw new Exception("Should never get here !"); throw new Exception("Should never get here !");
if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo bundleInfo)) if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo))
{ {
bundleInfo.PackAsset(assetInfo); bundleInfo.PackAsset(assetInfo);
} }
@ -55,28 +47,33 @@ namespace YooAsset.Editor
{ {
BuildBundleInfo newBundleInfo = new BuildBundleInfo(bundleName); BuildBundleInfo newBundleInfo = new BuildBundleInfo(bundleName);
newBundleInfo.PackAsset(assetInfo); newBundleInfo.PackAsset(assetInfo);
_bundleInfoDic.Add(bundleName, newBundleInfo); BundleInfos.Add(newBundleInfo);
} }
} }
/// <summary> /// <summary>
/// 是否包含资源包 /// 获取所有的打包资源
/// </summary> /// </summary>
public bool IsContainsBundle(string bundleName) public List<BuildAssetInfo> GetAllAssets()
{ {
return _bundleInfoDic.ContainsKey(bundleName); List<BuildAssetInfo> result = new List<BuildAssetInfo>(BundleInfos.Count);
} foreach (var bundleInfo in BundleInfos)
/// <summary>
/// 获取资源包信息如果没找到返回NULL
/// </summary>
public BuildBundleInfo GetBundleInfo(string bundleName)
{
if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo result))
{ {
return result; result.AddRange(bundleInfo.BuildinAssets);
} }
throw new Exception($"Not found bundle : {bundleName}"); return result;
}
/// <summary>
/// 获取AssetBundle内构建的资源路径列表
/// </summary>
public string[] GetBuildinAssetPaths(string bundleName)
{
if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo))
{
return bundleInfo.GetBuildinAssetPaths();
}
throw new Exception($"Not found {nameof(BuildBundleInfo)} : {bundleName}");
} }
/// <summary> /// <summary>
@ -84,8 +81,8 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public UnityEditor.AssetBundleBuild[] GetPipelineBuilds() public UnityEditor.AssetBundleBuild[] GetPipelineBuilds()
{ {
List<UnityEditor.AssetBundleBuild> builds = new List<UnityEditor.AssetBundleBuild>(_bundleInfoDic.Count); List<UnityEditor.AssetBundleBuild> builds = new List<UnityEditor.AssetBundleBuild>(BundleInfos.Count);
foreach (var bundleInfo in _bundleInfoDic.Values) foreach (var bundleInfo in BundleInfos)
{ {
if (bundleInfo.IsRawFile == false) if (bundleInfo.IsRawFile == false)
builds.Add(bundleInfo.CreatePipelineBuild()); builds.Add(bundleInfo.CreatePipelineBuild());
@ -94,15 +91,25 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 创建着色器信息类 /// 是否包含资源包
/// </summary> /// </summary>
public void CreateShadersBundleInfo(string shadersBundleName) public bool IsContainsBundle(string bundleName)
{ {
if (IsContainsBundle(shadersBundleName) == false) return TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo);
}
public bool TryGetBundleInfo(string bundleName, out BuildBundleInfo result)
{
foreach (var bundleInfo in BundleInfos)
{ {
var shaderBundleInfo = new BuildBundleInfo(shadersBundleName); if (bundleInfo.BundleName == bundleName)
_bundleInfoDic.Add(shadersBundleName, shaderBundleInfo); {
result = bundleInfo;
return true;
}
} }
result = null;
return false;
} }
} }
} }

View File

@ -0,0 +1,141 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset.Editor
{
public static class BuildMapCreater
{
/// <summary>
/// 执行资源构建上下文
/// </summary>
public static BuildMapContext CreateBuildMap(EBuildMode buildMode, string packageName)
{
BuildMapContext context = new BuildMapContext();
Dictionary<string, BuildAssetInfo> buildAssetDic = new Dictionary<string, BuildAssetInfo>(1000);
// 1. 检测配置合法性
AssetBundleCollectorSettingData.Setting.CheckConfigError();
// 2. 获取所有收集器收集的资源
var buildResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
List<CollectAssetInfo> allCollectAssets = buildResult.CollectAssets;
// 3. 剔除未被引用的依赖资源
List<CollectAssetInfo> removeDependList = new List<CollectAssetInfo>();
foreach (var collectAssetInfo in allCollectAssets)
{
if (collectAssetInfo.CollectorType == ECollectorType.DependAssetCollector)
{
if (IsRemoveDependAsset(allCollectAssets, collectAssetInfo.AssetPath))
removeDependList.Add(collectAssetInfo);
}
}
foreach (var removeValue in removeDependList)
{
allCollectAssets.Remove(removeValue);
}
// 4. 录入所有收集器收集的资源
foreach (var collectAssetInfo in allCollectAssets)
{
if (buildAssetDic.ContainsKey(collectAssetInfo.AssetPath) == false)
{
var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName,
collectAssetInfo.Address, collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset);
buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags);
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
buildAssetDic.Add(collectAssetInfo.AssetPath, buildAssetInfo);
}
else
{
throw new Exception($"Should never get here !");
}
}
// 5. 录入相关依赖的资源
foreach (var collectAssetInfo in allCollectAssets)
{
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
{
if (buildAssetDic.ContainsKey(dependAssetPath))
{
buildAssetDic[dependAssetPath].AddBundleTags(collectAssetInfo.AssetTags);
buildAssetDic[dependAssetPath].AddReferenceBundleName(collectAssetInfo.BundleName);
}
else
{
var buildAssetInfo = new BuildAssetInfo(dependAssetPath);
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
buildAssetInfo.AddReferenceBundleName(collectAssetInfo.BundleName);
buildAssetDic.Add(dependAssetPath, buildAssetInfo);
}
}
}
// 6. 记录关键信息
context.AssetFileCount = buildAssetDic.Count;
context.EnableAddressable = buildResult.EnableAddressable;
context.UniqueBundleName = buildResult.UniqueBundleName;
// 7. 填充主动收集资源的依赖列表
foreach (var collectAssetInfo in allCollectAssets)
{
var dependAssetInfos = new List<BuildAssetInfo>(collectAssetInfo.DependAssets.Count);
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
{
if (buildAssetDic.TryGetValue(dependAssetPath, out BuildAssetInfo value))
dependAssetInfos.Add(value);
else
throw new Exception("Should never get here !");
}
buildAssetDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos);
}
// 8. 计算完整的资源包名
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
{
pair.Value.CalculateFullBundleName(buildResult.UniqueBundleName, buildResult.PackageName);
}
// 9. 移除不参与构建的资源
List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>();
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
{
var buildAssetInfo = pair.Value;
if (buildAssetInfo.HasBundleName() == false)
removeBuildList.Add(buildAssetInfo);
}
foreach (var removeValue in removeBuildList)
{
buildAssetDic.Remove(removeValue.AssetPath);
}
// 10. 构建资源包
var allBuildinAssets = buildAssetDic.Values.ToList();
if (allBuildinAssets.Count == 0)
throw new Exception("构建的资源列表不能为空");
foreach (var assetInfo in allBuildinAssets)
{
context.PackAsset(assetInfo);
}
return context;
}
private static bool IsRemoveDependAsset(List<CollectAssetInfo> allCollectAssets, string dependAssetPath)
{
foreach (var collectAssetInfo in allCollectAssets)
{
var collectorType = collectAssetInfo.CollectorType;
if (collectorType == ECollectorType.MainAssetCollector || collectorType == ECollectorType.StaticAssetCollector)
{
if (collectAssetInfo.DependAssets.Contains(dependAssetPath))
return false;
}
}
BuildRunner.Log($"发现未被依赖的资源并自动移除 : {dependAssetPath}");
return true;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 2bc82466a51f50141975e4424095aa09 guid: e9274735f1f14af4b893c21a4240b816
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -28,11 +28,6 @@ namespace YooAsset.Editor
/// 缓存服务器端口 /// 缓存服务器端口
/// </summary> /// </summary>
public int CacheServerPort; public int CacheServerPort;
/// <summary>
/// 修复图集资源冗余问题
/// </summary>
public bool FixSpriteAtlasRedundancy = false;
} }
/// <summary> /// <summary>
@ -42,14 +37,9 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 内置资源的根目录 /// 输出的根目录
/// </summary> /// </summary>
public string StreamingAssetsRoot; public string OutputRoot;
/// <summary>
/// 构建输出的根目录
/// </summary>
public string BuildOutputRoot;
/// <summary> /// <summary>
/// 构建的平台 /// 构建的平台
@ -77,23 +67,13 @@ namespace YooAsset.Editor
public string PackageVersion; public string PackageVersion;
/// <summary>
/// 是否显示普通日志
/// </summary>
public bool EnableLog = true;
/// <summary> /// <summary>
/// 验证构建结果 /// 验证构建结果
/// </summary> /// </summary>
public bool VerifyBuildingResult = false; public bool VerifyBuildingResult = false;
/// <summary> /// <summary>
/// 共享资源的打包规则 /// 加密类
/// </summary>
public ISharedPackRule SharedPackRule = null;
/// <summary>
/// 资源的加密接口
/// </summary> /// </summary>
public IEncryptionServices EncryptionServices = null; public IEncryptionServices EncryptionServices = null;

View File

@ -7,10 +7,10 @@ namespace YooAsset.Editor
{ {
public class BuildParametersContext : IContextObject public class BuildParametersContext : IContextObject
{ {
private readonly System.Diagnostics.Stopwatch _buildWatch = new System.Diagnostics.Stopwatch();
private string _pipelineOutputDirectory = string.Empty; private string _pipelineOutputDirectory = string.Empty;
private string _packageOutputDirectory = string.Empty; private string _packageOutputDirectory = string.Empty;
private string _packageRootDirectory = string.Empty;
private string _streamingAssetsDirectory = string.Empty;
/// <summary> /// <summary>
/// 构建参数 /// 构建参数
@ -31,47 +31,23 @@ namespace YooAsset.Editor
{ {
if (string.IsNullOrEmpty(_pipelineOutputDirectory)) if (string.IsNullOrEmpty(_pipelineOutputDirectory))
{ {
_pipelineOutputDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{YooAssetSettings.OutputFolderName}"; _pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(Parameters.OutputRoot, Parameters.PackageName, Parameters.BuildTarget, Parameters.BuildMode);
} }
return _pipelineOutputDirectory; return _pipelineOutputDirectory;
} }
/// <summary> /// <summary>
/// 获取本次构建的补丁输出目录 /// 获取本次构建的补丁目录
/// </summary> /// </summary>
public string GetPackageOutputDirectory() public string GetPackageOutputDirectory()
{ {
if (string.IsNullOrEmpty(_packageOutputDirectory)) if (string.IsNullOrEmpty(_packageOutputDirectory))
{ {
_packageOutputDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{Parameters.PackageVersion}"; _packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.PackageName}/{Parameters.BuildTarget}/{Parameters.PackageVersion}";
} }
return _packageOutputDirectory; return _packageOutputDirectory;
} }
/// <summary>
/// 获取本次构建的补丁根目录
/// </summary>
public string GetPackageRootDirectory()
{
if (string.IsNullOrEmpty(_packageRootDirectory))
{
_packageRootDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}";
}
return _packageRootDirectory;
}
/// <summary>
/// 获取内置资源的目录
/// </summary>
public string GetStreamingAssetsDirectory()
{
if (string.IsNullOrEmpty(_streamingAssetsDirectory))
{
_streamingAssetsDirectory = $"{Parameters.StreamingAssetsRoot}/{Parameters.PackageName}";
}
return _streamingAssetsDirectory;
}
/// <summary> /// <summary>
/// 获取内置构建管线的构建选项 /// 获取内置构建管线的构建选项
/// </summary> /// </summary>
@ -141,5 +117,22 @@ namespace YooAsset.Editor
return buildParams; return buildParams;
} }
/// <summary>
/// 获取构建的耗时(单位:秒)
/// </summary>
public float GetBuildingSeconds()
{
float seconds = _buildWatch.ElapsedMilliseconds / 1000f;
return seconds;
}
public void BeginWatch()
{
_buildWatch.Start();
}
public void StopWatch()
{
_buildWatch.Stop();
}
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 28c5def11c9035443b6251933ffa6a30 guid: d6268d725eec21b4aae819adc1553f0e
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -27,11 +27,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public List<ReportBundleInfo> BundleInfos = new List<ReportBundleInfo>(); public List<ReportBundleInfo> BundleInfos = new List<ReportBundleInfo>();
/// <summary>
/// 冗余的资源列表
/// </summary>
public List<ReportRedundancyInfo> RedundancyInfos = new List<ReportRedundancyInfo>();
/// <summary> /// <summary>
/// 获取资源包信息类 /// 获取资源包信息类
@ -66,7 +61,7 @@ namespace YooAsset.Editor
File.Delete(savePath); File.Delete(savePath);
string json = JsonUtility.ToJson(buildReport, true); string json = JsonUtility.ToJson(buildReport, true);
FileUtility.WriteAllText(savePath, json); FileUtility.CreateFile(savePath, json);
} }
public static BuildReport Deserialize(string jsonData) public static BuildReport Deserialize(string jsonData)
{ {

View File

@ -48,16 +48,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string[] Tags; public string[] Tags;
/// <summary>
/// 引用该资源包的ID列表
/// </summary>
public int[] ReferenceIDs;
/// <summary>
/// 该资源包内包含的所有资源
/// </summary>
public List<string> AllBuiltinAssets = new List<string>();
/// <summary> /// <summary>
/// 获取资源分类标签的字符串 /// 获取资源分类标签的字符串
/// </summary> /// </summary>

View File

@ -58,26 +58,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool EnableAddressable; public bool EnableAddressable;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID;
/// <summary> /// <summary>
/// 资源包名唯一化 /// 资源包名唯一化
/// </summary> /// </summary>
public bool UniqueBundleName; public bool UniqueBundleName;
/// <summary>
/// 共享资源的打包规则类名
/// </summary>
public string SharedPackRuleClassName;
/// <summary> /// <summary>
/// 加密服务类名称 /// 加密服务类名称
/// </summary> /// </summary>

View File

@ -1,33 +0,0 @@
using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset.Editor
{
public static class BuildLogger
{
private static bool _enableLog = true;
public static void InitLogger(bool enableLog)
{
_enableLog = enableLog;
}
public static void Log(string message)
{
if (_enableLog)
{
Debug.Log(message);
}
}
public static void Warning(string message)
{
Debug.LogWarning(message);
}
public static void Error(string message)
{
Debug.LogError(message);
}
}
}

View File

@ -19,7 +19,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 构建失败的信息 /// 构建失败的信息
/// </summary> /// </summary>
public string ErrorInfo; public string FailedInfo;
/// <summary> /// <summary>
/// 输出的补丁包目录 /// 输出的补丁包目录

View File

@ -2,19 +2,13 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Diagnostics;
using UnityEngine; using UnityEngine;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
public class BuildRunner public class BuildRunner
{ {
private static Stopwatch _buildWatch; public static bool EnableLog = true;
/// <summary>
/// 总耗时
/// </summary>
public static int TotalSeconds = 0;
/// <summary> /// <summary>
/// 执行构建流程 /// 执行构建流程
@ -29,44 +23,45 @@ namespace YooAsset.Editor
BuildResult buildResult = new BuildResult(); BuildResult buildResult = new BuildResult();
buildResult.Success = true; buildResult.Success = true;
TotalSeconds = 0;
for (int i = 0; i < pipeline.Count; i++) for (int i = 0; i < pipeline.Count; i++)
{ {
IBuildTask task = pipeline[i]; IBuildTask task = pipeline[i];
try try
{ {
_buildWatch = Stopwatch.StartNew();
var taskAttribute = task.GetType().GetCustomAttribute<TaskAttribute>(); var taskAttribute = task.GetType().GetCustomAttribute<TaskAttribute>();
if (taskAttribute != null) Log($"---------------------------------------->{taskAttribute.Desc}<---------------------------------------");
BuildLogger.Log($"---------------------------------------->{taskAttribute.TaskDesc}<---------------------------------------");
task.Run(context); task.Run(context);
_buildWatch.Stop();
// 统计耗时
int seconds = GetBuildSeconds();
TotalSeconds += seconds;
if (taskAttribute != null)
BuildLogger.Log($"{taskAttribute.TaskDesc}耗时:{seconds}秒");
} }
catch (Exception e) catch (Exception e)
{ {
EditorTools.ClearProgressBar();
buildResult.FailedTask = task.GetType().Name; buildResult.FailedTask = task.GetType().Name;
buildResult.ErrorInfo = e.ToString(); buildResult.FailedInfo = e.ToString();
buildResult.Success = false; buildResult.Success = false;
break; break;
} }
} }
// 返回运行结果 // 返回运行结果
BuildLogger.Log($"构建过程总计耗时:{TotalSeconds}秒");
return buildResult; return buildResult;
} }
private static int GetBuildSeconds() /// <summary>
/// 日志输出
/// </summary>
public static void Log(string info)
{ {
float seconds = _buildWatch.ElapsedMilliseconds / 1000f; if (EnableLog)
return (int)seconds; {
UnityEngine.Debug.Log(info);
}
}
/// <summary>
/// 日志输出
/// </summary>
public static void Info(string info)
{
UnityEngine.Debug.Log(info);
} }
} }
} }

View File

@ -5,14 +5,10 @@ namespace YooAsset.Editor
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class TaskAttribute : Attribute public class TaskAttribute : Attribute
{ {
/// <summary> public string Desc;
/// 任务说明 public TaskAttribute(string desc)
/// </summary>
public string TaskDesc;
public TaskAttribute(string taskDesc)
{ {
TaskDesc = taskDesc; Desc = desc;
} }
} }
} }

View File

@ -1,68 +0,0 @@
using System.Collections.Generic;
using UnityEditor.Build.Content;
using UnityEngine.U2D;
using UnityEditor.Build.Pipeline.Injector;
using UnityEditor.Build.Pipeline.Interfaces;
using UnityEngine;
using System.Linq;
namespace UnityEditor.Build.Pipeline.Tasks
{
/// <summary>
/// Ref https://zhuanlan.zhihu.com/p/586918159
/// </summary>
public class RemoveSpriteAtlasRedundancy : IBuildTask
{
public int Version => 1;
[InjectContext]
IBundleWriteData writeDataParam;
public ReturnCode Run()
{
#if UNITY_2020_3_OR_NEWER
BundleWriteData writeData = (BundleWriteData)writeDataParam;
// 图集引用的精灵图片集合
HashSet<GUID> spriteGuids = new HashSet<GUID>();
foreach (var pair in writeData.FileToObjects)
{
foreach (ObjectIdentifier objectIdentifier in pair.Value)
{
var assetPath = AssetDatabase.GUIDToAssetPath(objectIdentifier.guid);
var assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(SpriteAtlas))
{
var spritePaths = AssetDatabase.GetDependencies(assetPath, false);
foreach (string spritePath in spritePaths)
{
GUID spriteGuild = AssetDatabase.GUIDFromAssetPath(spritePath);
spriteGuids.Add(spriteGuild);
}
}
}
}
// 移除图集引用的精力图片对象
foreach (var pair in writeData.FileToObjects)
{
List<ObjectIdentifier> objectIdentifiers = pair.Value;
for (int i = objectIdentifiers.Count - 1; i >= 0; i--)
{
ObjectIdentifier objectIdentifier = objectIdentifiers[i];
if (spriteGuids.Contains(objectIdentifier.guid))
{
if (objectIdentifier.localIdentifierInFile == 2800000)
{
// 删除图集散图的冗余纹理
objectIdentifiers.RemoveAt(i);
}
}
}
}
#endif
return ReturnCode.Success;
}
}
}

View File

@ -9,7 +9,7 @@ namespace UnityEditor.Build.Pipeline.Tasks
{ {
public static class SBPBuildTasks public static class SBPBuildTasks
{ {
public static IList<IBuildTask> Create(bool fixSpriteAtlasRedundancy, string builtInShaderBundleName) public static IList<IBuildTask> Create(string builtInShaderBundleName)
{ {
var buildTasks = new List<IBuildTask>(); var buildTasks = new List<IBuildTask>();
@ -33,8 +33,6 @@ namespace UnityEditor.Build.Pipeline.Tasks
// Packing // Packing
buildTasks.Add(new GenerateBundlePacking()); buildTasks.Add(new GenerateBundlePacking());
if (fixSpriteAtlasRedundancy)
buildTasks.Add(new RemoveSpriteAtlasRedundancy());
buildTasks.Add(new UpdateBundleObjectLayout()); buildTasks.Add(new UpdateBundleObjectLayout());
buildTasks.Add(new GenerateBundleCommands()); buildTasks.Add(new GenerateBundleCommands());
buildTasks.Add(new GenerateSubAssetPathMaps()); buildTasks.Add(new GenerateSubAssetPathMaps());

View File

@ -41,10 +41,36 @@ namespace YooAsset.Editor
throw new Exception("构建过程中发生严重错误!请查阅上下文日志!"); throw new Exception("构建过程中发生严重错误!请查阅上下文日志!");
} }
BuildLogger.Log("Unity引擎打包成功"); BuildRunner.Log("Unity引擎打包成功");
BuildResultContext buildResultContext = new BuildResultContext(); BuildResultContext buildResultContext = new BuildResultContext();
buildResultContext.UnityManifest = buildResults; buildResultContext.UnityManifest = buildResults;
context.SetContextObject(buildResultContext); context.SetContextObject(buildResultContext);
// 拷贝原生文件
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
CopyRawBundle(buildMapContext, buildParametersContext);
}
}
/// <summary>
/// 拷贝原生文件
/// </summary>
private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsRawFile)
{
string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
foreach (var buildAsset in bundleInfo.BuildinAssets)
{
if (buildAsset.IsRawAsset)
EditorTools.CopyFile(buildAsset.AssetPath, dest, true);
}
}
}
} }
} }
} }

View File

@ -33,26 +33,44 @@ namespace YooAsset.Editor
// 开始构建 // 开始构建
IBundleBuildResults buildResults; IBundleBuildResults buildResults;
var buildParameters = buildParametersContext.GetSBPBuildParameters(); var buildParameters = buildParametersContext.GetSBPBuildParameters();
var taskList = SBPBuildTasks.Create(buildParametersContext.Parameters.SBPParameters.FixSpriteAtlasRedundancy, buildMapContext.Command.ShadersBundleName); var shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName();
var taskList = SBPBuildTasks.Create(shadersBunldeName);
ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList); ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList);
if (exitCode < 0) if (exitCode < 0)
{ {
throw new Exception($"构建过程中发生错误 : {exitCode}"); throw new Exception($"构建过程中发生错误 : {exitCode}");
} }
// 创建着色器信息 BuildRunner.Log("Unity引擎打包成功");
// 说明:解决因为着色器资源包导致验证失败。
// 例如:当项目里没有着色器,如果有依赖内置着色器就会验证失败。
string shadersBundleName = buildMapContext.Command.ShadersBundleName;
if (buildResults.BundleInfos.ContainsKey(shadersBundleName))
{
buildMapContext.CreateShadersBundleInfo(shadersBundleName);
}
BuildLogger.Log("Unity引擎打包成功");
BuildResultContext buildResultContext = new BuildResultContext(); BuildResultContext buildResultContext = new BuildResultContext();
buildResultContext.Results = buildResults; buildResultContext.Results = buildResults;
context.SetContextObject(buildResultContext); context.SetContextObject(buildResultContext);
// 拷贝原生文件
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
CopyRawBundle(buildMapContext, buildParametersContext);
}
}
/// <summary>
/// 拷贝原生文件
/// </summary>
private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsRawFile)
{
string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
foreach (var buildAsset in bundleInfo.BuildinAssets)
{
if (buildAsset.IsRawAsset)
EditorTools.CopyFile(buildAsset.AssetPath, dest, true);
}
}
}
} }
} }
} }

View File

@ -12,13 +12,13 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var manifestContext = context.GetContextObject<ManifestContext>(); var patchManifestContext = context.GetContextObject<PatchManifestContext>();
var buildMode = buildParametersContext.Parameters.BuildMode; var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
if (buildParametersContext.Parameters.CopyBuildinFileOption != ECopyBuildinFileOption.None) if (buildParametersContext.Parameters.CopyBuildinFileOption != ECopyBuildinFileOption.None)
{ {
CopyBuildinFilesToStreaming(buildParametersContext, manifestContext); CopyBuildinFilesToStreaming(buildParametersContext, patchManifestContext);
} }
} }
} }
@ -26,26 +26,26 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 拷贝首包资源文件 /// 拷贝首包资源文件
/// </summary> /// </summary>
private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, ManifestContext manifestContext) private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, PatchManifestContext patchManifestContext)
{ {
ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption; ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
string streamingAssetsDirectory = buildParametersContext.GetStreamingAssetsDirectory(); string streamingAssetsDirectory = AssetBundleBuilderHelper.GetStreamingAssetsFolderPath();
string buildPackageName = buildParametersContext.Parameters.PackageName; string buildPackageName = buildParametersContext.Parameters.PackageName;
string buildPackageVersion = buildParametersContext.Parameters.PackageVersion; string buildPackageVersion = buildParametersContext.Parameters.PackageVersion;
// 加载补丁清单 // 加载补丁清单
PackageManifest manifest = manifestContext.Manifest; PatchManifest patchManifest = patchManifestContext.Manifest;
// 清空流目录 // 清空流目录
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags)
{ {
EditorTools.ClearFolder(streamingAssetsDirectory); AssetBundleBuilderHelper.ClearStreamingAssetsFolder();
} }
// 拷贝补丁清单文件 // 拷贝补丁清单文件
{ {
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildPackageName, buildPackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildPackageName, buildPackageVersion);
string sourcePath = $"{packageOutputDirectory}/{fileName}"; string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}"; string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
@ -53,7 +53,7 @@ namespace YooAsset.Editor
// 拷贝补丁清单哈希文件 // 拷贝补丁清单哈希文件
{ {
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildPackageName, buildPackageVersion); string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildPackageName, buildPackageVersion);
string sourcePath = $"{packageOutputDirectory}/{fileName}"; string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}"; string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
@ -61,7 +61,7 @@ namespace YooAsset.Editor
// 拷贝补丁清单版本文件 // 拷贝补丁清单版本文件
{ {
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildPackageName); string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildPackageName);
string sourcePath = $"{packageOutputDirectory}/{fileName}"; string sourcePath = $"{packageOutputDirectory}/{fileName}";
string destPath = $"{streamingAssetsDirectory}/{fileName}"; string destPath = $"{streamingAssetsDirectory}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
@ -70,10 +70,10 @@ namespace YooAsset.Editor
// 拷贝文件列表(所有文件) // 拷贝文件列表(所有文件)
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.OnlyCopyAll) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.OnlyCopyAll)
{ {
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}"; string sourcePath = $"{packageOutputDirectory}/{patchBundle.FileName}";
string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}"; string destPath = $"{streamingAssetsDirectory}/{patchBundle.FileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
} }
} }
@ -82,19 +82,19 @@ namespace YooAsset.Editor
if (option == ECopyBuildinFileOption.ClearAndCopyByTags || option == ECopyBuildinFileOption.OnlyCopyByTags) if (option == ECopyBuildinFileOption.ClearAndCopyByTags || option == ECopyBuildinFileOption.OnlyCopyByTags)
{ {
string[] tags = buildParametersContext.Parameters.CopyBuildinFileTags.Split(';'); string[] tags = buildParametersContext.Parameters.CopyBuildinFileTags.Split(';');
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
if (packageBundle.HasTag(tags) == false) if (patchBundle.HasTag(tags) == false)
continue; continue;
string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}"; string sourcePath = $"{packageOutputDirectory}/{patchBundle.FileName}";
string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}"; string destPath = $"{streamingAssetsDirectory}/{patchBundle.FileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
} }
} }
// 刷新目录 // 刷新目录
AssetDatabase.Refresh(); AssetDatabase.Refresh();
BuildLogger.Log($"内置文件拷贝完成:{streamingAssetsDirectory}"); BuildRunner.Log($"内置文件拷贝完成:{streamingAssetsDirectory}");
} }
} }
} }

View File

@ -1,44 +0,0 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset.Editor
{
[TaskAttribute("拷贝原生文件")]
public class TaskCopyRawFile : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
CopyRawBundle(buildMapContext, buildParametersContext);
}
}
/// <summary>
/// 拷贝原生文件
/// </summary>
private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.Collection)
{
if (bundleInfo.IsRawFile)
{
string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
foreach (var assetInfo in bundleInfo.AllMainAssets)
{
if (assetInfo.IsRawAsset)
EditorTools.CopyFile(assetInfo.AssetPath, dest, true);
}
}
}
}
}
}

View File

@ -1,384 +0,0 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build.Pipeline;
using UnityEditor.Build.Pipeline.Interfaces;
namespace YooAsset.Editor
{
public class ManifestContext : IContextObject
{
internal PackageManifest Manifest;
}
[TaskAttribute("创建清单文件")]
public class TaskCreateManifest : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
CreateManifestFile(context);
}
/// <summary>
/// 创建补丁清单文件到输出目录
/// </summary>
private void CreateManifestFile(BuildContext context)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
// 创建新补丁清单
PackageManifest manifest = new PackageManifest();
manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.LocationToLower = buildMapContext.Command.LocationToLower;
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
manifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
manifest.PackageName = buildParameters.PackageName;
manifest.PackageVersion = buildParameters.PackageVersion;
// 填充资源包集合
manifest.BundleList = GetAllPackageBundle(context);
CacheBundleIDs(manifest);
// 填充主资源集合
manifest.AssetList = GetAllPackageAsset(context, manifest);
// 更新Unity内置资源包的引用关系
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateBuiltInBundleReference(manifest, buildResultContext, buildMapContext.Command.ShadersBundleName);
}
}
// 更新资源包之间的引用关系
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateScriptPipelineReference(manifest, buildResultContext);
}
}
// 更新资源包之间的引用关系
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
{
var buildResultContext = context.GetContextObject<TaskBuilding.BuildResultContext>();
UpdateBuiltinPipelineReference(manifest, buildResultContext);
}
}
// 创建补丁清单文本文件
{
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
ManifestTools.SerializeToJson(filePath, manifest);
BuildLogger.Log($"创建补丁清单文件:{filePath}");
}
// 创建补丁清单二进制文件
string packageHash;
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
ManifestTools.SerializeToBinary(filePath, manifest);
packageHash = HashUtility.FileMD5(filePath);
BuildLogger.Log($"创建补丁清单文件:{filePath}");
ManifestContext manifestContext = new ManifestContext();
byte[] bytesData = FileUtility.ReadAllBytes(filePath);
manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData);
context.SetContextObject(manifestContext);
}
// 创建补丁清单哈希文件
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
FileUtility.WriteAllText(filePath, packageHash);
BuildLogger.Log($"创建补丁清单哈希文件:{filePath}");
}
// 创建补丁清单版本文件
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName);
string filePath = $"{packageOutputDirectory}/{fileName}";
FileUtility.WriteAllText(filePath, buildParameters.PackageVersion);
BuildLogger.Log($"创建补丁清单版本文件:{filePath}");
}
}
/// <summary>
/// 获取资源包列表
/// </summary>
private List<PackageBundle> GetAllPackageBundle(BuildContext context)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
List<PackageBundle> result = new List<PackageBundle>(1000);
foreach (var bundleInfo in buildMapContext.Collection)
{
var packageBundle = bundleInfo.CreatePackageBundle();
result.Add(packageBundle);
}
return result;
}
/// <summary>
/// 获取资源列表
/// </summary>
private List<PackageAsset> GetAllPackageAsset(BuildContext context, PackageManifest manifest)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
List<PackageAsset> result = new List<PackageAsset>(1000);
foreach (var bundleInfo in buildMapContext.Collection)
{
var assetInfos = bundleInfo.GetAllManifestAssetInfos();
foreach (var assetInfo in assetInfos)
{
PackageAsset packageAsset = new PackageAsset();
packageAsset.Address = buildMapContext.Command.EnableAddressable ? assetInfo.Address : string.Empty;
packageAsset.AssetPath = assetInfo.AssetPath;
packageAsset.AssetGUID = buildMapContext.Command.IncludeAssetGUID ? assetInfo.AssetGUID : string.Empty;
packageAsset.AssetTags = assetInfo.AssetTags.ToArray();
packageAsset.BundleID = GetCachedBundleID(assetInfo.BundleName);
packageAsset.DependIDs = GetAssetBundleDependIDs(packageAsset.BundleID, assetInfo, manifest);
result.Add(packageAsset);
}
}
return result;
}
private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PackageManifest manifest)
{
HashSet<int> result = new HashSet<int>();
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
{
if (dependAssetInfo.HasBundleName())
{
int bundleID = GetCachedBundleID(dependAssetInfo.BundleName);
if (mainBundleID != bundleID)
{
if (result.Contains(bundleID) == false)
result.Add(bundleID);
}
}
}
return result.ToArray();
}
/// <summary>
/// 更新Unity内置资源包的引用关系
/// </summary>
private void UpdateBuiltInBundleReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext, string shadersBunldeName)
{
// 获取所有依赖着色器资源包的资源包列表
List<string> shaderBundleReferenceList = new List<string>();
foreach (var valuePair in buildResultContext.Results.BundleInfos)
{
if (valuePair.Value.Dependencies.Any(t => t == shadersBunldeName))
shaderBundleReferenceList.Add(valuePair.Key);
}
// 注意:没有任何资源依赖着色器
if (shaderBundleReferenceList.Count == 0)
return;
// 获取着色器资源包索引
Predicate<PackageBundle> predicate = new Predicate<PackageBundle>(s => s.BundleName == shadersBunldeName);
int shaderBundleId = manifest.BundleList.FindIndex(predicate);
if (shaderBundleId == -1)
throw new Exception("没有发现着色器资源包!");
// 检测依赖交集并更新依赖ID
HashSet<string> tagTemps = new HashSet<string>();
foreach (var packageAsset in manifest.AssetList)
{
List<string> dependBundles = GetPackageAssetAllDependBundles(manifest, packageAsset);
List<string> conflictAssetPathList = dependBundles.Intersect(shaderBundleReferenceList).ToList();
if (conflictAssetPathList.Count > 0)
{
HashSet<int> newDependIDs = new HashSet<int>(packageAsset.DependIDs);
if (newDependIDs.Contains(shaderBundleId) == false)
newDependIDs.Add(shaderBundleId);
packageAsset.DependIDs = newDependIDs.ToArray();
foreach (var tag in packageAsset.AssetTags)
{
if (tagTemps.Contains(tag) == false)
tagTemps.Add(tag);
}
}
}
// 更新资源包标签
var packageBundle = manifest.BundleList[shaderBundleId];
HashSet<string> newTags = new HashSet<string>(packageBundle.Tags);
foreach (var tag in tagTemps)
{
if (newTags.Contains(tag) == false)
newTags.Add(tag);
}
packageBundle.Tags = newTags.ToArray();
}
private List<string> GetPackageAssetAllDependBundles(PackageManifest manifest, PackageAsset packageAsset)
{
List<string> result = new List<string>();
string mainBundle = manifest.BundleList[packageAsset.BundleID].BundleName;
result.Add(mainBundle);
foreach (var dependID in packageAsset.DependIDs)
{
string dependBundle = manifest.BundleList[dependID].BundleName;
result.Add(dependBundle);
}
return result;
}
#region 资源包引用关系相关
private readonly Dictionary<string, int> _cachedBundleID = new Dictionary<string, int>(10000);
private readonly Dictionary<string, string[]> _cachedBundleDepends = new Dictionary<string, string[]>(10000);
private void CacheBundleIDs(PackageManifest manifest)
{
UnityEngine.Debug.Assert(manifest.BundleList.Count != 0, "Manifest bundle list is empty !");
for (int index = 0; index < manifest.BundleList.Count; index++)
{
string bundleName = manifest.BundleList[index].BundleName;
_cachedBundleID.Add(bundleName, index);
}
}
private void UpdateScriptPipelineReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext)
{
int progressValue;
int totalCount = manifest.BundleList.Count;
// 缓存资源包依赖
_cachedBundleDepends.Clear();
progressValue = 0;
foreach (var packageBundle in manifest.BundleList)
{
if (packageBundle.IsRawFile)
{
_cachedBundleDepends.Add(packageBundle.BundleName, new string[] { });
continue;
}
if (buildResultContext.Results.BundleInfos.ContainsKey(packageBundle.BundleName) == false)
throw new Exception($"Not found bundle in SBP build results : {packageBundle.BundleName}");
var depends = buildResultContext.Results.BundleInfos[packageBundle.BundleName].Dependencies;
_cachedBundleDepends.Add(packageBundle.BundleName, depends);
int pro = ++progressValue;
if (pro % 100 == 0)
{
EditorTools.DisplayProgressBar("缓存资源包依赖列表", pro, totalCount);
}
}
EditorTools.ClearProgressBar();
// 计算资源包引用列表
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle);
int pro = ++progressValue;
if (pro % 100 == 0)
{
EditorTools.DisplayProgressBar("计算资源包引用关系", pro, totalCount);
}
}
EditorTools.ClearProgressBar();
}
private void UpdateBuiltinPipelineReference(PackageManifest manifest, TaskBuilding.BuildResultContext buildResultContext)
{
int progressValue;
int totalCount = manifest.BundleList.Count;
// 缓存资源包依赖
_cachedBundleDepends.Clear();
progressValue = 0;
foreach (var packageBundle in manifest.BundleList)
{
if (packageBundle.IsRawFile)
{
_cachedBundleDepends.Add(packageBundle.BundleName, new string[] { });
continue;
}
var depends = buildResultContext.UnityManifest.GetDirectDependencies(packageBundle.BundleName);
_cachedBundleDepends.Add(packageBundle.BundleName, depends);
int pro = ++progressValue;
if (pro % 100 == 0)
{
EditorTools.DisplayProgressBar("缓存资源包依赖列表", pro, totalCount);
}
}
EditorTools.ClearProgressBar();
// 计算资源包引用列表
progressValue = 0;
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle);
int pro = ++progressValue;
if (pro % 100 == 0)
{
EditorTools.DisplayProgressBar("计算资源包引用关系", ++progressValue, totalCount);
}
}
EditorTools.ClearProgressBar();
}
private int[] GetBundleRefrenceIDs(PackageManifest manifest, PackageBundle targetBundle)
{
List<string> referenceList = new List<string>();
foreach (var packageBundle in manifest.BundleList)
{
string bundleName = packageBundle.BundleName;
if (bundleName == targetBundle.BundleName)
continue;
string[] dependencies = GetCachedBundleDepends(bundleName);
if (dependencies.Contains(targetBundle.BundleName))
{
referenceList.Add(bundleName);
}
}
HashSet<int> result = new HashSet<int>();
foreach (var bundleName in referenceList)
{
int bundleID = GetCachedBundleID(bundleName);
if (result.Contains(bundleID) == false)
result.Add(bundleID);
}
return result.ToArray();
}
private int GetCachedBundleID(string bundleName)
{
if (_cachedBundleID.TryGetValue(bundleName, out int value) == false)
{
throw new Exception($"Not found cached bundle ID : {bundleName}");
}
return value;
}
private string[] GetCachedBundleDepends(string bundleName)
{
if (_cachedBundleDepends.TryGetValue(bundleName, out string[] value) == false)
{
throw new Exception($"Not found cached bundle depends : {bundleName}");
}
return value;
}
#endregion
}
}

View File

@ -0,0 +1,208 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build.Pipeline;
using UnityEditor.Build.Pipeline.Interfaces;
namespace YooAsset.Editor
{
public class PatchManifestContext : IContextObject
{
internal PatchManifest Manifest;
}
[TaskAttribute("创建补丁清单文件")]
public class TaskCreatePatchManifest : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
CreatePatchManifestFile(context);
}
/// <summary>
/// 创建补丁清单文件到输出目录
/// </summary>
private void CreatePatchManifestFile(BuildContext context)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
// 创建新补丁清单
PatchManifest patchManifest = new PatchManifest();
patchManifest.FileVersion = YooAssetSettings.PatchManifestFileVersion;
patchManifest.EnableAddressable = buildMapContext.EnableAddressable;
patchManifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
patchManifest.PackageName = buildParameters.PackageName;
patchManifest.PackageVersion = buildParameters.PackageVersion;
patchManifest.BundleList = GetAllPatchBundle(context);
patchManifest.AssetList = GetAllPatchAsset(context, patchManifest);
// 更新Unity内置资源包的引用关系
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
}
}
// 创建补丁清单文件
string packageHash;
{
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
PatchManifest.Serialize(filePath, patchManifest);
packageHash = HashUtility.FileMD5(filePath);
BuildRunner.Log($"创建补丁清单文件:{filePath}");
var patchManifestContext = new PatchManifestContext();
string jsonData = FileUtility.ReadFile(filePath);
patchManifestContext.Manifest = PatchManifest.Deserialize(jsonData);
context.SetContextObject(patchManifestContext);
}
// 创建补丁清单哈希文件
{
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
FileUtility.CreateFile(filePath, packageHash);
BuildRunner.Log($"创建补丁清单哈希文件:{filePath}");
}
// 创建补丁清单版本文件
{
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName);
string filePath = $"{packageOutputDirectory}/{fileName}";
FileUtility.CreateFile(filePath, buildParameters.PackageVersion);
BuildRunner.Log($"创建补丁清单版本文件:{filePath}");
}
}
/// <summary>
/// 获取资源包列表
/// </summary>
private List<PatchBundle> GetAllPatchBundle(BuildContext context)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
List<PatchBundle> result = new List<PatchBundle>(1000);
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
var patchBundle = bundleInfo.CreatePatchBundle();
result.Add(patchBundle);
}
return result;
}
/// <summary>
/// 获取资源列表
/// </summary>
private List<PatchAsset> GetAllPatchAsset(BuildContext context, PatchManifest patchManifest)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
List<PatchAsset> result = new List<PatchAsset>(1000);
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
var assetInfos = bundleInfo.GetAllPatchAssetInfos();
foreach (var assetInfo in assetInfos)
{
PatchAsset patchAsset = new PatchAsset();
if (buildMapContext.EnableAddressable)
patchAsset.Address = assetInfo.Address;
else
patchAsset.Address = string.Empty;
patchAsset.AssetPath = assetInfo.AssetPath;
patchAsset.AssetTags = assetInfo.AssetTags.ToArray();
patchAsset.BundleID = GetAssetBundleID(assetInfo.GetBundleName(), patchManifest);
patchAsset.DependIDs = GetAssetBundleDependIDs(patchAsset.BundleID, assetInfo, patchManifest);
result.Add(patchAsset);
}
}
return result;
}
private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PatchManifest patchManifest)
{
List<int> result = new List<int>();
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
{
if (dependAssetInfo.HasBundleName())
{
int bundleID = GetAssetBundleID(dependAssetInfo.GetBundleName(), patchManifest);
if (mainBundleID != bundleID)
{
if (result.Contains(bundleID) == false)
result.Add(bundleID);
}
}
}
return result.ToArray();
}
private int GetAssetBundleID(string bundleName, PatchManifest patchManifest)
{
for (int index = 0; index < patchManifest.BundleList.Count; index++)
{
if (patchManifest.BundleList[index].BundleName == bundleName)
return index;
}
throw new Exception($"Not found bundle name : {bundleName}");
}
/// <summary>
/// 更新Unity内置资源包的引用关系
/// </summary>
private void UpdateBuiltInBundleReference(PatchManifest patchManifest, IBundleBuildResults buildResults)
{
// 获取所有依赖着色器资源包的资源包列表
string shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName();
List<string> shaderBundleReferenceList = new List<string>();
foreach (var valuePair in buildResults.BundleInfos)
{
if (valuePair.Value.Dependencies.Any(t => t == shadersBunldeName))
shaderBundleReferenceList.Add(valuePair.Key);
}
// 注意:没有任何资源依赖着色器
if (shaderBundleReferenceList.Count == 0)
return;
// 获取着色器资源包索引
Predicate<PatchBundle> predicate = new Predicate<PatchBundle>(s => s.BundleName == shadersBunldeName);
int shaderBundleId = patchManifest.BundleList.FindIndex(predicate);
if (shaderBundleId == -1)
throw new Exception("没有发现着色器资源包!");
// 检测依赖交集并更新依赖ID
foreach (var patchAsset in patchManifest.AssetList)
{
List<string> dependBundles = GetPatchAssetAllDependBundles(patchManifest, patchAsset);
List<string> conflictAssetPathList = dependBundles.Intersect(shaderBundleReferenceList).ToList();
if (conflictAssetPathList.Count > 0)
{
List<int> newDependIDs = new List<int>(patchAsset.DependIDs);
if (newDependIDs.Contains(shaderBundleId) == false)
newDependIDs.Add(shaderBundleId);
patchAsset.DependIDs = newDependIDs.ToArray();
}
}
}
private List<string> GetPatchAssetAllDependBundles(PatchManifest patchManifest, PatchAsset patchAsset)
{
List<string> result = new List<string>();
string mainBundle = patchManifest.BundleList[patchAsset.BundleID].BundleName;
result.Add(mainBundle);
foreach (var dependID in patchAsset.DependIDs)
{
string dependBundle = patchManifest.BundleList[dependID].BundleName;
result.Add(dependBundle);
}
return result;
}
}
}

View File

@ -3,8 +3,8 @@ using System.Collections.Generic;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[TaskAttribute("制作")] [TaskAttribute("制作补丁包")]
public class TaskCreatePackage : IBuildTask public class TaskCreatePatchPackage : IBuildTask
{ {
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
@ -13,19 +13,19 @@ namespace YooAsset.Editor
var buildMode = buildParameters.Parameters.BuildMode; var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{ {
CopyPackageFiles(buildParameters, buildMapContext); CopyPatchFiles(buildParameters, buildMapContext);
} }
} }
/// <summary> /// <summary>
/// 拷贝补丁文件到补丁包目录 /// 拷贝补丁文件到补丁包目录
/// </summary> /// </summary>
private void CopyPackageFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) private void CopyPatchFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{ {
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
BuildLogger.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}"); BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}");
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{ {
@ -67,11 +67,11 @@ namespace YooAsset.Editor
// 拷贝所有补丁文件 // 拷贝所有补丁文件
int progressValue = 0; int progressValue = 0;
int fileTotalCount = buildMapContext.Collection.Count; int patchFileTotalCount = buildMapContext.BundleInfos.Count;
foreach (var bundleInfo in buildMapContext.Collection) foreach (var bundleInfo in buildMapContext.BundleInfos)
{ {
EditorTools.CopyFile(bundleInfo.PackageSourceFilePath, bundleInfo.PackageDestFilePath, true); EditorTools.CopyFile(bundleInfo.PatchInfo.BuildOutputFilePath, bundleInfo.PatchInfo.PatchOutputFilePath, true);
EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, fileTotalCount); EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
} }

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using UnityEditor; using UnityEditor;
namespace YooAsset.Editor namespace YooAsset.Editor
@ -13,21 +12,25 @@ namespace YooAsset.Editor
{ {
var buildParameters = context.GetContextObject<BuildParametersContext>(); var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
var manifestContext = context.GetContextObject<ManifestContext>(); var patchManifestContext = context.GetContextObject<PatchManifestContext>();
buildParameters.StopWatch();
var buildMode = buildParameters.Parameters.BuildMode; var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode != EBuildMode.SimulateBuild) if (buildMode != EBuildMode.SimulateBuild)
{ {
CreateReportFile(buildParameters, buildMapContext, manifestContext); CreateReportFile(buildParameters, buildMapContext, patchManifestContext);
} }
float buildSeconds = buildParameters.GetBuildingSeconds();
BuildRunner.Info($"Build time consuming {buildSeconds} seconds.");
} }
private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext, ManifestContext manifestContext) private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext, PatchManifestContext patchManifestContext)
{ {
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
PackageManifest manifest = manifestContext.Manifest; PatchManifest patchManifest = patchManifestContext.Manifest;
BuildReport buildReport = new BuildReport(); BuildReport buildReport = new BuildReport();
// 概述信息 // 概述信息
@ -39,18 +42,14 @@ namespace YooAsset.Editor
#endif #endif
buildReport.Summary.UnityVersion = UnityEngine.Application.unityVersion; buildReport.Summary.UnityVersion = UnityEngine.Application.unityVersion;
buildReport.Summary.BuildDate = DateTime.Now.ToString(); buildReport.Summary.BuildDate = DateTime.Now.ToString();
buildReport.Summary.BuildSeconds = BuildRunner.TotalSeconds; buildReport.Summary.BuildSeconds = (int)buildParametersContext.GetBuildingSeconds();
buildReport.Summary.BuildTarget = buildParameters.BuildTarget; buildReport.Summary.BuildTarget = buildParameters.BuildTarget;
buildReport.Summary.BuildPipeline = buildParameters.BuildPipeline; buildReport.Summary.BuildPipeline = buildParameters.BuildPipeline;
buildReport.Summary.BuildMode = buildParameters.BuildMode; buildReport.Summary.BuildMode = buildParameters.BuildMode;
buildReport.Summary.BuildPackageName = buildParameters.PackageName; buildReport.Summary.BuildPackageName = buildParameters.PackageName;
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion; buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
buildReport.Summary.EnableAddressable = buildMapContext.Command.EnableAddressable; buildReport.Summary.EnableAddressable = buildMapContext.EnableAddressable;
buildReport.Summary.LocationToLower = buildMapContext.Command.LocationToLower; buildReport.Summary.UniqueBundleName = buildMapContext.UniqueBundleName;
buildReport.Summary.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName;
buildReport.Summary.SharedPackRuleClassName = buildParameters.SharedPackRule == null ?
"null" : buildParameters.SharedPackRule.GetType().FullName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ? buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
"null" : buildParameters.EncryptionServices.GetType().FullName; "null" : buildParameters.EncryptionServices.GetType().FullName;
@ -62,69 +61,64 @@ namespace YooAsset.Editor
// 构建结果 // 构建结果
buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount; buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount;
buildReport.Summary.MainAssetTotalCount = GetMainAssetCount(manifest); buildReport.Summary.MainAssetTotalCount = GetMainAssetCount(patchManifest);
buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(manifest); buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(patchManifest);
buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(manifest); buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(patchManifest);
buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(manifest); buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(patchManifest);
buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(manifest); buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(patchManifest);
buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(manifest); buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(patchManifest);
buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(manifest); buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(patchManifest);
} }
// 资源对象列表 // 资源对象列表
buildReport.AssetInfos = new List<ReportAssetInfo>(manifest.AssetList.Count); buildReport.AssetInfos = new List<ReportAssetInfo>(patchManifest.AssetList.Count);
foreach (var packageAsset in manifest.AssetList) foreach (var patchAsset in patchManifest.AssetList)
{ {
var mainBundle = manifest.BundleList[packageAsset.BundleID]; var mainBundle = patchManifest.BundleList[patchAsset.BundleID];
ReportAssetInfo reportAssetInfo = new ReportAssetInfo(); ReportAssetInfo reportAssetInfo = new ReportAssetInfo();
reportAssetInfo.Address = packageAsset.Address; reportAssetInfo.Address = patchAsset.Address;
reportAssetInfo.AssetPath = packageAsset.AssetPath; reportAssetInfo.AssetPath = patchAsset.AssetPath;
reportAssetInfo.AssetTags = packageAsset.AssetTags; reportAssetInfo.AssetTags = patchAsset.AssetTags;
reportAssetInfo.AssetGUID = AssetDatabase.AssetPathToGUID(packageAsset.AssetPath); reportAssetInfo.AssetGUID = AssetDatabase.AssetPathToGUID(patchAsset.AssetPath);
reportAssetInfo.MainBundleName = mainBundle.BundleName; reportAssetInfo.MainBundleName = mainBundle.BundleName;
reportAssetInfo.MainBundleSize = mainBundle.FileSize; reportAssetInfo.MainBundleSize = mainBundle.FileSize;
reportAssetInfo.DependBundles = GetDependBundles(manifest, packageAsset); reportAssetInfo.DependBundles = GetDependBundles(patchManifest, patchAsset);
reportAssetInfo.DependAssets = GetDependAssets(buildMapContext, mainBundle.BundleName, packageAsset.AssetPath); reportAssetInfo.DependAssets = GetDependAssets(buildMapContext, mainBundle.BundleName, patchAsset.AssetPath);
buildReport.AssetInfos.Add(reportAssetInfo); buildReport.AssetInfos.Add(reportAssetInfo);
} }
// 资源包列表 // 资源包列表
buildReport.BundleInfos = new List<ReportBundleInfo>(manifest.BundleList.Count); buildReport.BundleInfos = new List<ReportBundleInfo>(patchManifest.BundleList.Count);
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
ReportBundleInfo reportBundleInfo = new ReportBundleInfo(); ReportBundleInfo reportBundleInfo = new ReportBundleInfo();
reportBundleInfo.BundleName = packageBundle.BundleName; reportBundleInfo.BundleName = patchBundle.BundleName;
reportBundleInfo.FileName = packageBundle.FileName; reportBundleInfo.FileName = patchBundle.FileName;
reportBundleInfo.FileHash = packageBundle.FileHash; reportBundleInfo.FileHash = patchBundle.FileHash;
reportBundleInfo.FileCRC = packageBundle.FileCRC; reportBundleInfo.FileCRC = patchBundle.FileCRC;
reportBundleInfo.FileSize = packageBundle.FileSize; reportBundleInfo.FileSize = patchBundle.FileSize;
reportBundleInfo.IsRawFile = packageBundle.IsRawFile; reportBundleInfo.Tags = patchBundle.Tags;
reportBundleInfo.LoadMethod = (EBundleLoadMethod)packageBundle.LoadMethod; reportBundleInfo.IsRawFile = patchBundle.IsRawFile;
reportBundleInfo.Tags = packageBundle.Tags; reportBundleInfo.LoadMethod = (EBundleLoadMethod)patchBundle.LoadMethod;
reportBundleInfo.ReferenceIDs = packageBundle.ReferenceIDs;
reportBundleInfo.AllBuiltinAssets = GetAllBuiltinAssets(buildMapContext, packageBundle.BundleName);
buildReport.BundleInfos.Add(reportBundleInfo); buildReport.BundleInfos.Add(reportBundleInfo);
} }
// 冗余资源列表
buildReport.RedundancyInfos = new List<ReportRedundancyInfo>(buildMapContext.RedundancyInfos);
// 序列化文件 // 序列化文件
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
BuildReport.Serialize(filePath, buildReport); BuildReport.Serialize(filePath, buildReport);
BuildLogger.Log($"资源构建报告文件创建完成:{filePath}"); BuildRunner.Log($"资源构建报告文件创建完成:{filePath}");
} }
/// <summary> /// <summary>
/// 获取资源对象依赖的所有资源包 /// 获取资源对象依赖的所有资源包
/// </summary> /// </summary>
private List<string> GetDependBundles(PackageManifest manifest, PackageAsset packageAsset) private List<string> GetDependBundles(PatchManifest patchManifest, PatchAsset patchAsset)
{ {
List<string> dependBundles = new List<string>(packageAsset.DependIDs.Length); List<string> dependBundles = new List<string>(patchAsset.DependIDs.Length);
foreach (int index in packageAsset.DependIDs) foreach (int index in patchAsset.DependIDs)
{ {
string dependBundleName = manifest.BundleList[index].BundleName; string dependBundleName = patchManifest.BundleList[index].BundleName;
dependBundles.Add(dependBundleName); dependBundles.Add(dependBundleName);
} }
return dependBundles; return dependBundles;
@ -136,14 +130,14 @@ namespace YooAsset.Editor
private List<string> GetDependAssets(BuildMapContext buildMapContext, string bundleName, string assetPath) private List<string> GetDependAssets(BuildMapContext buildMapContext, string bundleName, string assetPath)
{ {
List<string> result = new List<string>(); List<string> result = new List<string>();
var bundleInfo = buildMapContext.GetBundleInfo(bundleName); if (buildMapContext.TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo))
{ {
BuildAssetInfo findAssetInfo = null; BuildAssetInfo findAssetInfo = null;
foreach (var assetInfo in bundleInfo.AllMainAssets) foreach (var buildinAsset in bundleInfo.BuildinAssets)
{ {
if (assetInfo.AssetPath == assetPath) if (buildinAsset.AssetPath == assetPath)
{ {
findAssetInfo = assetInfo; findAssetInfo = buildinAsset;
break; break;
} }
} }
@ -156,72 +150,67 @@ namespace YooAsset.Editor
result.Add(dependAssetInfo.AssetPath); result.Add(dependAssetInfo.AssetPath);
} }
} }
else
{
throw new Exception($"Not found bundle : {bundleName}");
}
return result; return result;
} }
/// <summary> private int GetMainAssetCount(PatchManifest patchManifest)
/// 获取该资源包内的所有资源
/// </summary>
private List<string> GetAllBuiltinAssets(BuildMapContext buildMapContext, string bundleName)
{ {
var bundleInfo = buildMapContext.GetBundleInfo(bundleName); return patchManifest.AssetList.Count;
return bundleInfo.GetAllBuiltinAssetPaths();
} }
private int GetAllBundleCount(PatchManifest patchManifest)
private int GetMainAssetCount(PackageManifest manifest)
{ {
return manifest.AssetList.Count; return patchManifest.BundleList.Count;
} }
private int GetAllBundleCount(PackageManifest manifest) private long GetAllBundleSize(PatchManifest patchManifest)
{
return manifest.BundleList.Count;
}
private long GetAllBundleSize(PackageManifest manifest)
{ {
long fileBytes = 0; long fileBytes = 0;
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
fileBytes += packageBundle.FileSize; fileBytes += patchBundle.FileSize;
} }
return fileBytes; return fileBytes;
} }
private int GetEncryptedBundleCount(PackageManifest manifest) private int GetEncryptedBundleCount(PatchManifest patchManifest)
{ {
int fileCount = 0; int fileCount = 0;
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
if (packageBundle.LoadMethod != (byte)EBundleLoadMethod.Normal) if (patchBundle.LoadMethod != (byte)EBundleLoadMethod.Normal)
fileCount++; fileCount++;
} }
return fileCount; return fileCount;
} }
private long GetEncryptedBundleSize(PackageManifest manifest) private long GetEncryptedBundleSize(PatchManifest patchManifest)
{ {
long fileBytes = 0; long fileBytes = 0;
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
if (packageBundle.LoadMethod != (byte)EBundleLoadMethod.Normal) if (patchBundle.LoadMethod != (byte)EBundleLoadMethod.Normal)
fileBytes += packageBundle.FileSize; fileBytes += patchBundle.FileSize;
} }
return fileBytes; return fileBytes;
} }
private int GetRawBundleCount(PackageManifest manifest) private int GetRawBundleCount(PatchManifest patchManifest)
{ {
int fileCount = 0; int fileCount = 0;
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
if (packageBundle.IsRawFile) if (patchBundle.IsRawFile)
fileCount++; fileCount++;
} }
return fileCount; return fileCount;
} }
private long GetRawBundleSize(PackageManifest manifest) private long GetRawBundleSize(PatchManifest patchManifest)
{ {
long fileBytes = 0; long fileBytes = 0;
foreach (var packageBundle in manifest.BundleList) foreach (var patchBundle in patchManifest.BundleList)
{ {
if (packageBundle.IsRawFile) if (patchBundle.IsRawFile)
fileBytes += packageBundle.FileSize; fileBytes += patchBundle.FileSize;
} }
return fileBytes; return fileBytes;
} }

View File

@ -27,16 +27,17 @@ namespace YooAsset.Editor
private void EncryptingBundleFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) private void EncryptingBundleFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{ {
var encryptionServices = buildParametersContext.Parameters.EncryptionServices; var encryptionServices = buildParametersContext.Parameters.EncryptionServices;
if (encryptionServices == null)
return;
if (encryptionServices.GetType() == typeof(EncryptionNone)) // 如果没有设置加密类
if (encryptionServices == null)
return; return;
int progressValue = 0; int progressValue = 0;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.Collection) foreach (var bundleInfo in buildMapContext.BundleInfos)
{ {
bundleInfo.LoadMethod = EBundleLoadMethod.Normal;
EncryptFileInfo fileInfo = new EncryptFileInfo(); EncryptFileInfo fileInfo = new EncryptFileInfo();
fileInfo.BundleName = bundleInfo.BundleName; fileInfo.BundleName = bundleInfo.BundleName;
fileInfo.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; fileInfo.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
@ -47,19 +48,19 @@ namespace YooAsset.Editor
// 注意:原生文件不支持加密 // 注意:原生文件不支持加密
if (bundleInfo.IsRawFile) if (bundleInfo.IsRawFile)
{ {
BuildLogger.Warning($"Encryption not support raw file : {bundleInfo.BundleName}"); UnityEngine.Debug.LogWarning($"Encryption not support raw file : {bundleInfo.BundleName}");
continue; continue;
} }
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt"; string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt";
FileUtility.WriteAllBytes(filePath, encryptResult.EncryptedData); FileUtility.CreateFile(filePath, encryptResult.EncryptedData);
bundleInfo.EncryptedFilePath = filePath; bundleInfo.EncryptedFilePath = filePath;
bundleInfo.LoadMethod = encryptResult.LoadMethod; bundleInfo.LoadMethod = encryptResult.LoadMethod;
BuildLogger.Log($"Bundle文件加密完成{filePath}"); BuildRunner.Log($"Bundle文件加密完成{filePath}");
} }
// 进度条 // 进度条
EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.Collection.Count); EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.BundleInfos.Count);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
} }

View File

@ -13,206 +13,32 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = CreateBuildMap(buildParametersContext.Parameters); var buildMapContext = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.PackageName);
context.SetContextObject(buildMapContext); context.SetContextObject(buildMapContext);
BuildLogger.Log("构建内容准备完毕!"); BuildRunner.Log("构建内容准备完毕!");
// 检测构建结果 // 检测构建结果
CheckBuildMapContent(buildMapContext); CheckBuildMapContent(buildMapContext);
} }
/// <summary>
/// 资源构建上下文
/// </summary>
public BuildMapContext CreateBuildMap(BuildParameters buildParameters)
{
var buildMode = buildParameters.BuildMode;
var packageName = buildParameters.PackageName;
var sharedPackRule = buildParameters.SharedPackRule;
Dictionary<string, BuildAssetInfo> allBuildAssetInfoDic = new Dictionary<string, BuildAssetInfo>(1000);
// 1. 检测配置合法性
AssetBundleCollectorSettingData.Setting.CheckPackageConfigError(packageName);
// 2. 获取所有收集器收集的资源
var collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
List<CollectAssetInfo> allCollectAssetInfos = collectResult.CollectAssets;
// 3. 剔除未被引用的依赖项资源
RemoveZeroReferenceAssets(allCollectAssetInfos);
// 4. 录入所有收集器收集的资源
foreach (var collectAssetInfo in allCollectAssetInfos)
{
if (allBuildAssetInfoDic.ContainsKey(collectAssetInfo.AssetPath) == false)
{
var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName,
collectAssetInfo.Address, collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset);
buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags);
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
allBuildAssetInfoDic.Add(collectAssetInfo.AssetPath, buildAssetInfo);
}
else
{
throw new Exception($"Should never get here !");
}
}
// 5. 录入所有收集资源的依赖资源
foreach (var collectAssetInfo in allCollectAssetInfos)
{
string collectAssetBundleName = collectAssetInfo.BundleName;
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
{
if (allBuildAssetInfoDic.ContainsKey(dependAssetPath))
{
allBuildAssetInfoDic[dependAssetPath].AddBundleTags(collectAssetInfo.AssetTags);
allBuildAssetInfoDic[dependAssetPath].AddReferenceBundleName(collectAssetBundleName);
}
else
{
var buildAssetInfo = new BuildAssetInfo(dependAssetPath);
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
buildAssetInfo.AddReferenceBundleName(collectAssetBundleName);
allBuildAssetInfoDic.Add(dependAssetPath, buildAssetInfo);
}
}
}
// 6. 填充所有收集资源的依赖列表
foreach (var collectAssetInfo in allCollectAssetInfos)
{
var dependAssetInfos = new List<BuildAssetInfo>(collectAssetInfo.DependAssets.Count);
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
{
if (allBuildAssetInfoDic.TryGetValue(dependAssetPath, out BuildAssetInfo value))
dependAssetInfos.Add(value);
else
throw new Exception("Should never get here !");
}
allBuildAssetInfoDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos);
}
// 7. 记录关键信息
BuildMapContext context = new BuildMapContext();
context.AssetFileCount = allBuildAssetInfoDic.Count;
context.Command = collectResult.Command;
// 8. 计算共享资源的包名
var command = collectResult.Command;
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{
buildAssetInfo.CalculateShareBundleName(sharedPackRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
}
// 9. 记录冗余资源
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{
if (buildAssetInfo.IsRedundancyAsset())
{
var redundancyInfo = new ReportRedundancyInfo();
redundancyInfo.AssetPath = buildAssetInfo.AssetPath;
redundancyInfo.AssetType = AssetDatabase.GetMainAssetTypeAtPath(buildAssetInfo.AssetPath).Name;
redundancyInfo.AssetGUID = AssetDatabase.AssetPathToGUID(buildAssetInfo.AssetPath);
redundancyInfo.FileSize = FileUtility.GetFileSize(buildAssetInfo.AssetPath);
redundancyInfo.Number = buildAssetInfo.GetReferenceBundleCount();
context.RedundancyInfos.Add(redundancyInfo);
}
}
// 10. 移除不参与构建的资源
List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>();
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{
if (buildAssetInfo.HasBundleName() == false)
removeBuildList.Add(buildAssetInfo);
}
foreach (var removeValue in removeBuildList)
{
allBuildAssetInfoDic.Remove(removeValue.AssetPath);
}
// 11. 构建资源列表
var allPackAssets = allBuildAssetInfoDic.Values.ToList();
if (allPackAssets.Count == 0)
throw new Exception("构建的资源列表不能为空");
foreach (var assetInfo in allPackAssets)
{
context.PackAsset(assetInfo);
}
return context;
}
private void RemoveZeroReferenceAssets(List<CollectAssetInfo> allCollectAssetInfos)
{
// 1. 检测是否任何存在依赖资源
bool hasAnyDependCollector = false;
foreach (var collectAssetInfo in allCollectAssetInfos)
{
var collectorType = collectAssetInfo.CollectorType;
if (collectorType == ECollectorType.DependAssetCollector)
{
hasAnyDependCollector = true;
break;
}
}
if (hasAnyDependCollector == false)
return;
// 2. 获取所有主资源的依赖资源集合
HashSet<string> allDependAsset = new HashSet<string>();
foreach (var collectAssetInfo in allCollectAssetInfos)
{
var collectorType = collectAssetInfo.CollectorType;
if (collectorType == ECollectorType.MainAssetCollector || collectorType == ECollectorType.StaticAssetCollector)
{
foreach (var dependAsset in collectAssetInfo.DependAssets)
{
if (allDependAsset.Contains(dependAsset) == false)
allDependAsset.Add(dependAsset);
}
}
}
// 3. 找出所有零引用的依赖资源集合
List<CollectAssetInfo> removeList = new List<CollectAssetInfo>();
foreach (var collectAssetInfo in allCollectAssetInfos)
{
var collectorType = collectAssetInfo.CollectorType;
if (collectorType == ECollectorType.DependAssetCollector)
{
if (allDependAsset.Contains(collectAssetInfo.AssetPath) == false)
removeList.Add(collectAssetInfo);
}
}
// 4. 移除所有零引用的依赖资源
foreach (var removeValue in removeList)
{
BuildLogger.Log($"发现未被依赖的资源并自动移除 : {removeValue.AssetPath}");
allCollectAssetInfos.Remove(removeValue);
}
}
/// <summary> /// <summary>
/// 检测构建结果 /// 检测构建结果
/// </summary> /// </summary>
private void CheckBuildMapContent(BuildMapContext buildMapContext) private void CheckBuildMapContent(BuildMapContext buildMapContext)
{ {
foreach (var bundleInfo in buildMapContext.Collection) foreach (var bundleInfo in buildMapContext.BundleInfos)
{ {
// 注意:原生文件资源包只能包含一个原生文件 // 注意:原生文件资源包只能包含一个原生文件
bool isRawFile = bundleInfo.IsRawFile; bool isRawFile = bundleInfo.IsRawFile;
if (isRawFile) if (isRawFile)
{ {
if (bundleInfo.AllMainAssets.Count != 1) if (bundleInfo.BuildinAssets.Count != 1)
throw new Exception($"The bundle does not support multiple raw asset : {bundleInfo.BundleName}"); throw new Exception($"The bundle does not support multiple raw asset : {bundleInfo.BundleName}");
continue; continue;
} }
// 注意:原生文件不能被其它资源文件依赖 // 注意:原生文件不能被其它资源文件依赖
foreach (var assetInfo in bundleInfo.AllMainAssets) foreach (var assetInfo in bundleInfo.BuildinAssets)
{ {
if (assetInfo.AllDependAssetInfos != null) if (assetInfo.AllDependAssetInfos != null)
{ {

View File

@ -12,41 +12,20 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
buildParametersContext.BeginWatch();
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
// 检测构建参数合法性 // 检测构建参数合法性
if (buildParameters.BuildTarget == BuildTarget.NoTarget) if (buildParameters.BuildTarget == BuildTarget.NoTarget)
throw new Exception("请选择目标平台"); throw new Exception("请选择目标平台");
if (string.IsNullOrEmpty(buildParameters.PackageName)) if (string.IsNullOrEmpty(buildParameters.PackageName))
throw new Exception("包裹名称不能为空!"); throw new Exception("包裹名称不能为空");
if (string.IsNullOrEmpty(buildParameters.PackageVersion)) if(string.IsNullOrEmpty(buildParameters.PackageVersion))
throw new Exception("包裹版本不能为空!"); throw new Exception("包裹版本不能为空");
if (string.IsNullOrEmpty(buildParameters.BuildOutputRoot))
throw new Exception("构建输出的根目录为空!");
if (string.IsNullOrEmpty(buildParameters.StreamingAssetsRoot))
throw new Exception("内置资源根目录为空!");
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
if (buildParameters.SBPParameters == null)
throw new Exception($"{nameof(BuildParameters.SBPParameters)} is null !");
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");
}
if (buildParameters.BuildMode != EBuildMode.SimulateBuild) if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
{ {
#if UNITY_2021_3_OR_NEWER
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
BuildLogger.Warning("推荐使用可编程构建管线SBP");
}
#endif
// 检测当前是否正在构建资源包 // 检测当前是否正在构建资源包
if (BuildPipeline.isBuildingPlayer) if (BuildPipeline.isBuildingPlayer)
throw new Exception("当前正在构建资源包,请结束后再试"); throw new Exception("当前正在构建资源包,请结束后再试");
@ -63,20 +42,6 @@ namespace YooAsset.Editor
throw new Exception("首包资源标签不能为空!"); throw new Exception("首包资源标签不能为空!");
} }
// 检测共享资源打包规则
if (buildParameters.SharedPackRule == null)
throw new Exception("共享资源打包规则不能为空!");
#if UNITY_WEBGL
if (buildParameters.EncryptionServices != null)
{
if (buildParameters.EncryptionServices.GetType() != typeof(EncryptionNone))
{
throw new Exception("WebGL平台不支持加密");
}
}
#endif
// 检测包裹输出目录是否存在 // 检测包裹输出目录是否存在
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
if (Directory.Exists(packageOutputDirectory)) if (Directory.Exists(packageOutputDirectory))
@ -88,10 +53,11 @@ namespace YooAsset.Editor
if (buildParameters.BuildMode == EBuildMode.ForceRebuild) if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{ {
string packageRootDirectory = buildParametersContext.GetPackageRootDirectory(); // 删除平台总目录
if (EditorTools.DeleteDirectory(packageRootDirectory)) string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.PackageName}/{buildParameters.BuildTarget}";
if (EditorTools.DeleteDirectory(platformDirectory))
{ {
BuildLogger.Log($"删除包裹目录:{packageRootDirectory}"); BuildRunner.Log($"删除平台总目录:{platformDirectory}");
} }
} }
@ -99,7 +65,7 @@ namespace YooAsset.Editor
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
if (EditorTools.CreateDirectory(pipelineOutputDirectory)) if (EditorTools.CreateDirectory(pipelineOutputDirectory))
{ {
BuildLogger.Log($"创建输出目录:{pipelineOutputDirectory}"); BuildRunner.Log($"创建输出目录:{pipelineOutputDirectory}");
} }
} }
} }

View File

@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace YooAsset.Editor
{
[TaskAttribute("更新构建信息")]
public class TaskUpdateBuildInfo : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle;
// 1.检测路径长度
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
// NOTE检测路径长度不要超过260字符。
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
if (filePath.Length >= 260)
throw new Exception($"The output bundle name is too long {filePath.Length} chars : {filePath}");
}
// 2.更新构建输出的文件路径
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsEncryptedFile)
bundleInfo.PatchInfo.BuildOutputFilePath = bundleInfo.EncryptedFilePath;
else
bundleInfo.PatchInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
}
// 3.更新文件其它信息
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
string buildOutputFilePath = bundleInfo.PatchInfo.BuildOutputFilePath;
bundleInfo.PatchInfo.ContentHash = GetBundleContentHash(bundleInfo, context);
bundleInfo.PatchInfo.PatchFileHash = GetBundleFileHash(buildOutputFilePath, buildParametersContext);
bundleInfo.PatchInfo.PatchFileCRC = GetBundleFileCRC(buildOutputFilePath, buildParametersContext);
bundleInfo.PatchInfo.PatchFileSize = GetBundleFileSize(buildOutputFilePath, buildParametersContext);
}
// 4.更新补丁包输出的文件路径
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
string patchFileName = PatchManifest.CreateBundleFileName(outputNameStyle, bundleInfo.BundleName, bundleInfo.PatchInfo.PatchFileHash);
bundleInfo.PatchInfo.PatchOutputFilePath = $"{packageOutputDirectory}/{patchFileName}";
}
}
private string GetBundleContentHash(BuildBundleInfo bundleInfo, BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
if (bundleInfo.IsRawFile)
{
string filePath = bundleInfo.PatchInfo.BuildOutputFilePath;
return HashUtility.FileMD5(filePath);
}
if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
var buildResult = context.GetContextObject<TaskBuilding.BuildResultContext>();
var hash = buildResult.UnityManifest.GetAssetBundleHash(bundleInfo.BundleName);
if (hash.isValid)
return hash.ToString();
else
throw new Exception($"Not found bundle in build result : {bundleInfo.BundleName}");
}
else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
// 注意当资源包的依赖列表发生变化的时候ContentHash也会发生变化
var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
return value.Hash.ToString();
else
throw new Exception($"Not found bundle in build result : {bundleInfo.BundleName}");
}
else
{
throw new System.NotImplementedException();
}
}
private string GetBundleFileHash(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
else
return HashUtility.FileMD5(filePath);
}
private string GetBundleFileCRC(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000"; //8位
else
return HashUtility.FileCRC32(filePath);
}
private long GetBundleFileSize(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return 0;
else
return FileUtility.GetFileSize(filePath);
}
}
}

View File

@ -1,182 +0,0 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace YooAsset.Editor
{
[TaskAttribute("更新资源包信息")]
public class TaskUpdateBundleInfo : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle;
// 1.检测文件名长度
foreach (var bundleInfo in buildMapContext.Collection)
{
// NOTE检测文件名长度不要超过260字符。
string fileName = bundleInfo.BundleName;
if (fileName.Length >= 260)
throw new Exception($"The output bundle name is too long {fileName.Length} chars : {fileName}");
}
// 2.更新构建输出的文件路径
foreach (var bundleInfo in buildMapContext.Collection)
{
bundleInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
if (bundleInfo.IsEncryptedFile)
bundleInfo.PackageSourceFilePath = bundleInfo.EncryptedFilePath;
else
bundleInfo.PackageSourceFilePath = bundleInfo.BuildOutputFilePath;
}
// 3.更新文件其它信息
foreach (var bundleInfo in buildMapContext.Collection)
{
bundleInfo.PackageUnityHash = GetUnityHash(bundleInfo, context);
bundleInfo.PackageUnityCRC = GetUnityCRC(bundleInfo, context);
bundleInfo.PackageFileHash = GetBundleFileHash(bundleInfo.PackageSourceFilePath, buildParametersContext);
bundleInfo.PackageFileCRC = GetBundleFileCRC(bundleInfo.PackageSourceFilePath, buildParametersContext);
bundleInfo.PackageFileSize = GetBundleFileSize(bundleInfo.PackageSourceFilePath, buildParametersContext);
}
// 4.更新补丁包输出的文件路径
foreach (var bundleInfo in buildMapContext.Collection)
{
string bundleName = bundleInfo.BundleName;
string fileHash = bundleInfo.PackageFileHash;
string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleName);
string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash);
bundleInfo.PackageDestFilePath = $"{packageOutputDirectory}/{fileName}";
}
}
private string GetUnityHash(BuildBundleInfo bundleInfo, BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
if (bundleInfo.IsRawFile)
{
string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileMD5(filePath);
}
if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
var buildResult = context.GetContextObject<TaskBuilding.BuildResultContext>();
var hash = buildResult.UnityManifest.GetAssetBundleHash(bundleInfo.BundleName);
if (hash.isValid)
return hash.ToString();
else
throw new Exception($"Not found bundle hash in build result : {bundleInfo.BundleName}");
}
else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
// 注意当资源包的依赖列表发生变化的时候ContentHash也会发生变化
var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
return value.Hash.ToString();
else
throw new Exception($"Not found bundle hash in build result : {bundleInfo.BundleName}");
}
else
{
throw new System.NotImplementedException();
}
}
private uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return 0;
if (bundleInfo.IsRawFile)
return 0;
if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
string filePath = bundleInfo.BuildOutputFilePath;
if (BuildPipeline.GetCRCForAssetBundle(filePath, out uint crc))
return crc;
else
throw new Exception($"Not found bundle crc in build result : {bundleInfo.BundleName}");
}
else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
return value.Crc;
else
throw new Exception($"Not found bundle crc in build result : {bundleInfo.BundleName}");
}
else
{
throw new System.NotImplementedException();
}
}
private string GetBundleFileHash(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return GetFilePathTempHash(filePath);
else
return HashUtility.FileMD5(filePath);
}
private string GetBundleFileCRC(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000"; //8位
else
return HashUtility.FileCRC32(filePath);
}
private long GetBundleFileSize(string filePath, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return 0;
else
return FileUtility.GetFileSize(filePath);
}
protected string GetFilePathTempHash(string filePath)
{
byte[] bytes = Encoding.UTF8.GetBytes(filePath);
return HashUtility.BytesMD5(bytes);
// 注意:在文件路径的哈希值冲突的情况下,可以使用下面的方法
//return $"{HashUtility.BytesMD5(bytes)}-{Guid.NewGuid():N}";
}
protected long GetBundleTempSize(BuildBundleInfo bundleInfo)
{
long tempSize = 0;
var assetPaths = bundleInfo.GetAllMainAssetPaths();
foreach (var assetPath in assetPaths)
{
long size = FileUtility.GetFileSize(assetPath);
tempSize += size;
}
if (tempSize == 0)
{
string message = $"Bundle temp size is zero, check bundle main asset list : {bundleInfo.BundleName}";
throw new Exception(message);
}
return tempSize;
}
}
}

View File

@ -34,29 +34,29 @@ namespace YooAsset.Editor
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
string[] unityCreateBundles = unityManifest.GetAllAssetBundles(); string[] buildedBundles = unityManifest.GetAllAssetBundles();
// 1. 过滤掉原生Bundle // 1. 过滤掉原生Bundle
string[] mapBundles = buildMapContext.Collection.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToArray(); string[] mapBundles = buildMapContext.BundleInfos.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToArray();
// 2. 验证Bundle // 2. 验证Bundle
List<string> exceptBundleList1 = unityCreateBundles.Except(mapBundles).ToList(); List<string> exceptBundleList1 = buildedBundles.Except(mapBundles).ToList();
if (exceptBundleList1.Count > 0) if (exceptBundleList1.Count > 0)
{ {
foreach (var exceptBundle in exceptBundleList1) foreach (var exceptBundle in exceptBundleList1)
{ {
BuildLogger.Warning($"差异资源包: {exceptBundle}"); Debug.LogWarning($"差异资源包: {exceptBundle}");
} }
throw new System.Exception("存在差异资源包!请查看警告信息!"); throw new System.Exception("存在差异资源包!请查看警告信息!");
} }
// 3. 验证Bundle // 3. 验证Bundle
List<string> exceptBundleList2 = mapBundles.Except(unityCreateBundles).ToList(); List<string> exceptBundleList2 = mapBundles.Except(buildedBundles).ToList();
if (exceptBundleList2.Count > 0) if (exceptBundleList2.Count > 0)
{ {
foreach (var exceptBundle in exceptBundleList2) foreach (var exceptBundle in exceptBundleList2)
{ {
BuildLogger.Warning($"差异资源包: {exceptBundle}"); Debug.LogWarning($"差异资源包: {exceptBundle}");
} }
throw new System.Exception("存在差异资源包!请查看警告信息!"); throw new System.Exception("存在差异资源包!请查看警告信息!");
} }
@ -76,16 +76,16 @@ namespace YooAsset.Editor
string[] mapAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle); string[] mapAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
if (mapAssetPaths.Length != buildedAssetPaths.Length) if (mapAssetPaths.Length != buildedAssetPaths.Length)
{ {
BuildLogger.Warning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}"); Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
var exceptAssetList1 = mapAssetPaths.Except(buildedAssetPaths).ToList(); var exceptAssetList1 = mapAssetPaths.Except(buildedAssetPaths).ToList();
foreach (var excpetAsset in exceptAssetList1) foreach (var excpetAsset in exceptAssetList1)
{ {
BuildLogger.Warning($"构建失败的资源对象路径为 : {excpetAsset}"); Debug.LogWarning($"构建失败的资源对象路径为 : {excpetAsset}");
} }
var exceptAssetList2 = buildedAssetPaths.Except(mapAssetPaths).ToList(); var exceptAssetList2 = buildedAssetPaths.Except(mapAssetPaths).ToList();
foreach (var excpetAsset in exceptAssetList2) foreach (var excpetAsset in exceptAssetList2)
{ {
BuildLogger.Warning($"构建失败的资源对象路径为 : {excpetAsset}"); Debug.LogWarning($"构建失败的资源对象路径为 : {excpetAsset}");
} }
isPass = false; isPass = false;
continue; continue;
@ -101,7 +101,7 @@ namespace YooAsset.Editor
} }
*/ */
BuildLogger.Log("构建结果验证成功!"); BuildRunner.Log("构建结果验证成功!");
} }
/// <summary> /// <summary>

View File

@ -35,34 +35,34 @@ namespace YooAsset.Editor
{ {
var buildParameters = context.GetContextObject<BuildParametersContext>(); var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
List<string> unityCreateBundles = buildResults.BundleInfos.Keys.ToList(); List<string> buildedBundles = buildResults.BundleInfos.Keys.ToList();
// 1. 过滤掉原生Bundle // 1. 过滤掉原生Bundle
List<string> expectBundles = buildMapContext.Collection.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToList(); List<string> expectBundles = buildMapContext.BundleInfos.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToList();
// 2. 验证Bundle // 2. 验证Bundle
List<string> exceptBundleList1 = unityCreateBundles.Except(expectBundles).ToList(); List<string> exceptBundleList1 = buildedBundles.Except(expectBundles).ToList();
if (exceptBundleList1.Count > 0) if (exceptBundleList1.Count > 0)
{ {
foreach (var exceptBundle in exceptBundleList1) foreach (var exceptBundle in exceptBundleList1)
{ {
BuildLogger.Warning($"差异资源包: {exceptBundle}"); Debug.LogWarning($"差异资源包: {exceptBundle}");
} }
throw new System.Exception("存在差异资源包!请查看警告信息!"); throw new System.Exception("存在差异资源包!请查看警告信息!");
} }
// 3. 验证Bundle // 3. 验证Bundle
List<string> exceptBundleList2 = expectBundles.Except(unityCreateBundles).ToList(); List<string> exceptBundleList2 = expectBundles.Except(buildedBundles).ToList();
if (exceptBundleList2.Count > 0) if (exceptBundleList2.Count > 0)
{ {
foreach (var exceptBundle in exceptBundleList2) foreach (var exceptBundle in exceptBundleList2)
{ {
BuildLogger.Warning($"差异资源包: {exceptBundle}"); Debug.LogWarning($"差异资源包: {exceptBundle}");
} }
throw new System.Exception("存在差异资源包!请查看警告信息!"); throw new System.Exception("存在差异资源包!请查看警告信息!");
} }
BuildLogger.Log("构建结果验证成功!"); BuildRunner.Log("构建结果验证成功!");
} }
} }
} }

View File

@ -1,11 +0,0 @@

namespace YooAsset.Editor
{
public class EncryptionNone : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
throw new System.NotImplementedException();
}
}
}

View File

@ -7,13 +7,23 @@ namespace YooAsset.Editor
public enum EOutputNameStyle public enum EOutputNameStyle
{ {
/// <summary> /// <summary>
/// 哈希值名称 /// 000000000000000f000000000000000
/// </summary> /// </summary>
HashName = 1, HashName = 1,
/// <summary> /// <summary>
/// 资源包名称 + 哈希值名称 /// 000000000000000f000000000000000.bundle
/// </summary> /// </summary>
BundleName_HashName = 4, HashName_Extension = 2,
/// <summary>
/// bundle_name_000000000000000f000000000000000
/// </summary>
BundleName_HashName = 3,
/// <summary>
/// bundle_name_000000000000000f000000000000000.bundle
/// </summary>
BundleName_HashName_Extension = 4,
} }
} }

View File

@ -45,11 +45,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string AssetTags = string.Empty; public string AssetTags = string.Empty;
/// <summary>
/// 用户自定义数据
/// </summary>
public string UserData = string.Empty;
/// <summary> /// <summary>
/// 收集器是否有效 /// 收集器是否有效
@ -147,14 +142,11 @@ namespace YooAsset.Editor
} }
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(1000); Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(1000);
bool isRawAsset = PackRuleName == nameof(PackRawFile);
// 检测是否为原生资源打包规则
IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName);
bool isRawFilePackRule = packRuleInstance.IsRawFilePackRule();
// 检测原生资源包的收集器类型 // 检测原生资源包的收集器类型
if (isRawFilePackRule && CollectorType != ECollectorType.MainAssetCollector) if (isRawAsset && CollectorType != ECollectorType.MainAssetCollector)
throw new Exception($"The raw file pack rule must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}"); throw new Exception($"The raw file must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}");
if (string.IsNullOrEmpty(CollectPath)) if (string.IsNullOrEmpty(CollectPath))
throw new Exception($"The collect path is null or empty in group : {group.GroupName}"); throw new Exception($"The collect path is null or empty in group : {group.GroupName}");
@ -166,11 +158,11 @@ namespace YooAsset.Editor
string[] findAssets = EditorTools.FindAssets(EAssetSearchType.All, collectDirectory); string[] findAssets = EditorTools.FindAssets(EAssetSearchType.All, collectDirectory);
foreach (string assetPath in findAssets) foreach (string assetPath in findAssets)
{ {
if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(group, assetPath)) if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
{ {
if (result.ContainsKey(assetPath) == false) if (result.ContainsKey(assetPath) == false)
{ {
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule); var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset);
result.Add(assetPath, collectAssetInfo); result.Add(assetPath, collectAssetInfo);
} }
else else
@ -183,9 +175,9 @@ namespace YooAsset.Editor
else else
{ {
string assetPath = CollectPath; string assetPath = CollectPath;
if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(group, assetPath)) if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
{ {
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule); var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset);
result.Add(assetPath, collectAssetInfo); result.Add(assetPath, collectAssetInfo);
} }
else else
@ -197,23 +189,16 @@ namespace YooAsset.Editor
// 检测可寻址地址是否重复 // 检测可寻址地址是否重复
if (command.EnableAddressable) if (command.EnableAddressable)
{ {
var addressTemper = new Dictionary<string, string>(); HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result) foreach (var collectInfoPair in result)
{ {
if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector) if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector)
{ {
string address = collectInfoPair.Value.Address; string address = collectInfoPair.Value.Address;
string assetPath = collectInfoPair.Value.AssetPath; if (adressTemper.Contains(address) == false)
if (string.IsNullOrEmpty(address)) adressTemper.Add(address);
continue;
if (address.StartsWith("Assets/") || address.StartsWith("assets/"))
throw new Exception($"The address can not set asset path in collector : {CollectPath} \nAssetPath: {assetPath}");
if (addressTemper.TryGetValue(address, out var existed) == false)
addressTemper.Add(address, assetPath);
else else
throw new Exception($"The address is existed : {address} in collector : {CollectPath} \nAssetPath:\n {existed}\n {assetPath}"); throw new Exception($"The address is existed : {address} in collector : {CollectPath}");
} }
} }
} }
@ -222,12 +207,12 @@ namespace YooAsset.Editor
return result.Values.ToList(); return result.Values.ToList();
} }
private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawFilePackRule) private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawAsset)
{ {
string address = GetAddress(command, group, assetPath); string address = GetAddress(group, assetPath);
string bundleName = GetBundleName(command, group, assetPath); string bundleName = GetBundleName(group, assetPath);
List<string> assetTags = GetAssetTags(group); List<string> assetTags = GetAssetTags(group);
CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, isRawFilePackRule, assetTags); CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, assetTags, isRawAsset);
// 注意:模拟构建模式下不需要收集依赖资源 // 注意:模拟构建模式下不需要收集依赖资源
if (command.BuildMode == EBuildMode.SimulateBuild) if (command.BuildMode == EBuildMode.SimulateBuild)
@ -237,7 +222,7 @@ namespace YooAsset.Editor
return collectAssetInfo; return collectAssetInfo;
} }
private bool IsValidateAsset(string assetPath, bool isRawFilePackRule) private bool IsValidateAsset(string assetPath)
{ {
if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false) if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false)
{ {
@ -250,38 +235,15 @@ namespace YooAsset.Editor
return false; return false;
// 忽略编辑器下的类型资源 // 忽略编辑器下的类型资源
Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); Type type = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(LightingDataAsset) || assetType == typeof(LightmapParameters)) if (type == typeof(LightingDataAsset))
return false; return false;
// 检测原生文件是否合规 // 忽略Unity无法识别的无效文件
if (isRawFilePackRule) // 注意:只对非原生文件收集器处理
if(PackRuleName != nameof(PackRawFile))
{ {
string extension = EditorTools.RemoveFirstChar(System.IO.Path.GetExtension(assetPath)); if (type == typeof(UnityEditor.DefaultAsset))
if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() ||
extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.mat.ToString() ||
extension == EAssetFileExtension.controller.ToString() || extension == EAssetFileExtension.anim.ToString() ||
extension == EAssetFileExtension.ttf.ToString() || extension == EAssetFileExtension.shader.ToString())
{
UnityEngine.Debug.LogWarning($"Raw file pack rule can not support file estension : {extension}");
return false;
}
// 注意:原生文件只支持无依赖关系的资源
/*
string[] depends = AssetDatabase.GetDependencies(assetPath, true);
if (depends.Length != 1)
{
UnityEngine.Debug.LogWarning($"Raw file pack rule can not support estension : {extension}");
return false;
}
*/
}
else
{
// 忽略Unity无法识别的无效文件
// 注意:只对非原生文件收集器处理
if (assetType == typeof(UnityEditor.DefaultAsset))
{ {
UnityEngine.Debug.LogWarning($"Cannot pack default asset : {assetPath}"); UnityEngine.Debug.LogWarning($"Cannot pack default asset : {assetPath}");
return false; return false;
@ -289,66 +251,68 @@ namespace YooAsset.Editor
} }
string fileExtension = System.IO.Path.GetExtension(assetPath); string fileExtension = System.IO.Path.GetExtension(assetPath);
if (DefaultFilterRule.IsIgnoreFile(fileExtension)) if (IsIgnoreFile(fileExtension))
return false; return false;
return true; return true;
} }
private bool IsCollectAsset(AssetBundleCollectorGroup group, string assetPath) private bool IsIgnoreFile(string fileExtension)
{ {
foreach (var extension in YooAssetSettings.IgnoreFileExtensions)
{
if (extension == fileExtension)
return true;
}
return false;
}
private bool IsCollectAsset(string assetPath)
{
Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
return true;
// 根据规则设置过滤资源文件 // 根据规则设置过滤资源文件
IFilterRule filterRuleInstance = AssetBundleCollectorSettingData.GetFilterRuleInstance(FilterRuleName); IFilterRule filterRuleInstance = AssetBundleCollectorSettingData.GetFilterRuleInstance(FilterRuleName);
return filterRuleInstance.IsCollectAsset(new FilterRuleData(assetPath, CollectPath, group.GroupName, UserData)); return filterRuleInstance.IsCollectAsset(new FilterRuleData(assetPath));
} }
private string GetAddress(CollectCommand command, AssetBundleCollectorGroup group, string assetPath) private string GetAddress(AssetBundleCollectorGroup group, string assetPath)
{ {
if (command.EnableAddressable == false)
return string.Empty;
if (CollectorType != ECollectorType.MainAssetCollector) if (CollectorType != ECollectorType.MainAssetCollector)
return string.Empty; return string.Empty;
IAddressRule addressRuleInstance = AssetBundleCollectorSettingData.GetAddressRuleInstance(AddressRuleName); IAddressRule addressRuleInstance = AssetBundleCollectorSettingData.GetAddressRuleInstance(AddressRuleName);
string adressValue = addressRuleInstance.GetAssetAddress(new AddressRuleData(assetPath, CollectPath, group.GroupName, UserData)); string adressValue = addressRuleInstance.GetAssetAddress(new AddressRuleData(assetPath, CollectPath, group.GroupName));
return adressValue; return adressValue;
} }
private string GetBundleName(CollectCommand command, AssetBundleCollectorGroup group, string assetPath) private string GetBundleName(AssetBundleCollectorGroup group, string assetPath)
{ {
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection)) if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
{ return EditorTools.GetRegularPath(YooAssetSettings.UnityShadersBundleName).ToLower();
// 获取着色器打包规则结果
PackRuleResult packRuleResult = DefaultPackRule.CreateShadersPackRuleResult(); // 根据规则设置获取资源包名称
return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName); IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName);
} string bundleName = packRuleInstance.GetBundleName(new PackRuleData(assetPath, CollectPath, group.GroupName));
else return EditorTools.GetRegularPath(bundleName).ToLower();
{
// 获取其它资源打包规则结果
IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName);
PackRuleResult packRuleResult = packRuleInstance.GetPackRuleResult(new PackRuleData(assetPath, CollectPath, group.GroupName, UserData));
return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName);
}
} }
private List<string> GetAssetTags(AssetBundleCollectorGroup group) private List<string> GetAssetTags(AssetBundleCollectorGroup group)
{ {
List<string> tags = EditorTools.StringToStringList(group.AssetTags, ';'); List<string> tags = StringUtility.StringToStringList(group.AssetTags, ';');
List<string> temper = EditorTools.StringToStringList(AssetTags, ';'); List<string> temper = StringUtility.StringToStringList(AssetTags, ';');
tags.AddRange(temper); tags.AddRange(temper);
return tags; return tags;
} }
private List<string> GetAllDependencies(string mainAssetPath) private List<string> GetAllDependencies(string mainAssetPath)
{ {
List<string> result = new List<string>();
string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true); string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true);
List<string> result = new List<string>(depends.Length);
foreach (string assetPath in depends) foreach (string assetPath in depends)
{ {
// 注意:排除主资源对象 if (IsValidateAsset(assetPath))
if (assetPath == mainAssetPath)
continue;
if (IsValidateAsset(assetPath, false))
{ {
result.Add(assetPath); // 注意:排除主资源对象
if (assetPath != mainAssetPath)
result.Add(assetPath);
} }
} }
return result; return result;

View File

@ -10,23 +10,19 @@ namespace YooAsset.Editor
{ {
public class AssetBundleCollectorConfig public class AssetBundleCollectorConfig
{ {
public const string ConfigVersion = "2.4"; public const string ConfigVersion = "2.1";
public const string XmlVersion = "Version"; public const string XmlVersion = "Version";
public const string XmlCommon = "Common"; public const string XmlCommon = "Common";
public const string XmlEnableAddressable = "AutoAddressable"; public const string XmlEnableAddressable = "AutoAddressable";
public const string XmlLocationToLower = "LocationToLower";
public const string XmlIncludeAssetGUID = "IncludeAssetGUID";
public const string XmlUniqueBundleName = "UniqueBundleName"; public const string XmlUniqueBundleName = "UniqueBundleName";
public const string XmlShowPackageView = "ShowPackageView"; public const string XmlShowPackageView = "ShowPackageView";
public const string XmlShowEditorAlias = "ShowEditorAlias";
public const string XmlPackage = "Package"; public const string XmlPackage = "Package";
public const string XmlPackageName = "PackageName"; public const string XmlPackageName = "PackageName";
public const string XmlPackageDesc = "PackageDesc"; public const string XmlPackageDesc = "PackageDesc";
public const string XmlGroup = "Group"; public const string XmlGroup = "Group";
public const string XmlGroupActiveRule = "GroupActiveRule";
public const string XmlGroupName = "GroupName"; public const string XmlGroupName = "GroupName";
public const string XmlGroupDesc = "GroupDesc"; public const string XmlGroupDesc = "GroupDesc";
@ -37,7 +33,6 @@ namespace YooAsset.Editor
public const string XmlAddressRule = "AddressRule"; public const string XmlAddressRule = "AddressRule";
public const string XmlPackRule = "PackRule"; public const string XmlPackRule = "PackRule";
public const string XmlFilterRule = "FilterRule"; public const string XmlFilterRule = "FilterRule";
public const string XmlUserData = "UserData";
public const string XmlAssetTags = "AssetTags"; public const string XmlAssetTags = "AssetTags";
/// <summary> /// <summary>
@ -68,27 +63,22 @@ namespace YooAsset.Editor
// 读取公共配置 // 读取公共配置
bool enableAddressable = false; bool enableAddressable = false;
bool locationToLower = false;
bool includeAssetGUID = false;
bool uniqueBundleName = false; bool uniqueBundleName = false;
bool showPackageView = false; bool showPackageView = false;
bool showEditorAlias = false;
var commonNodeList = root.GetElementsByTagName(XmlCommon); var commonNodeList = root.GetElementsByTagName(XmlCommon);
if (commonNodeList.Count > 0) if (commonNodeList.Count > 0)
{ {
XmlElement commonElement = commonNodeList[0] as XmlElement; XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlEnableAddressable)) if (commonElement.HasAttribute(XmlEnableAddressable) == false)
enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false; throw new Exception($"Not found attribute {XmlEnableAddressable} in {XmlCommon}");
if (commonElement.HasAttribute(XmlLocationToLower)) if (commonElement.HasAttribute(XmlUniqueBundleName) == false)
locationToLower = commonElement.GetAttribute(XmlLocationToLower) == "True" ? true : false; throw new Exception($"Not found attribute {XmlUniqueBundleName} in {XmlCommon}");
if (commonElement.HasAttribute(XmlIncludeAssetGUID)) if (commonElement.HasAttribute(XmlShowPackageView) == false)
includeAssetGUID = commonElement.GetAttribute(XmlIncludeAssetGUID) == "True" ? true : false; throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}");
if (commonElement.HasAttribute(XmlUniqueBundleName))
uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false; enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
if (commonElement.HasAttribute(XmlShowPackageView)) uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false;
showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false; showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false;
if (commonElement.HasAttribute(XmlShowEditorAlias))
showEditorAlias = commonElement.GetAttribute(XmlShowEditorAlias) == "True" ? true : false;
} }
// 读取包裹配置 // 读取包裹配置
@ -112,8 +102,6 @@ namespace YooAsset.Editor
foreach (var groupNode in groupNodeList) foreach (var groupNode in groupNodeList)
{ {
XmlElement groupElement = groupNode as XmlElement; XmlElement groupElement = groupNode as XmlElement;
if (groupElement.HasAttribute(XmlGroupActiveRule) == false)
throw new Exception($"Not found attribute {XmlGroupActiveRule} in {XmlGroup}");
if (groupElement.HasAttribute(XmlGroupName) == false) if (groupElement.HasAttribute(XmlGroupName) == false)
throw new Exception($"Not found attribute {XmlGroupName} in {XmlGroup}"); throw new Exception($"Not found attribute {XmlGroupName} in {XmlGroup}");
if (groupElement.HasAttribute(XmlGroupDesc) == false) if (groupElement.HasAttribute(XmlGroupDesc) == false)
@ -122,7 +110,6 @@ namespace YooAsset.Editor
throw new Exception($"Not found attribute {XmlAssetTags} in {XmlGroup}"); throw new Exception($"Not found attribute {XmlAssetTags} in {XmlGroup}");
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup(); AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
group.ActiveRuleName = groupElement.GetAttribute(XmlGroupActiveRule);
group.GroupName = groupElement.GetAttribute(XmlGroupName); group.GroupName = groupElement.GetAttribute(XmlGroupName);
group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc); group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc);
group.AssetTags = groupElement.GetAttribute(XmlAssetTags); group.AssetTags = groupElement.GetAttribute(XmlAssetTags);
@ -145,39 +132,27 @@ namespace YooAsset.Editor
throw new Exception($"Not found attribute {XmlPackRule} in {XmlCollector}"); throw new Exception($"Not found attribute {XmlPackRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlFilterRule) == false) if (collectorElement.HasAttribute(XmlFilterRule) == false)
throw new Exception($"Not found attribute {XmlFilterRule} in {XmlCollector}"); throw new Exception($"Not found attribute {XmlFilterRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlUserData) == false)
throw new Exception($"Not found attribute {XmlUserData} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlAssetTags) == false) if (collectorElement.HasAttribute(XmlAssetTags) == false)
throw new Exception($"Not found attribute {XmlAssetTags} in {XmlCollector}"); throw new Exception($"Not found attribute {XmlAssetTags} in {XmlCollector}");
AssetBundleCollector collector = new AssetBundleCollector(); AssetBundleCollector collector = new AssetBundleCollector();
collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath); collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath);
collector.CollectorGUID = collectorElement.GetAttribute(XmlCollectorGUID); collector.CollectorGUID = collectorElement.GetAttribute(XmlCollectorGUID);
collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType)); collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType));
collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule); collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule);
collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule); collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule);
collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule); collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule);
collector.UserData = collectorElement.GetAttribute(XmlUserData);
collector.AssetTags = collectorElement.GetAttribute(XmlAssetTags); collector.AssetTags = collectorElement.GetAttribute(XmlAssetTags);
group.Collectors.Add(collector); group.Collectors.Add(collector);
} }
} }
} }
// 检测配置错误
foreach (var package in packages)
{
package.CheckConfigError();
}
// 保存配置数据 // 保存配置数据
AssetBundleCollectorSettingData.ClearAll(); AssetBundleCollectorSettingData.ClearAll();
AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable; AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable;
AssetBundleCollectorSettingData.Setting.LocationToLower = locationToLower;
AssetBundleCollectorSettingData.Setting.IncludeAssetGUID = includeAssetGUID;
AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName; AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName;
AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView; AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView;
AssetBundleCollectorSettingData.Setting.ShowEditorAlias = showEditorAlias;
AssetBundleCollectorSettingData.Setting.Packages.AddRange(packages); AssetBundleCollectorSettingData.Setting.Packages.AddRange(packages);
AssetBundleCollectorSettingData.SaveFile(); AssetBundleCollectorSettingData.SaveFile();
Debug.Log($"导入配置完毕!"); Debug.Log($"导入配置完毕!");
@ -206,11 +181,8 @@ namespace YooAsset.Editor
// 设置公共配置 // 设置公共配置
var commonElement = xmlDoc.CreateElement(XmlCommon); var commonElement = xmlDoc.CreateElement(XmlCommon);
commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString()); commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString());
commonElement.SetAttribute(XmlLocationToLower, AssetBundleCollectorSettingData.Setting.LocationToLower.ToString());
commonElement.SetAttribute(XmlIncludeAssetGUID, AssetBundleCollectorSettingData.Setting.IncludeAssetGUID.ToString());
commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString()); commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString());
commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString()); commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString());
commonElement.SetAttribute(XmlShowEditorAlias, AssetBundleCollectorSettingData.Setting.ShowEditorAlias.ToString());
root.AppendChild(commonElement); root.AppendChild(commonElement);
// 设置Package配置 // 设置Package配置
@ -225,7 +197,6 @@ namespace YooAsset.Editor
foreach (var group in package.Groups) foreach (var group in package.Groups)
{ {
var groupElement = xmlDoc.CreateElement(XmlGroup); var groupElement = xmlDoc.CreateElement(XmlGroup);
groupElement.SetAttribute(XmlGroupActiveRule, group.ActiveRuleName);
groupElement.SetAttribute(XmlGroupName, group.GroupName); groupElement.SetAttribute(XmlGroupName, group.GroupName);
groupElement.SetAttribute(XmlGroupDesc, group.GroupDesc); groupElement.SetAttribute(XmlGroupDesc, group.GroupDesc);
groupElement.SetAttribute(XmlAssetTags, group.AssetTags); groupElement.SetAttribute(XmlAssetTags, group.AssetTags);
@ -241,7 +212,6 @@ namespace YooAsset.Editor
collectorElement.SetAttribute(XmlAddressRule, collector.AddressRuleName); collectorElement.SetAttribute(XmlAddressRule, collector.AddressRuleName);
collectorElement.SetAttribute(XmlPackRule, collector.PackRuleName); collectorElement.SetAttribute(XmlPackRule, collector.PackRuleName);
collectorElement.SetAttribute(XmlFilterRule, collector.FilterRuleName); collectorElement.SetAttribute(XmlFilterRule, collector.FilterRuleName);
collectorElement.SetAttribute(XmlUserData, collector.UserData);
collectorElement.SetAttribute(XmlAssetTags, collector.AssetTags); collectorElement.SetAttribute(XmlAssetTags, collector.AssetTags);
groupElement.AppendChild(collectorElement); groupElement.AppendChild(collectorElement);
} }
@ -326,62 +296,6 @@ namespace YooAsset.Editor
return UpdateXmlConfig(xmlDoc); return UpdateXmlConfig(xmlDoc);
} }
// 2.1 -> 2.2
if (configVersion == "2.1")
{
// 添加公共元素属性
var commonNodeList = root.GetElementsByTagName(XmlCommon);
if (commonNodeList.Count > 0)
{
XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlShowEditorAlias) == false)
commonElement.SetAttribute(XmlShowEditorAlias, "False");
}
// 更新版本
root.SetAttribute(XmlVersion, "2.2");
return UpdateXmlConfig(xmlDoc);
}
// 2.2 -> 2.3
if (configVersion == "2.2")
{
// 获取所有分组元素
var groupNodeList = root.GetElementsByTagName(XmlGroup);
foreach (var groupNode in groupNodeList)
{
XmlElement groupElement = groupNode as XmlElement;
var collectorNodeList = groupElement.GetElementsByTagName(XmlCollector);
foreach (var collectorNode in collectorNodeList)
{
XmlElement collectorElement = collectorNode as XmlElement;
if (collectorElement.HasAttribute(XmlUserData) == false)
collectorElement.SetAttribute(XmlUserData, string.Empty);
}
}
// 更新版本
root.SetAttribute(XmlVersion, "2.3");
return UpdateXmlConfig(xmlDoc);
}
// 2.3 -> 2.4
if (configVersion == "2.3")
{
// 获取所有分组元素
var groupNodeList = root.GetElementsByTagName(XmlGroup);
foreach (var groupNode in groupNodeList)
{
XmlElement groupElement = groupNode as XmlElement;
if (groupElement.HasAttribute(XmlGroupActiveRule) == false)
groupElement.SetAttribute(XmlGroupActiveRule, $"{nameof(EnableGroup)}");
}
// 更新版本
root.SetAttribute(XmlVersion, "2.4");
return UpdateXmlConfig(xmlDoc);
}
return false; return false;
} }
} }

View File

@ -44,9 +44,6 @@ namespace YooAsset.Editor
if (AssetBundleCollectorSettingData.HasActiveRuleName(ActiveRuleName) == false) if (AssetBundleCollectorSettingData.HasActiveRuleName(ActiveRuleName) == false)
throw new Exception($"Invalid {nameof(IActiveRule)} class type : {ActiveRuleName} in group : {GroupName}"); throw new Exception($"Invalid {nameof(IActiveRule)} class type : {ActiveRuleName} in group : {GroupName}");
// 当分组不是激活状态时,直接不进行检测
if (ActiveRuleName == nameof(DisableGroup)) return;
foreach (var collector in Collectors) foreach (var collector in Collectors)
{ {
collector.CheckConfigError(); collector.CheckConfigError();
@ -99,20 +96,16 @@ namespace YooAsset.Editor
// 检测可寻址地址是否重复 // 检测可寻址地址是否重复
if (command.EnableAddressable) if (command.EnableAddressable)
{ {
var addressTemper = new Dictionary<string, string>(); HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result) foreach (var collectInfoPair in result)
{ {
if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector) if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector)
{ {
string address = collectInfoPair.Value.Address; string address = collectInfoPair.Value.Address;
string assetPath = collectInfoPair.Value.AssetPath; if (adressTemper.Contains(address) == false)
if (string.IsNullOrEmpty(address)) adressTemper.Add(address);
continue;
if (addressTemper.TryGetValue(address, out var existed) == false)
addressTemper.Add(address, assetPath);
else else
throw new Exception($"The address is existed : {address} in group : {GroupName} \nAssetPath:\n {existed}\n {assetPath}"); throw new Exception($"The address is existed : {address} in group : {GroupName}");
} }
} }
} }

View File

@ -76,20 +76,16 @@ namespace YooAsset.Editor
// 检测可寻址地址是否重复 // 检测可寻址地址是否重复
if (command.EnableAddressable) if (command.EnableAddressable)
{ {
var addressTemper = new Dictionary<string, string>(); HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result) foreach (var collectInfoPair in result)
{ {
if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector) if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector)
{ {
string address = collectInfoPair.Value.Address; string address = collectInfoPair.Value.Address;
string assetPath = collectInfoPair.Value.AssetPath; if (adressTemper.Contains(address) == false)
if (string.IsNullOrEmpty(address)) adressTemper.Add(address);
continue;
if (addressTemper.TryGetValue(address, out var existed) == false)
addressTemper.Add(address, assetPath);
else else
throw new Exception($"The address is existed : {address} \nAssetPath:\n {existed}\n {assetPath}"); throw new Exception($"The address is existed : {address}");
} }
} }
} }
@ -106,7 +102,7 @@ namespace YooAsset.Editor
HashSet<string> result = new HashSet<string>(); HashSet<string> result = new HashSet<string>();
foreach (var group in Groups) foreach (var group in Groups)
{ {
List<string> groupTags = EditorTools.StringToStringList(group.AssetTags, ';'); List<string> groupTags = StringUtility.StringToStringList(group.AssetTags, ';');
foreach (var tag in groupTags) foreach (var tag in groupTags)
{ {
if (result.Contains(tag) == false) if (result.Contains(tag) == false)
@ -115,7 +111,7 @@ namespace YooAsset.Editor
foreach (var collector in group.Collectors) foreach (var collector in group.Collectors)
{ {
List<string> collectorTags = EditorTools.StringToStringList(collector.AssetTags, ';'); List<string> collectorTags = StringUtility.StringToStringList(collector.AssetTags, ';');
foreach (var tag in collectorTags) foreach (var tag in collectorTags)
{ {
if (result.Contains(tag) == false) if (result.Contains(tag) == false)

View File

@ -6,40 +6,23 @@ using UnityEngine;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[CreateAssetMenu(fileName = "AssetBundleCollectorSetting", menuName = "YooAsset/Create AssetBundle Collector Settings")]
public class AssetBundleCollectorSetting : ScriptableObject public class AssetBundleCollectorSetting : ScriptableObject
{ {
/// <summary> /// <summary>
/// 显示包裹列表视图 /// 是否显示包裹列表视图
/// </summary> /// </summary>
public bool ShowPackageView = false; public bool ShowPackageView = false;
/// <summary> /// <summary>
/// 启用可寻址资源定位 /// 是否启用可寻址资源定位
/// </summary> /// </summary>
public bool EnableAddressable = false; public bool EnableAddressable = false;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower = false;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID = false;
/// <summary> /// <summary>
/// 资源包名唯一化 /// 资源包名唯一化
/// </summary> /// </summary>
public bool UniqueBundleName = false; public bool UniqueBundleName = false;
/// <summary>
/// 是否显示编辑器别名
/// </summary>
public bool ShowEditorAlias = false;
/// <summary> /// <summary>
/// 包裹列表 /// 包裹列表
/// </summary> /// </summary>
@ -51,28 +34,14 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public void ClearAll() public void ClearAll()
{ {
ShowPackageView = false;
EnableAddressable = false; EnableAddressable = false;
LocationToLower = false;
IncludeAssetGUID = false;
UniqueBundleName = false;
ShowEditorAlias = false;
Packages.Clear(); Packages.Clear();
} }
/// <summary> /// <summary>
/// 检测包裹配置错误 /// 检测配置错误
/// </summary> /// </summary>
public void CheckPackageConfigError(string packageName) public void CheckConfigError()
{
var package = GetPackage(packageName);
package.CheckConfigError();
}
/// <summary>
/// 检测所有配置错误
/// </summary>
public void CheckAllPackageConfigError()
{ {
foreach (var package in Packages) foreach (var package in Packages)
{ {
@ -81,9 +50,9 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 修复所有配置错误 /// 修复配置错误
/// </summary> /// </summary>
public bool FixAllPackageConfigError() public bool FixConfigError()
{ {
bool isFixed = false; bool isFixed = false;
foreach (var package in Packages) foreach (var package in Packages)
@ -101,8 +70,16 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public List<string> GetPackageAllTags(string packageName) public List<string> GetPackageAllTags(string packageName)
{ {
var package = GetPackage(packageName); foreach (var package in Packages)
return package.GetAllTags(); {
if (package.PackageName == packageName)
{
return package.GetAllTags();
}
}
Debug.LogWarning($"Not found package : {packageName}");
return new List<string>();
} }
/// <summary> /// <summary>
@ -111,27 +88,36 @@ namespace YooAsset.Editor
public CollectResult GetPackageAssets(EBuildMode buildMode, string packageName) public CollectResult GetPackageAssets(EBuildMode buildMode, string packageName)
{ {
if (string.IsNullOrEmpty(packageName)) if (string.IsNullOrEmpty(packageName))
throw new Exception("Build package name is null or empty !"); throw new Exception("Build package name is null or mepty !");
var package = GetPackage(packageName);
CollectCommand command = new CollectCommand(buildMode, packageName,
EnableAddressable, LocationToLower, IncludeAssetGUID, UniqueBundleName);
CollectResult collectResult = new CollectResult(command);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
return collectResult;
}
/// <summary>
/// 获取包裹类
/// </summary>
public AssetBundleCollectorPackage GetPackage(string packageName)
{
foreach (var package in Packages) foreach (var package in Packages)
{ {
if (package.PackageName == packageName) if (package.PackageName == packageName)
return package; {
CollectCommand command = new CollectCommand(buildMode, EnableAddressable);
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
return collectResult;
}
} }
throw new Exception($"Not found package : {packageName}");
throw new Exception($"Not found collector pacakge : {packageName}");
}
/// <summary>
/// 获取所有包裹收集的资源文件
/// </summary>
public List<CollectResult> GetAllPackageAssets(EBuildMode buildMode)
{
List<CollectResult> collectResultList = new List<CollectResult>(1000);
foreach (var package in Packages)
{
CollectCommand command = new CollectCommand(buildMode, EnableAddressable);
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
collectResultList.Add(collectResult);
}
return collectResultList;
} }
} }
} }

View File

@ -27,8 +27,110 @@ namespace YooAsset.Editor
public static bool IsDirty { private set; get; } = false; public static bool IsDirty { private set; get; } = false;
static AssetBundleCollectorSettingData() private static AssetBundleCollectorSetting _setting = null;
public static AssetBundleCollectorSetting Setting
{ {
get
{
if (_setting == null)
LoadSettingData();
return _setting;
}
}
public static List<string> GetActiveRuleNames()
{
if (_setting == null)
LoadSettingData();
List<string> names = new List<string>();
foreach (var pair in _cacheActiveRuleTypes)
{
names.Add(pair.Key);
}
return names;
}
public static List<string> GetAddressRuleNames()
{
if (_setting == null)
LoadSettingData();
List<string> names = new List<string>();
foreach (var pair in _cacheAddressRuleTypes)
{
names.Add(pair.Key);
}
return names;
}
public static List<string> GetPackRuleNames()
{
if (_setting == null)
LoadSettingData();
List<string> names = new List<string>();
foreach (var pair in _cachePackRuleTypes)
{
names.Add(pair.Key);
}
return names;
}
public static List<string> GetFilterRuleNames()
{
if (_setting == null)
LoadSettingData();
List<string> names = new List<string>();
foreach (var pair in _cacheFilterRuleTypes)
{
names.Add(pair.Key);
}
return names;
}
public static bool HasActiveRuleName(string ruleName)
{
foreach (var pair in _cacheActiveRuleTypes)
{
if (pair.Key == ruleName)
return true;
}
return false;
}
public static bool HasAddressRuleName(string ruleName)
{
foreach (var pair in _cacheAddressRuleTypes)
{
if (pair.Key == ruleName)
return true;
}
return false;
}
public static bool HasPackRuleName(string ruleName)
{
foreach (var pair in _cachePackRuleTypes)
{
if (pair.Key == ruleName)
return true;
}
return false;
}
public static bool HasFilterRuleName(string ruleName)
{
foreach (var pair in _cacheFilterRuleTypes)
{
if (pair.Key == ruleName)
return true;
}
return false;
}
/// <summary>
/// 加载配置文件
/// </summary>
private static void LoadSettingData()
{
_setting = EditorHelper.LoadSettingData<AssetBundleCollectorSetting>();
// IPackRule // IPackRule
{ {
// 清空缓存集合 // 清空缓存集合
@ -44,7 +146,6 @@ namespace YooAsset.Editor
typeof(PackCollector), typeof(PackCollector),
typeof(PackGroup), typeof(PackGroup),
typeof(PackRawFile), typeof(PackRawFile),
typeof(PackShaderVariants)
}; };
var customTypes = EditorTools.GetAssignableTypes(typeof(IPackRule)); var customTypes = EditorTools.GetAssignableTypes(typeof(IPackRule));
@ -92,10 +193,8 @@ namespace YooAsset.Editor
List<Type> types = new List<Type>(100) List<Type> types = new List<Type>(100)
{ {
typeof(AddressByFileName), typeof(AddressByFileName),
typeof(AddressByFilePath), typeof(AddressByCollectorAndFileName),
typeof(AddressByFolderAndFileName), typeof(AddressByGroupAndFileName)
typeof(AddressByGroupAndFileName),
typeof(AddressDisable)
}; };
var customTypes = EditorTools.GetAssignableTypes(typeof(IAddressRule)); var customTypes = EditorTools.GetAssignableTypes(typeof(IAddressRule));
@ -132,17 +231,6 @@ namespace YooAsset.Editor
} }
} }
private static AssetBundleCollectorSetting _setting = null;
public static AssetBundleCollectorSetting Setting
{
get
{
if (_setting == null)
_setting = SettingLoader.LoadSettingData<AssetBundleCollectorSetting>();
return _setting;
}
}
/// <summary> /// <summary>
/// 存储配置文件 /// 存储配置文件
/// </summary> /// </summary>
@ -162,7 +250,7 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public static void FixFile() public static void FixFile()
{ {
bool isFixed = Setting.FixAllPackageConfigError(); bool isFixed = Setting.FixConfigError();
if (isFixed) if (isFixed)
{ {
IsDirty = true; IsDirty = true;
@ -178,80 +266,7 @@ namespace YooAsset.Editor
SaveFile(); SaveFile();
} }
public static List<RuleDisplayName> GetActiveRuleNames() // 实例类相关
{
List<RuleDisplayName> names = new List<RuleDisplayName>();
foreach (var pair in _cacheActiveRuleTypes)
{
RuleDisplayName ruleName = new RuleDisplayName();
ruleName.ClassName = pair.Key;
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
names.Add(ruleName);
}
return names;
}
public static List<RuleDisplayName> GetAddressRuleNames()
{
List<RuleDisplayName> names = new List<RuleDisplayName>();
foreach (var pair in _cacheAddressRuleTypes)
{
RuleDisplayName ruleName = new RuleDisplayName();
ruleName.ClassName = pair.Key;
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
names.Add(ruleName);
}
return names;
}
public static List<RuleDisplayName> GetPackRuleNames()
{
List<RuleDisplayName> names = new List<RuleDisplayName>();
foreach (var pair in _cachePackRuleTypes)
{
RuleDisplayName ruleName = new RuleDisplayName();
ruleName.ClassName = pair.Key;
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
names.Add(ruleName);
}
return names;
}
public static List<RuleDisplayName> GetFilterRuleNames()
{
List<RuleDisplayName> names = new List<RuleDisplayName>();
foreach (var pair in _cacheFilterRuleTypes)
{
RuleDisplayName ruleName = new RuleDisplayName();
ruleName.ClassName = pair.Key;
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
names.Add(ruleName);
}
return names;
}
private static string GetRuleDisplayName(string name, Type type)
{
var attribute = DisplayNameAttributeHelper.GetAttribute<DisplayNameAttribute>(type);
if (attribute != null && string.IsNullOrEmpty(attribute.DisplayName) == false)
return attribute.DisplayName;
else
return name;
}
public static bool HasActiveRuleName(string ruleName)
{
return _cacheActiveRuleTypes.Keys.Contains(ruleName);
}
public static bool HasAddressRuleName(string ruleName)
{
return _cacheAddressRuleTypes.Keys.Contains(ruleName);
}
public static bool HasPackRuleName(string ruleName)
{
return _cachePackRuleTypes.Keys.Contains(ruleName);
}
public static bool HasFilterRuleName(string ruleName)
{
return _cacheFilterRuleTypes.Keys.Contains(ruleName);
}
public static IActiveRule GetActiveRuleInstance(string ruleName) public static IActiveRule GetActiveRuleInstance(string ruleName)
{ {
if (_cacheActiveRuleInstance.TryGetValue(ruleName, out IActiveRule instance)) if (_cacheActiveRuleInstance.TryGetValue(ruleName, out IActiveRule instance))
@ -332,26 +347,11 @@ namespace YooAsset.Editor
Setting.EnableAddressable = enableAddressable; Setting.EnableAddressable = enableAddressable;
IsDirty = true; IsDirty = true;
} }
public static void ModifyLocationToLower(bool locationToLower)
{
Setting.LocationToLower = locationToLower;
IsDirty = true;
}
public static void ModifyIncludeAssetGUID(bool includeAssetGUID)
{
Setting.IncludeAssetGUID = includeAssetGUID;
IsDirty = true;
}
public static void ModifyUniqueBundleName(bool uniqueBundleName) public static void ModifyUniqueBundleName(bool uniqueBundleName)
{ {
Setting.UniqueBundleName = uniqueBundleName; Setting.UniqueBundleName = uniqueBundleName;
IsDirty = true; IsDirty = true;
} }
public static void ModifyShowEditorAlias(bool showAlias)
{
Setting.ShowEditorAlias = showAlias;
IsDirty = true;
}
// 资源包裹编辑相关 // 资源包裹编辑相关
public static AssetBundleCollectorPackage CreatePackage(string packageName) public static AssetBundleCollectorPackage CreatePackage(string packageName)

View File

@ -12,29 +12,22 @@ namespace YooAsset.Editor
public class AssetBundleCollectorWindow : EditorWindow public class AssetBundleCollectorWindow : EditorWindow
{ {
[MenuItem("YooAsset/AssetBundle Collector", false, 101)] [MenuItem("YooAsset/AssetBundle Collector", false, 101)]
public static void OpenWindow() public static void ShowExample()
{ {
AssetBundleCollectorWindow window = GetWindow<AssetBundleCollectorWindow>("资源包收集工具", true, WindowsDefine.DockedWindowTypes); AssetBundleCollectorWindow window = GetWindow<AssetBundleCollectorWindow>("资源包收集工具", true, EditorDefine.DockedWindowTypes);
window.minSize = new Vector2(800, 600); window.minSize = new Vector2(800, 600);
} }
private Button _saveButton; private Button _saveButton;
private List<string> _collectorTypeList; private List<string> _collectorTypeList;
private List<RuleDisplayName> _activeRuleList; private List<string> _activeRuleList;
private List<RuleDisplayName> _addressRuleList; private List<string> _addressRuleList;
private List<RuleDisplayName> _packRuleList; private List<string> _packRuleList;
private List<RuleDisplayName> _filterRuleList; private List<string> _filterRuleList;
private Button _settingsButton;
private VisualElement _helpBoxContainer;
private VisualElement _setting1Container;
private VisualElement _setting2Container;
private Toggle _showPackageToogle; private Toggle _showPackageToogle;
private Toggle _enableAddressableToogle; private Toggle _enableAddressableToogle;
private Toggle _locationToLowerToogle;
private Toggle _includeAssetGUIDToogle;
private Toggle _uniqueBundleNameToogle; private Toggle _uniqueBundleNameToogle;
private Toggle _showEditorAliasToggle;
private VisualElement _packageContainer; private VisualElement _packageContainer;
private ListView _packageListView; private ListView _packageListView;
@ -49,11 +42,10 @@ namespace YooAsset.Editor
private VisualElement _collectorContainer; private VisualElement _collectorContainer;
private ScrollView _collectorScrollView; private ScrollView _collectorScrollView;
private PopupField<RuleDisplayName> _activeRulePopupField; private PopupField<string> _activeRulePopupField;
private int _lastModifyPackageIndex = 0; private int _lastModifyPackageIndex = 0;
private int _lastModifyGroupIndex = 0; private int _lastModifyGroupIndex = 0;
private bool _showSettings = false;
public void CreateGUI() public void CreateGUI()
@ -77,20 +69,13 @@ namespace YooAsset.Editor
VisualElement root = this.rootVisualElement; VisualElement root = this.rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleCollectorWindow>(); var visualAsset = EditorHelper.LoadWindowUXML<AssetBundleCollectorWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
visualAsset.CloneTree(root); visualAsset.CloneTree(root);
// 警示栏
_helpBoxContainer = root.Q("HelpBoxContainer");
// 公共设置相关 // 公共设置相关
_settingsButton = root.Q<Button>("SettingsButton");
_settingsButton.clicked += SettingsBtn_clicked;
_setting1Container = root.Q("PublicContainer1");
_setting2Container = root.Q("PublicContainer2");
_showPackageToogle = root.Q<Toggle>("ShowPackages"); _showPackageToogle = root.Q<Toggle>("ShowPackages");
_showPackageToogle.RegisterValueChangedCallback(evt => _showPackageToogle.RegisterValueChangedCallback(evt =>
{ {
@ -103,30 +88,12 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue); AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue);
RefreshWindow(); RefreshWindow();
}); });
_locationToLowerToogle = root.Q<Toggle>("LocationToLower");
_locationToLowerToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyLocationToLower(evt.newValue);
RefreshWindow();
});
_includeAssetGUIDToogle = root.Q<Toggle>("IncludeAssetGUID");
_includeAssetGUIDToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyIncludeAssetGUID(evt.newValue);
RefreshWindow();
});
_uniqueBundleNameToogle = root.Q<Toggle>("UniqueBundleName"); _uniqueBundleNameToogle = root.Q<Toggle>("UniqueBundleName");
_uniqueBundleNameToogle.RegisterValueChangedCallback(evt => _uniqueBundleNameToogle.RegisterValueChangedCallback(evt =>
{ {
AssetBundleCollectorSettingData.ModifyUniqueBundleName(evt.newValue); AssetBundleCollectorSettingData.ModifyUniqueBundleName(evt.newValue);
RefreshWindow(); RefreshWindow();
}); });
_showEditorAliasToggle = root.Q<Toggle>("ShowEditorAlias");
_showEditorAliasToggle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyShowEditorAlias(evt.newValue);
RefreshWindow();
});
// 配置修复按钮 // 配置修复按钮
var fixBtn = root.Q<Button>("FixButton"); var fixBtn = root.Q<Button>("FixButton");
@ -173,7 +140,6 @@ namespace YooAsset.Editor
{ {
selectPackage.PackageName = evt.newValue; selectPackage.PackageName = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage); AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
FillPackageViewData();
} }
}); });
@ -186,7 +152,6 @@ namespace YooAsset.Editor
{ {
selectPackage.PackageDesc = evt.newValue; selectPackage.PackageDesc = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage); AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
FillPackageViewData();
} }
}); });
@ -271,23 +236,21 @@ namespace YooAsset.Editor
// 分组激活规则 // 分组激活规则
var activeRuleContainer = root.Q("ActiveRuleContainer"); var activeRuleContainer = root.Q("ActiveRuleContainer");
{ {
_activeRulePopupField = new PopupField<RuleDisplayName>("Active Rule", _activeRuleList, 0); _activeRulePopupField = new PopupField<string>("Active Rule", _activeRuleList, 0);
_activeRulePopupField.name = "ActiveRuleMaskField"; _activeRulePopupField.name = "ActiveRuleMaskField";
_activeRulePopupField.style.unityTextAlign = TextAnchor.MiddleLeft; _activeRulePopupField.style.unityTextAlign = TextAnchor.MiddleLeft;
_activeRulePopupField.formatListItemCallback = FormatListItemCallback; activeRuleContainer.Add(_activeRulePopupField);
_activeRulePopupField.formatSelectedValueCallback = FormatSelectedValueCallback;
_activeRulePopupField.RegisterValueChangedCallback(evt => _activeRulePopupField.RegisterValueChangedCallback(evt =>
{ {
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage; var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup; var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectPackage != null && selectGroup != null) if (selectPackage != null && selectGroup != null)
{ {
selectGroup.ActiveRuleName = evt.newValue.ClassName; selectGroup.ActiveRuleName = evt.newValue;
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup); AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
FillGroupViewData(); FillGroupViewData();
} }
}); });
activeRuleContainer.Add(_activeRulePopupField);
} }
// 刷新窗体 // 刷新窗体
@ -327,42 +290,6 @@ namespace YooAsset.Editor
{ {
_showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView); _showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView);
_enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable); _enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable);
_locationToLowerToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.LocationToLower);
_includeAssetGUIDToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.IncludeAssetGUID);
_uniqueBundleNameToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.UniqueBundleName);
_showEditorAliasToggle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowEditorAlias);
// 警示框
#if UNITY_2020_3_OR_NEWER
_helpBoxContainer.Clear();
if (_enableAddressableToogle.value && _locationToLowerToogle.value)
{
var helpBox = new HelpBox("无法同时开启[Enable Addressable]选项和[Location To Lower]选项", HelpBoxMessageType.Error);
_helpBoxContainer.Add(helpBox);
}
if (AssetBundleCollectorSettingData.Setting.Packages.Count > 1 && _uniqueBundleNameToogle.value == false)
{
var helpBox = new HelpBox("检测到当前配置存在多个Package建议开启[Unique Bundle Name]选项", HelpBoxMessageType.Warning);
_helpBoxContainer.Add(helpBox);
}
if (_helpBoxContainer.childCount > 0)
_helpBoxContainer.style.display = DisplayStyle.Flex;
else
_helpBoxContainer.style.display = DisplayStyle.None;
#endif
// 设置栏
if (_showSettings)
{
_setting1Container.style.display = DisplayStyle.Flex;
_setting2Container.style.display = DisplayStyle.Flex;
}
else
{
_setting1Container.style.display = DisplayStyle.None;
_setting2Container.style.display = DisplayStyle.None;
}
_groupContainer.visible = false; _groupContainer.visible = false;
_collectorContainer.visible = false; _collectorContainer.visible = false;
@ -394,25 +321,6 @@ namespace YooAsset.Editor
{ {
AssetBundleCollectorSettingData.SaveFile(); AssetBundleCollectorSettingData.SaveFile();
} }
private void SettingsBtn_clicked()
{
_showSettings = !_showSettings;
RefreshWindow();
}
private string FormatListItemCallback(RuleDisplayName ruleDisplayName)
{
if (_showEditorAliasToggle.value)
return ruleDisplayName.DisplayName;
else
return ruleDisplayName.ClassName;
}
private string FormatSelectedValueCallback(RuleDisplayName ruleDisplayName)
{
if (_showEditorAliasToggle.value)
return ruleDisplayName.DisplayName;
else
return ruleDisplayName.ClassName;
}
// 包裹列表相关 // 包裹列表相关
private void FillPackageViewData() private void FillPackageViewData()
@ -502,7 +410,7 @@ namespace YooAsset.Editor
_groupListView.itemsSource = selectPackage.Groups; _groupListView.itemsSource = selectPackage.Groups;
_groupListView.Rebuild(); _groupListView.Rebuild();
if (_lastModifyGroupIndex >= 0 && _lastModifyGroupIndex < _groupListView.itemsSource.Count) if(_lastModifyGroupIndex >=0 && _lastModifyGroupIndex < _groupListView.itemsSource.Count)
{ {
_groupListView.selectedIndex = _lastModifyGroupIndex; _groupListView.selectedIndex = _lastModifyGroupIndex;
} }
@ -552,7 +460,7 @@ namespace YooAsset.Editor
_collectorContainer.visible = true; _collectorContainer.visible = true;
_lastModifyGroupIndex = _groupListView.selectedIndex; _lastModifyGroupIndex = _groupListView.selectedIndex;
_activeRulePopupField.SetValueWithoutNotify(GetActiveRuleIndex(selectGroup.ActiveRuleName)); _activeRulePopupField.SetValueWithoutNotify(selectGroup.ActiveRuleName);
_groupNameTxt.SetValueWithoutNotify(selectGroup.GroupName); _groupNameTxt.SetValueWithoutNotify(selectGroup.GroupName);
_groupDescTxt.SetValueWithoutNotify(selectGroup.GroupDesc); _groupDescTxt.SetValueWithoutNotify(selectGroup.GroupDesc);
_groupAssetTagsTxt.SetValueWithoutNotify(selectGroup.AssetTags); _groupAssetTagsTxt.SetValueWithoutNotify(selectGroup.AssetTags);
@ -656,34 +564,25 @@ namespace YooAsset.Editor
} }
if (_enableAddressableToogle.value) if (_enableAddressableToogle.value)
{ {
var popupField = new PopupField<RuleDisplayName>(_addressRuleList, 0); var popupField = new PopupField<string>(_addressRuleList, 0);
popupField.name = "PopupField1"; popupField.name = "PopupField1";
popupField.style.unityTextAlign = TextAnchor.MiddleLeft; popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
popupField.style.width = 220; popupField.style.width = 200;
elementBottom.Add(popupField); elementBottom.Add(popupField);
} }
{ {
var popupField = new PopupField<RuleDisplayName>(_packRuleList, 0); var popupField = new PopupField<string>(_packRuleList, 0);
popupField.name = "PopupField2"; popupField.name = "PopupField2";
popupField.style.unityTextAlign = TextAnchor.MiddleLeft; popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
popupField.style.width = 220;
elementBottom.Add(popupField);
}
{
var popupField = new PopupField<RuleDisplayName>(_filterRuleList, 0);
popupField.name = "PopupField3";
popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
popupField.style.width = 150; popupField.style.width = 150;
elementBottom.Add(popupField); elementBottom.Add(popupField);
} }
{ {
var textField = new TextField(); var popupField = new PopupField<string>(_filterRuleList, 0);
textField.name = "TextField0"; popupField.name = "PopupField3";
textField.label = "UserData"; popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
textField.style.width = 200; popupField.style.width = 150;
elementBottom.Add(textField); elementBottom.Add(popupField);
var label = textField.Q<Label>();
label.style.minWidth = 63;
} }
{ {
var textField = new TextField(); var textField = new TextField();
@ -768,7 +667,7 @@ namespace YooAsset.Editor
popupField0.index = GetCollectorTypeIndex(collector.CollectorType.ToString()); popupField0.index = GetCollectorTypeIndex(collector.CollectorType.ToString());
popupField0.RegisterValueChangedCallback(evt => popupField0.RegisterValueChangedCallback(evt =>
{ {
collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue); collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(evt.newValue);
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -777,15 +676,13 @@ namespace YooAsset.Editor
}); });
// Address Rule // Address Rule
var popupField1 = element.Q<PopupField<RuleDisplayName>>("PopupField1"); var popupField1 = element.Q<PopupField<string>>("PopupField1");
if (popupField1 != null) if (popupField1 != null)
{ {
popupField1.index = GetAddressRuleIndex(collector.AddressRuleName); popupField1.index = GetAddressRuleIndex(collector.AddressRuleName);
popupField1.formatListItemCallback = FormatListItemCallback;
popupField1.formatSelectedValueCallback = FormatSelectedValueCallback;
popupField1.RegisterValueChangedCallback(evt => popupField1.RegisterValueChangedCallback(evt =>
{ {
collector.AddressRuleName = evt.newValue.ClassName; collector.AddressRuleName = evt.newValue;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -795,13 +692,11 @@ namespace YooAsset.Editor
} }
// Pack Rule // Pack Rule
var popupField2 = element.Q<PopupField<RuleDisplayName>>("PopupField2"); var popupField2 = element.Q<PopupField<string>>("PopupField2");
popupField2.index = GetPackRuleIndex(collector.PackRuleName); popupField2.index = GetPackRuleIndex(collector.PackRuleName);
popupField2.formatListItemCallback = FormatListItemCallback;
popupField2.formatSelectedValueCallback = FormatSelectedValueCallback;
popupField2.RegisterValueChangedCallback(evt => popupField2.RegisterValueChangedCallback(evt =>
{ {
collector.PackRuleName = evt.newValue.ClassName; collector.PackRuleName = evt.newValue;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -810,13 +705,11 @@ namespace YooAsset.Editor
}); });
// Filter Rule // Filter Rule
var popupField3 = element.Q<PopupField<RuleDisplayName>>("PopupField3"); var popupField3 = element.Q<PopupField<string>>("PopupField3");
popupField3.index = GetFilterRuleIndex(collector.FilterRuleName); popupField3.index = GetFilterRuleIndex(collector.FilterRuleName);
popupField3.formatListItemCallback = FormatListItemCallback;
popupField3.formatSelectedValueCallback = FormatSelectedValueCallback;
popupField3.RegisterValueChangedCallback(evt => popupField3.RegisterValueChangedCallback(evt =>
{ {
collector.FilterRuleName = evt.newValue.ClassName; collector.FilterRuleName = evt.newValue;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -824,15 +717,6 @@ namespace YooAsset.Editor
} }
}); });
// UserData
var textFiled0 = element.Q<TextField>("TextField0");
textFiled0.SetValueWithoutNotify(collector.UserData);
textFiled0.RegisterValueChangedCallback(evt =>
{
collector.UserData = evt.newValue;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
});
// Tags // Tags
var textFiled1 = element.Q<TextField>("TextField1"); var textFiled1 = element.Q<TextField>("TextField1");
textFiled1.SetValueWithoutNotify(collector.AssetTags); textFiled1.SetValueWithoutNotify(collector.AssetTags);
@ -859,8 +743,7 @@ namespace YooAsset.Editor
try try
{ {
CollectCommand command = new CollectCommand(EBuildMode.SimulateBuild, _packageNameTxt.value, CollectCommand command = new CollectCommand(EBuildMode.DryRunBuild, _enableAddressableToogle.value);
_enableAddressableToogle.value, _locationToLowerToogle.value, _includeAssetGUIDToogle.value, _uniqueBundleNameToogle.value);
collectAssetInfos = collector.GetAllCollectAssets(command, group); collectAssetInfos = collector.GetAllCollectAssets(command, group);
} }
catch (System.Exception e) catch (System.Exception e)
@ -878,7 +761,12 @@ namespace YooAsset.Editor
string showInfo = collectAssetInfo.AssetPath; string showInfo = collectAssetInfo.AssetPath;
if (_enableAddressableToogle.value) if (_enableAddressableToogle.value)
showInfo = $"[{collectAssetInfo.Address}] {collectAssetInfo.AssetPath}"; {
IAddressRule instance = AssetBundleCollectorSettingData.GetAddressRuleInstance(collector.AddressRuleName);
AddressRuleData ruleData = new AddressRuleData(collectAssetInfo.AssetPath, collector.CollectPath, group.GroupName);
string addressValue = instance.GetAssetAddress(ruleData);
showInfo = $"[{addressValue}] {showInfo}";
}
var label = new Label(); var label = new Label();
label.text = showInfo; label.text = showInfo;
@ -927,7 +815,7 @@ namespace YooAsset.Editor
{ {
for (int i = 0; i < _addressRuleList.Count; i++) for (int i = 0; i < _addressRuleList.Count; i++)
{ {
if (_addressRuleList[i].ClassName == ruleName) if (_addressRuleList[i] == ruleName)
return i; return i;
} }
return 0; return 0;
@ -936,7 +824,7 @@ namespace YooAsset.Editor
{ {
for (int i = 0; i < _packRuleList.Count; i++) for (int i = 0; i < _packRuleList.Count; i++)
{ {
if (_packRuleList[i].ClassName == ruleName) if (_packRuleList[i] == ruleName)
return i; return i;
} }
return 0; return 0;
@ -945,20 +833,11 @@ namespace YooAsset.Editor
{ {
for (int i = 0; i < _filterRuleList.Count; i++) for (int i = 0; i < _filterRuleList.Count; i++)
{ {
if (_filterRuleList[i].ClassName == ruleName) if (_filterRuleList[i] == ruleName)
return i; return i;
} }
return 0; return 0;
} }
private RuleDisplayName GetActiveRuleIndex(string ruleName)
{
for (int i = 0; i < _activeRuleList.Count; i++)
{
if (_activeRuleList[i].ClassName == ruleName)
return _activeRuleList[i];
}
return _activeRuleList[0];
}
} }
} }
#endif #endif

View File

@ -1,23 +1,14 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;"> <uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;">
<ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
<ui:Button text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
<ui:Button text="导入" display-tooltip-when-elided="true" name="ImportButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="导入" display-tooltip-when-elided="true" name="ImportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
<ui:Button text="修复" display-tooltip-when-elided="true" name="FixButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="修复" display-tooltip-when-elided="true" name="FixButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
</uie:Toolbar> </uie:Toolbar>
<ui:VisualElement name="PublicContainer" style="background-color: rgb(79, 79, 79); flex-direction: column; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;"> <ui:VisualElement name="PublicContainer" style="height: 30px; background-color: rgb(67, 67, 67); flex-direction: row; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:VisualElement name="HelpBoxContainer" style="flex-grow: 1;" /> <ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Button text="Settings" display-tooltip-when-elided="true" name="SettingsButton" /> <ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
<ui:VisualElement name="PublicContainer1" style="flex-direction: row; flex-wrap: nowrap; height: 28px;"> <ui:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Show Editor Alias" name="ShowEditorAlias" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
<ui:VisualElement name="PublicContainer2" style="flex-direction: row; flex-wrap: nowrap; height: 28px;">
<ui:Toggle label="Location To Lower" name="LocationToLower" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Include Asset GUID" name="IncludeAssetGUID" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
</ui:VisualElement> </ui:VisualElement>
<ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;"> <ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;">
<ui:VisualElement name="PackageContainer" style="width: 200px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;"> <ui:VisualElement name="PackageContainer" style="width: 200px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">

View File

@ -25,30 +25,38 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string AssetPath { private set; get; } public string AssetPath { private set; get; }
/// <summary>
/// 是否为原生资源
/// </summary>
public bool IsRawAsset { private set; get; }
/// <summary> /// <summary>
/// 资源分类标签 /// 资源分类标签
/// </summary> /// </summary>
public List<string> AssetTags { private set; get; } public List<string> AssetTags { private set; get; }
/// <summary>
/// 是否为原生资源
/// </summary>
public bool IsRawAsset { private set; get; }
/// <summary> /// <summary>
/// 依赖的资源列表 /// 依赖的资源列表
/// </summary> /// </summary>
public List<string> DependAssets = new List<string>(); public List<string> DependAssets = new List<string>();
public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset, List<string> assetTags) public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, List<string> assetTags, bool isRawAsset)
{ {
CollectorType = collectorType; CollectorType = collectorType;
BundleName = bundleName; BundleName = bundleName;
Address = address; Address = address;
AssetPath = assetPath; AssetPath = assetPath;
IsRawAsset = isRawAsset;
AssetTags = assetTags; AssetTags = assetTags;
IsRawAsset = isRawAsset;
}
/// <summary>
/// 资源包名称追加包裹名
/// </summary>
public void BundleNameAppendPackageName(string packageName)
{
BundleName = $"{packageName.ToLower()}_{BundleName}";
} }
} }
} }

View File

@ -9,48 +9,14 @@ namespace YooAsset.Editor
public EBuildMode BuildMode { private set; get; } public EBuildMode BuildMode { private set; get; }
/// <summary> /// <summary>
/// 包裹名称 /// 是否启用可寻址资源定位
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 启用可寻址资源定位
/// </summary> /// </summary>
public bool EnableAddressable { private set; get; } public bool EnableAddressable { private set; get; }
/// <summary> public CollectCommand(EBuildMode buildMode, bool enableAddressable)
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower { private set; get; }
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID { private set; get; }
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName { private set; get; }
/// <summary>
/// 着色器统一全名称
/// </summary>
public string ShadersBundleName { private set; get; }
public CollectCommand(EBuildMode buildMode, string packageName, bool enableAddressable, bool locationToLower, bool includeAssetGUID, bool uniqueBundleName)
{ {
BuildMode = buildMode; BuildMode = buildMode;
PackageName = packageName;
EnableAddressable = enableAddressable; EnableAddressable = enableAddressable;
LocationToLower = locationToLower;
IncludeAssetGUID = includeAssetGUID;
UniqueBundleName = uniqueBundleName;
// 着色器统一全名称
var packRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
ShadersBundleName = packRuleResult.GetMainBundleName(packageName, uniqueBundleName);
} }
} }
} }

View File

@ -6,22 +6,44 @@ namespace YooAsset.Editor
public class CollectResult public class CollectResult
{ {
/// <summary> /// <summary>
/// 收集命令 /// 包裹名称
/// </summary> /// </summary>
public CollectCommand Command { private set; get; } public string PackageName { private set; get; }
/// <summary>
/// 是否启用可寻址资源定位
/// </summary>
public bool EnableAddressable { private set; get; }
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName { private set; get; }
/// <summary> /// <summary>
/// 收集的资源信息列表 /// 收集的资源信息列表
/// </summary> /// </summary>
public List<CollectAssetInfo> CollectAssets { private set; get; } public List<CollectAssetInfo> CollectAssets { private set; get; }
public CollectResult(CollectCommand command)
public CollectResult(string packageName, bool enableAddressable, bool uniqueBundleName)
{ {
Command = command; PackageName = packageName;
EnableAddressable = enableAddressable;
UniqueBundleName = uniqueBundleName;
} }
public void SetCollectAssets(List<CollectAssetInfo> collectAssets) public void SetCollectAssets(List<CollectAssetInfo> collectAssets)
{ {
CollectAssets = collectAssets; CollectAssets = collectAssets;
if (UniqueBundleName)
{
foreach (var collectAsset in CollectAssets)
{
collectAsset.BundleNameAppendPackageName(PackageName);
}
}
} }
} }
} }

View File

@ -1,79 +0,0 @@

namespace YooAsset.Editor
{
public struct PackRuleData
{
public string AssetPath;
public string CollectPath;
public string GroupName;
public string UserData;
public PackRuleData(string assetPath, string collectPath, string groupName, string userData)
{
AssetPath = assetPath;
CollectPath = collectPath;
GroupName = groupName;
UserData = userData;
}
}
public struct PackRuleResult
{
private readonly string _bundleName;
private readonly string _bundleExtension;
public PackRuleResult(string bundleName, string bundleExtension)
{
_bundleName = bundleName;
_bundleExtension = bundleExtension;
}
/// <summary>
/// 获取主资源包全名称
/// </summary>
public string GetMainBundleName(string packageName, bool uniqueBundleName)
{
string fullName;
string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').Replace(" ", "_").ToLower();
if (uniqueBundleName)
fullName = $"{packageName}_{bundleName}.{_bundleExtension}";
else
fullName = $"{bundleName}.{_bundleExtension}";
return fullName.ToLower();
}
/// <summary>
/// 获取共享资源包全名称
/// </summary>
public string GetShareBundleName(string packageName, bool uniqueBundleName)
{
// 注意:冗余的共享资源包名返回空
if (string.IsNullOrEmpty(_bundleName) && string.IsNullOrEmpty(_bundleExtension))
return string.Empty;
string fullName;
string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').Replace(" ", "_").ToLower();
if (uniqueBundleName)
fullName = $"{packageName}_share_{bundleName}.{_bundleExtension}";
else
fullName = $"share_{bundleName}.{_bundleExtension}";
return fullName.ToLower();
}
}
/// <summary>
/// 资源打包规则接口
/// </summary>
public interface IPackRule
{
/// <summary>
/// 获取打包规则结果
/// </summary>
PackRuleResult GetPackRuleResult(PackRuleData data);
/// <summary>
/// 是否为原生文件打包规则
/// </summary>
bool IsRawFilePackRule();
}
}

View File

@ -1,14 +0,0 @@

namespace YooAsset.Editor
{
/// <summary>
/// 共享资源的打包规则
/// </summary>
public interface ISharedPackRule
{
/// <summary>
/// 获取打包规则结果
/// </summary>
PackRuleResult GetPackRuleResult(string assetPath);
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1ed930b0cc1db1742b0a131ca476bd82
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,9 @@
 
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[DisplayName("启用分组")] /// <summary>
/// 启用分组
/// </summary>
public class EnableGroup : IActiveRule public class EnableGroup : IActiveRule
{ {
public bool IsActiveGroup() public bool IsActiveGroup()
@ -10,7 +12,9 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("禁用分组")] /// <summary>
/// 禁用分组
/// </summary>
public class DisableGroup : IActiveRule public class DisableGroup : IActiveRule
{ {
public bool IsActiveGroup() public bool IsActiveGroup()

View File

@ -0,0 +1,40 @@
using System.IO;
namespace YooAsset.Editor
{
/// <summary>
/// 以文件名为定位地址
/// </summary>
public class AddressByFileName : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
return Path.GetFileNameWithoutExtension(data.AssetPath);
}
}
/// <summary>
/// 以组名+文件名为定位地址
/// </summary>
public class AddressByGroupAndFileName : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
string fileName = Path.GetFileNameWithoutExtension(data.AssetPath);
return $"{data.GroupName}_{fileName}";
}
}
/// <summary>
/// 以收集器名+文件名为定位地址
/// </summary>
public class AddressByCollectorAndFileName : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
string fileName = Path.GetFileNameWithoutExtension(data.AssetPath);
string collectorName = Path.GetFileNameWithoutExtension(data.CollectPath);
return $"{collectorName}_{fileName}";
}
}
}

View File

@ -1,28 +1,12 @@
using System.Collections; using UnityEngine;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor; using UnityEditor;
using System.IO;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
public class DefaultFilterRule /// <summary>
{ /// 收集所有资源
/// <summary> /// </summary>
/// 忽略的文件类型
/// </summary>
private readonly static HashSet<string> _ignoreFileExtensions = new HashSet<string>() { "", ".so", ".dll", ".cs", ".js", ".boo", ".meta", ".cginc", ".hlsl" };
/// <summary>
/// 查询是否为忽略文件
/// </summary>
public static bool IsIgnoreFile(string fileExtension)
{
return _ignoreFileExtensions.Contains(fileExtension);
}
}
[DisplayName("收集所有资源")]
public class CollectAll : IFilterRule public class CollectAll : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)
@ -31,7 +15,9 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("收集场景")] /// <summary>
/// 只收集场景
/// </summary>
public class CollectScene : IFilterRule public class CollectScene : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)
@ -40,7 +26,9 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("收集预制体")] /// <summary>
/// 只收集预制体
/// </summary>
public class CollectPrefab : IFilterRule public class CollectPrefab : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)
@ -49,13 +37,15 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("收集精灵类型的纹理")] /// <summary>
/// 只收集精灵类型的资源
/// </summary>
public class CollectSprite : IFilterRule public class CollectSprite : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)
{ {
var mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(data.AssetPath); var mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(data.AssetPath);
if (mainAssetType == typeof(Texture2D)) if(mainAssetType == typeof(Texture2D))
{ {
var texImporter = AssetImporter.GetAtPath(data.AssetPath) as TextureImporter; var texImporter = AssetImporter.GetAtPath(data.AssetPath) as TextureImporter;
if (texImporter != null && texImporter.textureType == TextureImporterType.Sprite) if (texImporter != null && texImporter.textureType == TextureImporterType.Sprite)
@ -70,7 +60,9 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("收集着色器变种集合")] /// <summary>
/// 只收集着色器变种收集文件
/// </summary>
public class CollectShaderVariants : IFilterRule public class CollectShaderVariants : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)

View File

@ -0,0 +1,138 @@
using System;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
/// <summary>
/// 以文件路径作为资源包名
/// 注意:每个文件独自打资源包
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image_backgroud.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view_main.bundle"
/// </summary>
public class PackSeparately : IPackRule
{
string IPackRule.GetBundleName(PackRuleData data)
{
string bundleName = StringUtility.RemoveExtension(data.AssetPath);
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
}
}
/// <summary>
/// 以父类文件夹路径作为资源包名
/// 注意:文件夹下所有文件打进一个资源包
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view.bundle"
/// </summary>
public class PackDirectory : IPackRule
{
public static PackDirectory StaticPackRule = new PackDirectory();
string IPackRule.GetBundleName(PackRuleData data)
{
string bundleName = Path.GetDirectoryName(data.AssetPath);
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
}
}
/// <summary>
/// 以收集器路径下顶级文件夹为资源包名
/// 注意:文件夹下所有文件打进一个资源包
/// 例如:收集器路径为 "Assets/UIPanel"
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop.bundle"
/// </summary>
public class PackTopDirectory : IPackRule
{
string IPackRule.GetBundleName(PackRuleData data)
{
string assetPath = data.AssetPath.Replace(data.CollectPath, string.Empty);
assetPath = assetPath.TrimStart('/');
string[] splits = assetPath.Split('/');
if (splits.Length > 0)
{
if (Path.HasExtension(splits[0]))
throw new Exception($"Not found root directory : {assetPath}");
string bundleName = $"{data.CollectPath}/{splits[0]}";
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
}
else
{
throw new Exception($"Not found root directory : {assetPath}");
}
}
}
/// <summary>
/// 以收集器路径作为资源包名
/// 注意:收集的所有文件打进一个资源包
/// </summary>
public class PackCollector : IPackRule
{
string IPackRule.GetBundleName(PackRuleData data)
{
string collectPath = data.CollectPath;
if (AssetDatabase.IsValidFolder(collectPath))
{
string bundleName = collectPath;
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
}
else
{
string bundleName = StringUtility.RemoveExtension(collectPath);
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
}
}
}
/// <summary>
/// 以分组名称作为资源包名
/// 注意:收集的所有文件打进一个资源包
/// </summary>
public class PackGroup : IPackRule
{
string IPackRule.GetBundleName(PackRuleData data)
{
return data.GroupName;
}
}
/// <summary>
/// 原生文件打包模式
/// 注意:原生文件打包支持:图片,音频,视频,文本
/// </summary>
public class PackRawFile : IPackRule
{
string IPackRule.GetBundleName(PackRuleData data)
{
string extension = StringUtility.RemoveFirstChar(Path.GetExtension(data.AssetPath));
if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() ||
extension == EAssetFileExtension.mat.ToString() || extension == EAssetFileExtension.controller.ToString() ||
extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.anim.ToString() ||
extension == EAssetFileExtension.shader.ToString())
{
throw new Exception($"{nameof(PackRawFile)} is not support file estension : {extension}");
}
// 注意:原生文件只支持无依赖关系的资源
string[] depends = AssetDatabase.GetDependencies(data.AssetPath, true);
if (depends.Length != 1)
throw new Exception($"{nameof(PackRawFile)} is not support estension : {extension}");
string bundleName = data.AssetPath;
return EditorTools.GetRegularPath(bundleName).Replace('/', '_').Replace('.', '_');
}
}
/// <summary>
/// 着色器变种收集文件
/// </summary>
public class PackShaderVariants : IPackRule
{
public string GetBundleName(PackRuleData data)
{
return YooAssetSettings.UnityShadersBundleName;
}
}
}

View File

@ -1,52 +0,0 @@
using System.IO;
namespace YooAsset.Editor
{
[DisplayName("定位地址: 禁用")]
public class AddressDisable : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
return string.Empty;
}
}
[DisplayName("定位地址: 文件名")]
public class AddressByFileName : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
return Path.GetFileNameWithoutExtension(data.AssetPath);
}
}
[DisplayName("定位地址: 文件路径")]
public class AddressByFilePath : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
throw new System.Exception("可寻址模式下已经默认支持通过资源路径加载!");
}
}
[DisplayName("定位地址: 分组名_文件名")]
public class AddressByGroupAndFileName : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
string fileName = Path.GetFileNameWithoutExtension(data.AssetPath);
return $"{data.GroupName}_{fileName}";
}
}
[DisplayName("定位地址: 文件夹名_文件名")]
public class AddressByFolderAndFileName : IAddressRule
{
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
string fileName = Path.GetFileNameWithoutExtension(data.AssetPath);
FileInfo fileInfo = new FileInfo(data.AssetPath);
return $"{fileInfo.Directory.Name}_{fileName}";
}
}
}

View File

@ -1,196 +0,0 @@
using System;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
public class DefaultPackRule
{
/// <summary>
/// AssetBundle文件的后缀名
/// </summary>
public const string AssetBundleFileExtension = "bundle";
/// <summary>
/// 原生文件的后缀名
/// </summary>
public const string RawFileExtension = "rawfile";
/// <summary>
/// Unity着色器资源包名称
/// </summary>
public const string ShadersBundleName = "unityshaders";
public static PackRuleResult CreateShadersPackRuleResult()
{
PackRuleResult result = new PackRuleResult(ShadersBundleName, AssetBundleFileExtension);
return result;
}
}
/// <summary>
/// 以文件路径作为资源包名
/// 注意:每个文件独自打资源包
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image_backgroud.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view_main.bundle"
/// </summary>
[DisplayName("资源包名: 文件路径")]
public class PackSeparately : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string bundleName = PathUtility.RemoveExtension(data.AssetPath);
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
}
}
/// <summary>
/// 以父类文件夹路径作为资源包名
/// 注意:文件夹下所有文件打进一个资源包
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view.bundle"
/// </summary>
[DisplayName("资源包名: 父类文件夹路径")]
public class PackDirectory : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string bundleName = Path.GetDirectoryName(data.AssetPath);
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
}
}
/// <summary>
/// 以收集器路径下顶级文件夹为资源包名
/// 注意:文件夹下所有文件打进一个资源包
/// 例如:收集器路径为 "Assets/UIPanel"
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop.bundle"
/// </summary>
[DisplayName("资源包名: 收集器下顶级文件夹路径")]
public class PackTopDirectory : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string assetPath = data.AssetPath.Replace(data.CollectPath, string.Empty);
assetPath = assetPath.TrimStart('/');
string[] splits = assetPath.Split('/');
if (splits.Length > 0)
{
if (Path.HasExtension(splits[0]))
throw new Exception($"Not found root directory : {assetPath}");
string bundleName = $"{data.CollectPath}/{splits[0]}";
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
else
{
throw new Exception($"Not found root directory : {assetPath}");
}
}
bool IPackRule.IsRawFilePackRule()
{
return false;
}
}
/// <summary>
/// 以收集器路径作为资源包名
/// 注意:收集的所有文件打进一个资源包
/// </summary>
[DisplayName("资源包名: 收集器路径")]
public class PackCollector : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string bundleName;
string collectPath = data.CollectPath;
if (AssetDatabase.IsValidFolder(collectPath))
{
bundleName = collectPath;
}
else
{
bundleName = PathUtility.RemoveExtension(collectPath);
}
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
}
}
/// <summary>
/// 以分组名称作为资源包名
/// 注意:收集的所有文件打进一个资源包
/// </summary>
[DisplayName("资源包名: 分组名称")]
public class PackGroup : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string bundleName = data.GroupName;
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
}
}
/// <summary>
/// 打包原生文件
/// </summary>
[DisplayName("打包原生文件")]
public class PackRawFile : IPackRule
{
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{
string bundleName = data.AssetPath;
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.RawFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return true;
}
}
/// <summary>
/// 打包着色器变种集合
/// </summary>
[DisplayName("打包着色器变种集合文件")]
public class PackShaderVariants : IPackRule
{
public PackRuleResult GetPackRuleResult(PackRuleData data)
{
return DefaultPackRule.CreateShadersPackRuleResult();
}
bool IPackRule.IsRawFilePackRule()
{
return false;
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
/// <summary>
/// 零冗余的共享资源打包规则
/// </summary>
public class ZeroRedundancySharedPackRule : ISharedPackRule
{
public PackRuleResult GetPackRuleResult(string assetPath)
{
string bundleName = Path.GetDirectoryName(assetPath);
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
}
/// <summary>
/// 全部冗余的共享资源打包规则
/// </summary>
public class FullRedundancySharedPackRule : ISharedPackRule
{
public PackRuleResult GetPackRuleResult(string assetPath)
{
PackRuleResult result = new PackRuleResult(string.Empty, string.Empty);
return result;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3b8606481370397489cb3aa21e726d9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,36 +0,0 @@
using System;
using System.Reflection;
namespace YooAsset.Editor
{
/// <summary>
/// 编辑器显示名字
/// </summary>
public class DisplayNameAttribute : Attribute
{
public string DisplayName;
public DisplayNameAttribute(string name)
{
this.DisplayName = name;
}
}
public static class DisplayNameAttributeHelper
{
internal static T GetAttribute<T>(Type type) where T : Attribute
{
return (T)type.GetCustomAttribute(typeof(T), false);
}
internal static T GetAttribute<T>(MethodInfo methodInfo) where T : Attribute
{
return (T)methodInfo.GetCustomAttribute(typeof(T), false);
}
internal static T GetAttribute<T>(FieldInfo field) where T : Attribute
{
return (T)field.GetCustomAttribute(typeof(T), false);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 92d5f73b21059af43b7f56165b7acd63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,14 +6,12 @@ namespace YooAsset.Editor
public string AssetPath; public string AssetPath;
public string CollectPath; public string CollectPath;
public string GroupName; public string GroupName;
public string UserData;
public AddressRuleData(string assetPath, string collectPath, string groupName, string userData) public AddressRuleData(string assetPath, string collectPath, string groupName)
{ {
AssetPath = assetPath; AssetPath = assetPath;
CollectPath = collectPath; CollectPath = collectPath;
GroupName = groupName; GroupName = groupName;
UserData = userData;
} }
} }

View File

@ -4,16 +4,10 @@ namespace YooAsset.Editor
public struct FilterRuleData public struct FilterRuleData
{ {
public string AssetPath; public string AssetPath;
public string CollectPath;
public string GroupName;
public string UserData;
public FilterRuleData(string assetPath, string collectPath, string groupName, string userData) public FilterRuleData(string assetPath)
{ {
AssetPath = assetPath; AssetPath = assetPath;
CollectPath = collectPath;
GroupName = groupName;
UserData = userData;
} }
} }

View File

@ -0,0 +1,34 @@

namespace YooAsset.Editor
{
public struct PackRuleData
{
public string AssetPath;
public string CollectPath;
public string GroupName;
public PackRuleData(string assetPath)
{
AssetPath = assetPath;
CollectPath = string.Empty;
GroupName = string.Empty;
}
public PackRuleData(string assetPath, string collectPath, string groupName)
{
AssetPath = assetPath;
CollectPath = collectPath;
GroupName = groupName;
}
}
/// <summary>
/// 资源打包规则接口
/// </summary>
public interface IPackRule
{
/// <summary>
/// 获取资源打包所属的资源包名称
/// </summary>
string GetBundleName(PackRuleData data);
}
}

View File

@ -1,9 +0,0 @@

namespace YooAsset.Editor
{
public class RuleDisplayName
{
public string ClassName;
public string DisplayName;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: df712711c3830af419b7ada8fee53dda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -13,9 +13,9 @@ namespace YooAsset.Editor
public class AssetBundleDebuggerWindow : EditorWindow public class AssetBundleDebuggerWindow : EditorWindow
{ {
[MenuItem("YooAsset/AssetBundle Debugger", false, 104)] [MenuItem("YooAsset/AssetBundle Debugger", false, 104)]
public static void OpenWindow() public static void ShowExample()
{ {
AssetBundleDebuggerWindow wnd = GetWindow<AssetBundleDebuggerWindow>("资源包调试工具", true, WindowsDefine.DockedWindowTypes); AssetBundleDebuggerWindow wnd = GetWindow<AssetBundleDebuggerWindow>("资源包调试工具", true, EditorDefine.DockedWindowTypes);
wnd.minSize = new Vector2(800, 600); wnd.minSize = new Vector2(800, 600);
} }
@ -63,7 +63,7 @@ namespace YooAsset.Editor
VisualElement root = rootVisualElement; VisualElement root = rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleDebuggerWindow>(); var visualAsset = EditorHelper.LoadWindowUXML<AssetBundleDebuggerWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
@ -278,7 +278,7 @@ namespace YooAsset.Editor
string filePath = $"{resultPath}/{nameof(DebugReport)}_{_currentReport.FrameCount}.json"; string filePath = $"{resultPath}/{nameof(DebugReport)}_{_currentReport.FrameCount}.json";
string fileContent = JsonUtility.ToJson(_currentReport, true); string fileContent = JsonUtility.ToJson(_currentReport, true);
FileUtility.WriteAllText(filePath, fileContent); FileUtility.CreateFile(filePath, fileContent);
} }
} }
private void OnSearchKeyWordChange(ChangeEvent<string> e) private void OnSearchKeyWordChange(ChangeEvent<string> e)

View File

@ -24,7 +24,7 @@ namespace YooAsset.Editor
public void InitViewer() public void InitViewer()
{ {
// 加载布局文件 // 加载布局文件
_visualAsset = UxmlLoader.LoadWindowUXML<DebuggerAssetListViewer>(); _visualAsset = EditorHelper.LoadWindowUXML<DebuggerAssetListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -45,10 +45,6 @@ namespace YooAsset.Editor
_dependListView = _root.Q<ListView>("BottomListView"); _dependListView = _root.Q<ListView>("BottomListView");
_dependListView.makeItem = MakeDependListViewItem; _dependListView.makeItem = MakeDependListViewItem;
_dependListView.bindItem = BindDependListViewItem; _dependListView.bindItem = BindDependListViewItem;
#if UNITY_2020_3_OR_NEWER
SplitView.Adjuster(_root);
#endif
} }
/// <summary> /// <summary>

View File

@ -24,7 +24,7 @@ namespace YooAsset.Editor
public void InitViewer() public void InitViewer()
{ {
// 加载布局文件 // 加载布局文件
_visualAsset = UxmlLoader.LoadWindowUXML<DebuggerBundleListViewer>(); _visualAsset = EditorHelper.LoadWindowUXML<DebuggerBundleListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -45,10 +45,6 @@ namespace YooAsset.Editor
_usingListView = _root.Q<ListView>("BottomListView"); _usingListView = _root.Q<ListView>("BottomListView");
_usingListView.makeItem = MakeIncludeListViewItem; _usingListView.makeItem = MakeIncludeListViewItem;
_usingListView.bindItem = BindIncludeListViewItem; _usingListView.bindItem = BindIncludeListViewItem;
#if UNITY_2020_3_OR_NEWER
SplitView.Adjuster(_root);
#endif
} }
/// <summary> /// <summary>

View File

@ -10,9 +10,9 @@ namespace YooAsset.Editor
public class AssetBundleReporterWindow : EditorWindow public class AssetBundleReporterWindow : EditorWindow
{ {
[MenuItem("YooAsset/AssetBundle Reporter", false, 103)] [MenuItem("YooAsset/AssetBundle Reporter", false, 103)]
public static void OpenWindow() public static void ShowExample()
{ {
AssetBundleReporterWindow window = GetWindow<AssetBundleReporterWindow>("资源包报告工具", true, WindowsDefine.DockedWindowTypes); AssetBundleReporterWindow window = GetWindow<AssetBundleReporterWindow>("资源包报告工具", true, EditorDefine.DockedWindowTypes);
window.minSize = new Vector2(800, 600); window.minSize = new Vector2(800, 600);
} }
@ -35,18 +35,12 @@ namespace YooAsset.Editor
/// 资源包视图 /// 资源包视图
/// </summary> /// </summary>
BundleView, BundleView,
/// <summary>
/// 冗余资源试图
/// </summary>
Redundancy,
} }
private ToolbarMenu _viewModeMenu; private ToolbarMenu _viewModeMenu;
private ReporterSummaryViewer _summaryViewer; private ReporterSummaryViewer _summaryViewer;
private ReporterAssetListViewer _assetListViewer; private ReporterAssetListViewer _assetListViewer;
private ReporterBundleListViewer _bundleListViewer; private ReporterBundleListViewer _bundleListViewer;
private ReporterRedundancyListViewer _redundancyListViewer;
private EViewMode _viewMode; private EViewMode _viewMode;
private BuildReport _buildReport; private BuildReport _buildReport;
@ -61,7 +55,7 @@ namespace YooAsset.Editor
VisualElement root = this.rootVisualElement; VisualElement root = this.rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleReporterWindow>(); var visualAsset = EditorHelper.LoadWindowUXML<AssetBundleReporterWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
@ -76,7 +70,6 @@ namespace YooAsset.Editor
_viewModeMenu.menu.AppendAction(EViewMode.Summary.ToString(), ViewModeMenuAction0, ViewModeMenuFun0); _viewModeMenu.menu.AppendAction(EViewMode.Summary.ToString(), ViewModeMenuAction0, ViewModeMenuFun0);
_viewModeMenu.menu.AppendAction(EViewMode.AssetView.ToString(), ViewModeMenuAction1, ViewModeMenuFun1); _viewModeMenu.menu.AppendAction(EViewMode.AssetView.ToString(), ViewModeMenuAction1, ViewModeMenuFun1);
_viewModeMenu.menu.AppendAction(EViewMode.BundleView.ToString(), ViewModeMenuAction2, ViewModeMenuFun2); _viewModeMenu.menu.AppendAction(EViewMode.BundleView.ToString(), ViewModeMenuAction2, ViewModeMenuFun2);
_viewModeMenu.menu.AppendAction(EViewMode.Redundancy.ToString(), ViewModeMenuAction3, ViewModeMenuFun3);
// 搜索栏 // 搜索栏
var searchField = root.Q<ToolbarSearchField>("SearchField"); var searchField = root.Q<ToolbarSearchField>("SearchField");
@ -94,10 +87,6 @@ namespace YooAsset.Editor
_bundleListViewer = new ReporterBundleListViewer(); _bundleListViewer = new ReporterBundleListViewer();
_bundleListViewer.InitViewer(); _bundleListViewer.InitViewer();
// 加载试图
_redundancyListViewer = new ReporterRedundancyListViewer();
_redundancyListViewer.InitViewer();
// 显示视图 // 显示视图
_viewMode = EViewMode.Summary; _viewMode = EViewMode.Summary;
_viewModeMenu.text = EViewMode.Summary.ToString(); _viewModeMenu.text = EViewMode.Summary.ToString();
@ -120,12 +109,11 @@ namespace YooAsset.Editor
return; return;
_reportFilePath = selectFilePath; _reportFilePath = selectFilePath;
string jsonData = FileUtility.ReadAllText(_reportFilePath); string jsonData = FileUtility.ReadFile(_reportFilePath);
_buildReport = BuildReport.Deserialize(jsonData); _buildReport = BuildReport.Deserialize(jsonData);
_summaryViewer.FillViewData(_buildReport);
_assetListViewer.FillViewData(_buildReport, _searchKeyWord); _assetListViewer.FillViewData(_buildReport, _searchKeyWord);
_bundleListViewer.FillViewData(_buildReport, _reportFilePath, _searchKeyWord); _bundleListViewer.FillViewData(_buildReport, _reportFilePath, _searchKeyWord);
_redundancyListViewer.FillViewData(_buildReport, _searchKeyWord); _summaryViewer.FillViewData(_buildReport);
} }
private void OnSearchKeyWordChange(ChangeEvent<string> e) private void OnSearchKeyWordChange(ChangeEvent<string> e)
{ {
@ -146,7 +134,6 @@ namespace YooAsset.Editor
_summaryViewer.AttachParent(root); _summaryViewer.AttachParent(root);
_assetListViewer.DetachParent(); _assetListViewer.DetachParent();
_bundleListViewer.DetachParent(); _bundleListViewer.DetachParent();
_redundancyListViewer.DetachParent();
} }
} }
private void ViewModeMenuAction1(DropdownMenuAction action) private void ViewModeMenuAction1(DropdownMenuAction action)
@ -159,7 +146,6 @@ namespace YooAsset.Editor
_summaryViewer.DetachParent(); _summaryViewer.DetachParent();
_assetListViewer.AttachParent(root); _assetListViewer.AttachParent(root);
_bundleListViewer.DetachParent(); _bundleListViewer.DetachParent();
_redundancyListViewer.DetachParent();
} }
} }
private void ViewModeMenuAction2(DropdownMenuAction action) private void ViewModeMenuAction2(DropdownMenuAction action)
@ -172,20 +158,6 @@ namespace YooAsset.Editor
_summaryViewer.DetachParent(); _summaryViewer.DetachParent();
_assetListViewer.DetachParent(); _assetListViewer.DetachParent();
_bundleListViewer.AttachParent(root); _bundleListViewer.AttachParent(root);
_redundancyListViewer.DetachParent();
}
}
private void ViewModeMenuAction3(DropdownMenuAction action)
{
if (_viewMode != EViewMode.Redundancy)
{
_viewMode = EViewMode.Redundancy;
VisualElement root = this.rootVisualElement;
_viewModeMenu.text = EViewMode.Redundancy.ToString();
_summaryViewer.DetachParent();
_assetListViewer.DetachParent();
_bundleListViewer.DetachParent();
_redundancyListViewer.AttachParent(root);
} }
} }
private DropdownMenuAction.Status ViewModeMenuFun0(DropdownMenuAction action) private DropdownMenuAction.Status ViewModeMenuFun0(DropdownMenuAction action)
@ -209,13 +181,6 @@ namespace YooAsset.Editor
else else
return DropdownMenuAction.Status.Normal; return DropdownMenuAction.Status.Normal;
} }
private DropdownMenuAction.Status ViewModeMenuFun3(DropdownMenuAction action)
{
if (_viewMode == EViewMode.Redundancy)
return DropdownMenuAction.Status.Checked;
else
return DropdownMenuAction.Status.Normal;
}
} }
} }
#endif #endif

View File

@ -1,36 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace YooAsset.Editor
{
[Serializable]
public class ReportRedundancyInfo
{
/// <summary>
/// 资源路径
/// </summary>
public string AssetPath;
/// <summary>
/// 资源类型
/// </summary>
public string AssetType;
/// <summary>
/// 资源GUID
/// 说明Meta文件记录的GUID
/// </summary>
public string AssetGUID;
/// <summary>
/// 资源文件大小
/// </summary>
public long FileSize;
/// <summary>
/// 冗余的资源包数量
/// </summary>
public int Number;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7fbb7b27f54d3b0439a951348fd9d785
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -38,7 +38,7 @@ namespace YooAsset.Editor
public void InitViewer() public void InitViewer()
{ {
// 加载布局文件 // 加载布局文件
_visualAsset = UxmlLoader.LoadWindowUXML<ReporterAssetListViewer>(); _visualAsset = EditorHelper.LoadWindowUXML<ReporterAssetListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -68,10 +68,6 @@ namespace YooAsset.Editor
_dependListView = _root.Q<ListView>("BottomListView"); _dependListView = _root.Q<ListView>("BottomListView");
_dependListView.makeItem = MakeDependListViewItem; _dependListView.makeItem = MakeDependListViewItem;
_dependListView.bindItem = BindDependListViewItem; _dependListView.bindItem = BindDependListViewItem;
#if UNITY_2020_3_OR_NEWER
SplitView.Adjuster(_root);
#endif
} }
/// <summary> /// <summary>

View File

@ -1,10 +1,10 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;"> <ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;"> <uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
<uie:ToolbarButton text="Asset Path" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" /> <uie:ToolbarButton text="Asset Path" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
<uie:ToolbarButton text="Main Bundle" display-tooltip-when-elided="true" name="TopBar2" style="width: 145px; -unity-text-align: middle-left; flex-grow: 1;" /> <uie:ToolbarButton text="Main Bundle" display-tooltip-when-elided="true" name="TopBar2" style="width: 145px; -unity-text-align: middle-left; flex-grow: 1;" />
</uie:Toolbar> </uie:Toolbar>
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1; flex-basis: 60px;" /> <ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
</ui:VisualElement> </ui:VisualElement>
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;"> <ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;"> <uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">

View File

@ -42,7 +42,7 @@ namespace YooAsset.Editor
public void InitViewer() public void InitViewer()
{ {
// 加载布局文件 // 加载布局文件
_visualAsset = UxmlLoader.LoadWindowUXML<ReporterBundleListViewer>(); _visualAsset = EditorHelper.LoadWindowUXML<ReporterBundleListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -76,10 +76,6 @@ namespace YooAsset.Editor
_includeListView = _root.Q<ListView>("BottomListView"); _includeListView = _root.Q<ListView>("BottomListView");
_includeListView.makeItem = MakeIncludeListViewItem; _includeListView.makeItem = MakeIncludeListViewItem;
_includeListView.bindItem = BindIncludeListViewItem; _includeListView.bindItem = BindIncludeListViewItem;
#if UNITY_2020_3_OR_NEWER
SplitView.Adjuster(_root);
#endif
} }
/// <summary> /// <summary>
@ -349,24 +345,10 @@ namespace YooAsset.Editor
private void FillIncludeListView(ReportBundleInfo bundleInfo) private void FillIncludeListView(ReportBundleInfo bundleInfo)
{ {
List<ReportAssetInfo> containsList = new List<ReportAssetInfo>(); List<ReportAssetInfo> containsList = new List<ReportAssetInfo>();
HashSet<string> mainAssetDic = new HashSet<string>();
foreach (var assetInfo in _buildReport.AssetInfos) foreach (var assetInfo in _buildReport.AssetInfos)
{ {
if (assetInfo.MainBundleName == bundleInfo.BundleName) if (assetInfo.MainBundleName == bundleInfo.BundleName)
{
mainAssetDic.Add(assetInfo.AssetPath);
containsList.Add(assetInfo); containsList.Add(assetInfo);
}
}
foreach (string assetPath in bundleInfo.AllBuiltinAssets)
{
if (mainAssetDic.Contains(assetPath) == false)
{
var assetInfo = new ReportAssetInfo();
assetInfo.AssetPath = assetPath;
assetInfo.AssetGUID = "--";
containsList.Add(assetInfo);
}
} }
_includeListView.Clear(); _includeListView.Clear();
@ -390,16 +372,6 @@ namespace YooAsset.Editor
element.Add(label); element.Add(label);
} }
{
var label = new Label();
label.name = "Label3";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
//label.style.flexGrow = 1f;
label.style.width = 100;
element.Add(label);
}
{ {
var label = new Label(); var label = new Label();
label.name = "Label2"; label.name = "Label2";
@ -421,10 +393,6 @@ namespace YooAsset.Editor
var label1 = element.Q<Label>("Label1"); var label1 = element.Q<Label>("Label1");
label1.text = assetInfo.AssetPath; label1.text = assetInfo.AssetPath;
// Asset Source
var label3 = element.Q<Label>("Label3");
label3.text = assetInfo.AssetGUID != "--" ? "Main Asset" : "Builtin Asset";
// GUID // GUID
var label2 = element.Q<Label>("Label2"); var label2 = element.Q<Label>("Label2");
label2.text = assetInfo.AssetGUID; label2.text = assetInfo.AssetGUID;

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 8875000dff445624da4d6a2d6ef2f446 guid: a0319abb8eae03b4b88e8f900fe2276c
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

Some files were not shown because too many files have changed in this diff Show More