Compare commits

...

281 Commits
1.3.6 ... main

Author SHA1 Message Date
hevinci dc33abde46 update asset system 2023-06-16 15:01:13 +08:00
hevinci aae7b08dd1 update space shooter 2023-06-16 14:10:33 +08:00
hevinci f70582af1a Update CHANGELOG.md 2023-06-14 19:23:02 +08:00
hevinci f04d84bb93 Update package.json 2023-06-14 19:22:53 +08:00
hevinci 78693deed6 update space shooter
启用了新的内置资源查询机制。
2023-06-14 18:52:59 +08:00
hevinci f1a5965b4c update editor code
增加自动分析冗余资源的开关
2023-06-14 16:40:27 +08:00
hevinci cd43d0775d update runtime code 2023-06-13 16:41:27 +08:00
hevinci cf532a84ef update editor code 2023-06-13 16:41:08 +08:00
hevinci 651b65d148 update runtime code
优化了文件路径合并的逻辑。
2023-06-09 18:25:43 +08:00
hevinci 895dde1cc8 update logic code
优化了创建文件的方式。
2023-06-09 18:12:03 +08:00
hevinci f6e94c9514 Update CHANGELOG.md 2023-06-09 11:27:33 +08:00
hevinci da4ba4453c Update package.json 2023-06-09 11:27:19 +08:00
hevinci 53ea8c8002 update runtime code 2023-06-09 11:27:15 +08:00
hevinci d4549b1228 update space shooter
修复了DEMO里IOS平台流解密失败的问题。
2023-06-05 19:02:13 +08:00
hevinci fcf9eff2f6 update space shooter 2023-06-05 18:04:09 +08:00
hevinci 93b58149d2 update runtime code 2023-05-30 15:03:22 +08:00
hevinci c91c49465b update cache system
修复验证远端下载文件,极小概率失败的问题。
2023-05-29 19:28:07 +08:00
hevinci e9fa3ead04 update asset system
修复安卓平台下,小米8手机上有小概率加载原生文件失败的问题。
2023-05-29 17:30:43 +08:00
hevinci eff2f1d968 update space shooter 2023-05-26 18:35:34 +08:00
hevinci cd0a6579b8 Update CHANGELOG.md 2023-05-26 18:07:32 +08:00
hevinci 18c2e232cf Update package.json 2023-05-26 18:07:20 +08:00
hevinci ad680638ac update AssetBundleBuilder
Unity2021版本及以上推荐使用可编程构建管线(SBP)
2023-05-26 18:05:39 +08:00
hevinci 0764061d8f update space shooter 2023-05-25 16:38:33 +08:00
hevinci d448026250 update AssetBundleBuilder
修复了内置着色器Tag未正确传染给依赖资源包的问题。
2023-05-25 16:38:02 +08:00
hevinci 34f553b9e3 update AssetBundleCollector
修复了收集器对着色器未过滤的问题。
2023-05-25 16:35:18 +08:00
hevinci 25d1e32ce9 update asset system 2023-05-15 15:34:49 +08:00
hevinci 8686c32ada Update CHANGELOG.md 2023-05-12 17:45:24 +08:00
hevinci f043c6710a Update CHANGELOG.md 2023-05-12 17:43:13 +08:00
hevinci acd27e36fa Update package.json 2023-05-12 17:43:05 +08:00
hevinci 37f0d1e5a1 update runtime code
新增方法YooAssets.SetCacheSystemSandboxPath()
2023-05-12 17:32:41 +08:00
hevinci e6397559ff update cache system
新增方法ResoucePackage.ClearAllCacheFilesAsync()
2023-05-12 14:30:08 +08:00
hevinci 812c46adeb update runtime code
销毁Package的时候清空缓存记录。
2023-05-06 10:42:33 +08:00
hevinci 4d7fb6301a update samples 2023-05-05 10:35:02 +08:00
hevinci f0951f2a25 update samples 2023-05-05 09:49:08 +08:00
hevinci 7d2defedb7 update asset bundle collector 2023-05-04 11:14:01 +08:00
何冠峰 17ab618bed
Merge pull request #102 from hanazonoyurine/main
可寻址地址冲突时,打印冲突地址的资源地址
2023-05-04 10:46:44 +08:00
hanazonoyurine 0f9e932616
可寻址地址冲突时,打印冲突地址的资源地址 2023-04-27 16:30:17 +08:00
hevinci 20b0bd26ae Update CHANGELOG.md 2023-04-22 17:45:25 +08:00
hevinci 3b395861d9 Update package.json 2023-04-22 17:45:13 +08:00
hevinci d5d1f851ab update runtime code 2023-04-22 17:37:07 +08:00
hevinci c2e2a33af1 update samples 2023-04-22 17:23:51 +08:00
hevinci 9a729f921e update editor code
BuildParameters增加共享资源的打包规则字段
2023-04-22 17:22:59 +08:00
hevinci 1b75f4b6e9 update runtime code
UpdatePackageManifestAsync方法增加自动保存版本号参数
2023-04-22 17:20:23 +08:00
hevinci aaab6692c3 update runtime code 2023-04-22 11:25:51 +08:00
hevinci 70fc85e456 update runtime code
增加DestroyPackage()方法
2023-04-22 11:22:28 +08:00
hevinci 29358a7b4b update runtime code 2023-04-22 10:27:56 +08:00
hevinci b1b0563d84 update editor code
增加右键创建配置文件
2023-04-22 10:27:46 +08:00
hevinci 21b1e5bee7 Update LICENSE.md 2023-04-20 21:22:27 +08:00
hevinci c02eeef846 update edtior code
增加home page菜单栏
2023-04-20 21:22:19 +08:00
hevinci e84e50708b update asset bundle builder
增加对WEBGL平台加密选项的检测。
2023-04-20 17:56:21 +08:00
hevinci 1471ca06f3 Update CHANGELOG.md 2023-04-14 16:53:38 +08:00
hevinci 60b04c19dc Update package.json 2023-04-14 16:53:27 +08:00
hevinci 4490c99eee update samples 2023-04-14 16:43:27 +08:00
hevinci 9a84cdef9f fix #48
优化了场景卸载机制,在切换场景的时候不在主动卸载资源。
2023-04-14 16:42:43 +08:00
hevinci 62bbf110fb fix #83
修复了资源收集界面Package列表没有实时刷新的问题。
2023-04-14 15:34:25 +08:00
hevinci fd282d96d1 fix #97
修复着色器变种收集配置无法保存的问题。
2023-04-14 15:21:26 +08:00
hevinci 4e4da4440b update asset system 2023-04-13 17:36:58 +08:00
hevinci 5651d6dd9d update properties
增加
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
2023-04-13 17:04:46 +08:00
hevinci e0499993a4 Update README.md 2023-04-08 17:18:40 +08:00
hevinci 5c59cfe983 delete docs 2023-04-08 17:17:07 +08:00
hevinci 396ec7121c Update CHANGELOG.md 2023-04-08 11:18:36 +08:00
hevinci e403c80d51 Update package.json 2023-04-08 11:18:30 +08:00
hevinci aac315826e update asset bundle collector
修复了通过代码途径导入XML配置的报错问题。
2023-04-07 16:07:24 +08:00
hevinci 567c34d4d1 fix #95
修复了原生文件不支持ini格式文件的问题。
2023-04-06 16:32:50 +08:00
hevinci 896681df87 update asset system
修复了资源文件路径无效导致异常的问题。
2023-04-06 16:15:25 +08:00
hevinci e278883958 update docs 2023-03-30 17:41:42 +08:00
hevinci 0d57565cae Update CHANGELOG.md 2023-03-29 19:05:04 +08:00
hevinci 513c71398d Update package.json 2023-03-29 19:03:07 +08:00
hevinci a22c80a199 update package system 2023-03-29 18:14:39 +08:00
hevinci 16e3001e51 update editor code
调试窗口和报告窗口增加分屏功能。
2023-03-29 17:10:56 +08:00
hevinci 3943850bc1 update AssetBundleBuilder
调整构建的输出目录结构。
2023-03-29 12:19:31 +08:00
hevinci 4fc41a449e Merge branch 'main' of https://github.com/tuyoogame/YooAsset 2023-03-27 17:54:25 +08:00
hevinci f945508625 Update README.md 2023-03-27 17:54:19 +08:00
何冠峰 beaa77832c
Merge pull request #86 from LiuOcean/main
update UniTask tutorial doc
2023-03-27 09:57:29 +08:00
L d0480edda6 update UniTask tutorial doc 2023-03-25 14:16:51 +08:00
hevinci de43495af5 update asset system
编辑器模拟模式增加虚拟资源包
2023-03-24 18:33:36 +08:00
hevinci c60cc1e84f update asset system
新增了初始化参数LoadingMaxTimeSlice
移除了参数AssetLoadingMaxNumber
2023-03-24 17:01:35 +08:00
hevinci 82c83fcdf7 update operation system 2023-03-24 16:59:28 +08:00
hevinci 19221480a0 update asset bundle collector
导入时检测xml配置错误。
2023-03-24 16:25:45 +08:00
hevinci 290e139346 update asset bundle collector
增加了AddressByFilePath规则类
2023-03-24 16:13:39 +08:00
hevinci 923b0751e5 update asset system
扩展了Instantiate方法
2023-03-24 16:07:30 +08:00
hevinci 334b96f90e update samples 2023-03-22 19:00:58 +08:00
hevinci 7ae8a6c247 update patch system 2023-03-22 19:00:52 +08:00
hevinci 18830544a6 update samples 2023-03-22 18:58:46 +08:00
hevinci 37cab30ed7 update patch system 2023-03-22 18:58:35 +08:00
hevinci 91fe51d10a update patch system
UpdatePackageManifestOperation增加新方法FlushManifestVersionFile()
2023-03-22 18:48:52 +08:00
hevinci 027ae02aa0 update asset system
增加了下载失败尝试次数的初始化参数
2023-03-22 17:14:58 +08:00
hevinci 49e0d9729d Update FAQ.md 2023-03-22 09:44:36 +08:00
hevinci 15c667b043 update samples 2023-03-22 09:44:25 +08:00
hevinci 4820d2a54a update properties 2023-03-22 09:44:18 +08:00
hevinci 58a40ad1d1 update asset bundle builder 2023-03-22 09:43:28 +08:00
hevinci 1877a373d6 Merge branch 'main' of https://github.com/tuyoogame/YooAsset 2023-03-21 19:35:03 +08:00
hevinci 192b60f037 update asset bundle collector
修复了GroupActiveRule保存无效的问题。
2023-03-21 19:35:01 +08:00
hevinci c40224b454 update asset bundle builder 2023-03-21 19:34:00 +08:00
何冠峰 6508bf6851
Merge pull request #82 from LiuOcean/main
Update CodeTutorial4.md file
2023-03-21 12:42:52 +08:00
L 96b8ced64f Update CodeTutorial4.md file 2023-03-17 11:56:10 +08:00
hevinci 254da59b7a update asset bundle builder 2023-03-14 16:12:48 +08:00
hevinci c9b775d8ff update asset bundle builder
报告文件内增加资源包内嵌的资源列表
2023-03-13 19:36:17 +08:00
hevinci d60b0ea0ea Update document 2023-03-11 00:47:39 +08:00
hevinci 20061983d6 update space shooter 2023-03-11 00:45:58 +08:00
hevinci ff8f8623d9 update space shooter 2023-03-11 00:14:26 +08:00
hevinci 1ce1a6f0ff update extension sample 2023-03-11 00:08:15 +08:00
hevinci 67d09d95fa update runtime code
代码里移除了Patch敏感字。
2023-03-11 00:06:40 +08:00
hevinci 10e04c7645 update editor code 2023-03-10 23:44:15 +08:00
hevinci 9c05ac8cc2 Update CHANGELOG.md 2023-03-10 16:06:54 +08:00
hevinci 55d1eb145e Update package.json 2023-03-10 16:06:45 +08:00
hevinci c8cdeb2ae1 update asset system 2023-03-10 15:53:28 +08:00
hevinci 9891ab23a2 update samples 2023-03-09 17:29:37 +08:00
hevinci 9739fe2b79 update samples 2023-03-09 17:28:40 +08:00
hevinci c976221cbb update shader variant collector
修复了在unity2021下界面错乱的问题。
2023-03-09 15:33:48 +08:00
hevinci 8267904155 update editor code 2023-03-09 15:16:02 +08:00
hevinci ef8a8ff497 update asset bundle builder 2023-03-09 10:29:14 +08:00
hevinci 2384921477 update asset bundle builder
修复了可编程构建管线,当项目里没有着色器,如果有引用内置着色器会导致打包失败的问题。
2023-03-08 19:39:20 +08:00
hevinci 985b05f29d update asset bundle builder
优化了打包逻辑,提高构建速度。
2023-03-08 19:27:09 +08:00
hevinci 5254fb65ef update asset bundle collector 2023-03-08 18:34:48 +08:00
hevinci 8ff666d5e2 update patch system 2023-03-08 12:48:57 +08:00
hevinci ed77d6dc1f update decryption services 2023-03-08 12:22:09 +08:00
hevinci 7b41fd82a4 update asset system 2023-03-08 12:10:07 +08:00
hevinci ac0112199d update asset bundle builder
修复了SBP打包,如果包含内置资源会打包失败的问题。
2023-03-06 20:18:41 +08:00
hevinci ef5e1e65f9 fix #73
修复了同步加载原生文件,程序卡死的问题。
2023-03-06 20:05:34 +08:00
hevinci b330d26b4f update asset bundle builder 2023-03-06 19:07:46 +08:00
hevinci 93d7c34454 update logger 2023-03-03 18:24:01 +08:00
hevinci 0bd5677e26 update runtime code 2023-03-03 18:21:56 +08:00
hevinci 22e2e978ef Merge branch 'main' of https://github.com/tuyoogame/YooAsset 2023-03-03 18:04:46 +08:00
hevinci 65c2651105 Update EditorHelper.cs 2023-03-03 18:04:44 +08:00
何冠峰 ef13e19c48
Merge pull request #72 from HXiaoMing/feat-custom-logger
feat(YooLogger):支持自定义日志处理,方便收集线上问题
2023-03-03 18:03:21 +08:00
hevinci 39ffad6da6 Update CHANGELOG.md 2023-03-03 17:28:51 +08:00
hevinci 13924fca13 Update package.json 2023-03-03 17:28:42 +08:00
hevinci 438f006d1d update samples 2023-03-03 17:28:24 +08:00
hevinci 6fb5626230 Update document 2023-03-03 17:28:03 +08:00
hevinci ab29069af5 update download system
下载文件验证支持多线程。
2023-03-03 16:12:17 +08:00
hevinci fc3ed28eda update samples 2023-03-03 11:53:22 +08:00
hevinci 46c9110b85 update asset bundle builder 2023-03-03 11:51:48 +08:00
hevinci 06b033ed36 update asset system
优化了资源加载器查询逻辑。
2023-03-03 11:23:15 +08:00
hevinci ab96f3f28c update cache system
优化缓存系统的存储目录结构。
2023-03-01 20:35:01 +08:00
hevinci 295238cbb6 update asset system
优化资源对象加载耗时统计逻辑。
2023-03-01 18:23:47 +08:00
huanggongming 69125e967f feat(YooLogger):支持自定义日志处理,方便收集线上问题 2023-03-01 16:10:24 +08:00
hevinci 4f0f0e54ac update asset bundle collector
优化了资源收集界面,查看Collector主资源列表卡顿问题。
2023-03-01 11:03:52 +08:00
hevinci a9a01b08dc update patch system 2023-03-01 10:50:38 +08:00
hevinci c27a3e105c update asset bundle builder
修复SBP构建时,如果有原生文件导致报错的问题。
2023-02-28 19:21:13 +08:00
hevinci 3cfc084e62 update cache system 2023-02-28 19:17:05 +08:00
hevinci 7c1873e861 update asset bundle builder
修复在构建过程中发生异常后进度条未消失的问题。
2023-02-28 19:01:32 +08:00
hevinci c57c313dbe update samples 2023-02-28 18:26:10 +08:00
hevinci 19cf9c0129 update download system
修复关闭编辑器时的报错。
2023-02-28 18:25:48 +08:00
hevinci ebcb05cc55 update cache system
优化了缓存系统初始化逻辑,支持分帧获取所有缓存文件。
2023-02-28 18:25:27 +08:00
hevinci 7c4dbb1f38 update asset bundle builder 2023-02-27 19:10:56 +08:00
hevinci 091b46ccaf update samples 2023-02-27 19:02:24 +08:00
hevinci 4da2bf441f update shader variant collector
着色器变种收集界面增加单次照射数量的控制。
2023-02-27 19:02:16 +08:00
hevinci 365ed560f6 update asset bundle builder
优化资源包引用关系计算效率。
2023-02-27 18:11:51 +08:00
hevinci bcf6372602 update download system 2023-02-24 19:45:05 +08:00
hevinci a5e24be5d4 update asset bundle builder
修复资源包存在循环依赖的情况下打包卡死的问题。
2023-02-24 18:49:45 +08:00
hevinci cdaf6f0dca update samples 2023-02-24 16:52:50 +08:00
何冠峰 e38d0bc6d0
Merge pull request #70 from HXiaoMing/feat-custom-download-request
feat(DownloadSystem):支持自定义下载请求
2023-02-24 15:58:44 +08:00
huanggongming eb16ba8365 feat(DownloadSystem):支持自定义下载请求 2023-02-24 12:18:18 +08:00
hevinci 3beb4f53d6 Update document 2023-02-24 12:13:18 +08:00
hevinci f8ba0c9753 update asset system
修复引用链无效的问题。
2023-02-24 12:12:44 +08:00
hevinci 0232e5adec Update document 2023-02-23 12:15:41 +08:00
hevinci a0bc521903 Update CHANGELOG.md 2023-02-22 18:56:54 +08:00
hevinci 071a84d9ef Update package.json 2023-02-22 18:56:46 +08:00
hevinci aa40b5336e update samples 2023-02-22 18:41:29 +08:00
hevinci 157402bb39 update asset bundle collector
收集界面增加用户自定义数据栏。
2023-02-22 18:41:12 +08:00
何冠峰 5a98a68c27
Merge pull request #62 from DumoeDss/main
[feat] 添加自定义Address规则与跨平台资源收集
2023-02-22 17:10:03 +08:00
hevinci f6bc52fd59 update asset bundle builder 2023-02-22 17:02:28 +08:00
hevinci d1f2712e5f update cache system
缓存系统支持后缀名存储方式
2023-02-22 16:46:36 +08:00
hevinci 8958317f61 update asset bundle builder 2023-02-22 15:41:10 +08:00
hevinci fdf27cbc1a update runtime logic
补丁清单的资源包列表增加引用链
2023-02-22 15:41:01 +08:00
hevinci 26ffb829d0 update samples 2023-02-22 15:29:00 +08:00
hevinci 521e3e2587 update asset bundle builder 2023-02-21 14:52:16 +08:00
hevinci 17c6158478 update cache system
EVerifyLevel 新增Middle等级
2023-02-21 14:35:02 +08:00
hevinci fa0dc48993 update asset bundle reporter 2023-02-21 11:57:17 +08:00
Sayo 826bdaab5c
Merge branch 'tuyoogame:main' into main 2023-02-20 16:33:35 +08:00
hevinci 7d21da76fb update sample 2023-02-20 15:54:22 +08:00
hevinci 70465a49d7 Update document 2023-02-20 14:58:28 +08:00
hevinci acca74dce7 Update CHANGELOG.md 2023-02-17 19:15:34 +08:00
hevinci d8e7892ab7 Update package.json 2023-02-17 19:15:22 +08:00
hevinci e887bf1fd7 fix #67
修复报告查看界面2021.3兼容性问题
2023-02-17 19:07:10 +08:00
hevinci 145ca936e7 update sample 2023-02-17 18:44:19 +08:00
hevinci 69c7a51215 update runtime logic 2023-02-17 18:43:39 +08:00
hevinci c4875d4f80 optimize pack rule
接口变动:IPackRule
2023-02-17 18:41:27 +08:00
hevinci eed3c9768b Update document 2023-02-16 20:10:50 +08:00
Sayo 2c650f2bdf
Merge branch 'tuyoogame:main' into main 2023-02-15 22:57:24 +08:00
hevinci 71e8392359 update AssetBundleBuilder 2023-02-14 17:29:19 +08:00
Sayo cfbf6e23ec
Merge branch 'tuyoogame:main' into main 2023-02-14 15:14:06 +08:00
hevinci 9be5ec0f31 Update CHANGELOG.md 2023-02-14 11:49:35 +08:00
hevinci a8a0c3831b Update package.json 2023-02-14 11:49:21 +08:00
hevinci ef31d5a938 update asset system
修复资源加载代码逻辑错误。
2023-02-14 11:40:35 +08:00
hevinci 812db6dafe fix #65
修复构建逻辑代码错误。
2023-02-14 11:39:01 +08:00
hevinci 66fe2f0995 Update CHANGELOG.md 2023-02-10 17:41:48 +08:00
hevinci 3b40cc7833 Update package.json 2023-02-10 17:41:29 +08:00
hevinci 5a01ca061a update AssetBundleBuilder
unity2021开始不再支持内置构建管线。
2023-02-10 17:41:08 +08:00
hevinci ef0cc05f5c update cache system 2023-02-10 16:13:08 +08:00
hevinci c5c6e4ae23 update AssetBundleBuilder 2023-02-10 15:16:24 +08:00
hevinci 1c2bbfea93 update asset system
修复了WEBGL平台加载原生文件失败的问题
2023-02-09 16:57:01 +08:00
hevinci 8893317f59 update space shooter 2023-02-09 14:08:04 +08:00
hevinci ca8b5c85dd update sapce shooter
移除了BetterStreamingAssets插件,并使用安卓原生接口类代替。
2023-02-09 12:02:00 +08:00
Sayo a64d485278
Merge branch 'tuyoogame:main' into main 2023-02-08 10:42:07 +08:00
hevinci 2612764922 Update README.md 2023-02-07 18:39:42 +08:00
hevinci 8ce8e81792 update new cache system
重新设计了资源缓存系统
2023-02-07 18:39:08 +08:00
Sayo fbba2ddec9
Merge branch 'tuyoogame:main' into main 2023-02-07 11:47:51 +08:00
hevinci 33a1b9d4bf update shader variant collector 2023-02-06 17:50:36 +08:00
hevinci 03abac082c update shader variant collector 2023-02-02 10:05:20 +08:00
hevinci 3672a7e1fa update shader variant collector
着色器变种收集增加分批处理功能。
2023-02-01 19:32:37 +08:00
hevinci df27e7ba75 update shader variant collector
优化着色器变种收集代码
2023-02-01 18:59:47 +08:00
hevinci 423655e1ca update asset system
修复了通过Handle句柄查询资源包下载进度为零的问题。
2023-01-31 18:14:03 +08:00
hevinci f620223613 update asset system 2023-01-31 17:00:07 +08:00
hevinci 365a94d7b7 update settings 2023-01-31 16:57:43 +08:00
hevinci a98efd83b6 update operation system 2023-01-31 16:26:28 +08:00
Sayo 6488e96127 [feat] 添加跨平台资源收集 2023-01-30 12:07:34 +08:00
hevinci cc75594747 update patch system
修复WebGL平台本地文件验证报错。
2023-01-05 19:01:45 +08:00
hevinci e5de104933 update runtime code 2023-01-03 17:00:35 +08:00
hevinci 954e76ab33 Update CHANGELOG.md 2023-01-03 10:06:51 +08:00
hevinci 82bda518c9 Update package.json 2023-01-03 10:06:41 +08:00
hevinci cdc5bcd31f fix #56
修复更新资源清单错误计算超时时间的问题。
2022-12-29 14:23:16 +08:00
hevinci 61f6d480ae Update runtime code
修复清单解析异步操作的进度条变化
2022-12-28 16:44:25 +08:00
hevinci df6df3548c Update document 2022-12-27 10:20:13 +08:00
hevinci ac839450e2 update runtime code 2022-12-27 10:19:35 +08:00
hevinci 4fa01e1a29 update editor code 2022-12-27 10:18:57 +08:00
hevinci db2a45ec35 Update CHANGELOG.md 2022-12-26 01:21:07 +08:00
hevinci 76c6f5cc1c Update package.json 2022-12-26 01:20:48 +08:00
hevinci 339b519881 update editor code 2022-12-26 01:04:43 +08:00
hevinci de2fab1370 update runtime code 2022-12-26 01:04:35 +08:00
hevinci fd4b6794cc update samples 2022-12-26 00:49:40 +08:00
hevinci f3e3f7cf85 update runtime code 2022-12-26 00:48:56 +08:00
hevinci dd824254a9 update runtime code 2022-12-25 00:25:41 +08:00
hevinci 16943d4590 update runtime code 2022-12-24 22:09:14 +08:00
hevinci a95697088b update editor code 2022-12-24 22:03:29 +08:00
hevinci f771a98f25 update editor code
修复开启UniqueBundleName选项后,SBP构建报错的问题。
2022-12-21 17:11:09 +08:00
hevinci 3b1a8beadf update runtime code 2022-12-21 17:10:28 +08:00
hevinci 209e9d7705 update samples 2022-12-21 12:06:07 +08:00
hevinci de09a042e6 update runtime code 2022-12-21 12:05:05 +08:00
hevinci 66cd491493 update editor code 2022-12-21 12:04:56 +08:00
hevinci 4a158319e5 update runtime code 2022-12-21 10:54:22 +08:00
hevinci b322a848ba update samples 2022-12-20 16:17:16 +08:00
hevinci 4e759134bd update runtime code 2022-12-20 16:17:01 +08:00
hevinci 5c16171781 update runtime code 2022-12-18 21:55:49 +08:00
hevinci 08ad68d4a2 update samples 2022-12-17 22:38:26 +08:00
hevinci 2ace30acd8 update runtime code 2022-12-17 22:37:39 +08:00
hevinci fc55b1be82 update runtime code 2022-12-17 18:13:08 +08:00
hevinci b287dfedcf update samples 2022-12-17 18:08:49 +08:00
hevinci d6984f0ad4 update editor code 2022-12-17 18:08:38 +08:00
hevinci 85cb1ed3f6 update runtime code
优化清单分帧加载方式。
2022-12-17 18:08:23 +08:00
hevinci 32b5240fcc update patch system
缓存文件验证采取分帧处理。
2022-12-14 21:53:09 +08:00
hevinci 7b9fda2298 update download system
优化资源文件下载流程。
2022-12-13 23:30:16 +08:00
hevinci 15a605b677 update UniTask sample 2022-12-13 12:22:27 +08:00
hevinci f4a3fcece8 Fixed #54 2022-12-13 11:46:39 +08:00
hevinci d67fc31c26 update patch system
初始化的时候检测覆盖安装
2022-12-13 11:29:22 +08:00
hevinci 889000d8a8 update samples 2022-12-12 20:16:34 +08:00
hevinci e827e74cc7 update runtime code 2022-12-07 19:10:13 +08:00
hevinci 45ca1ebf02 update runtime logic
优化字符串拼接方法。
2022-12-07 17:52:32 +08:00
hevinci 3a81d7babd update editor logic 2022-12-07 17:52:02 +08:00
hevinci a1d5949177 Update document 2022-12-07 15:10:30 +08:00
hevinci d7ae52160b update runtime logic
优化了补丁清单解析。
2022-12-07 11:26:08 +08:00
hevinci e3fa33b9b5 update editor logic
移除BundleName_HashName选项。
2022-12-07 11:25:41 +08:00
hevinci ac251114ff update samples 2022-12-05 16:30:47 +08:00
hevinci 824d1c1501 update asset system 2022-12-05 16:29:45 +08:00
hevinci ac88fd5cf6 update asset sytem
资源句柄类增加GetDownloadReport()方法。
2022-12-05 14:36:26 +08:00
hevinci 5197d42807 Update CHANGELOG.md 2022-12-04 20:27:27 +08:00
hevinci 7a0f4caa9b Update package.json 2022-12-04 20:27:13 +08:00
hevinci 5bf1d29edc update utility 2022-12-04 20:14:02 +08:00
hevinci 2687466ed4 Update editor file 2022-12-03 23:16:39 +08:00
hevinci 14512d6470 Update samples 2022-12-03 23:16:16 +08:00
hevinci 32268f5a4a Update editor logic
资源收集界面规则选项显示别名
2022-12-03 23:16:04 +08:00
何冠峰 81401ca0b8
Merge pull request #53 from ZensYue/main
[add]Add ShowEditorAlias 添加显示编辑器名字
2022-12-03 20:12:31 +08:00
hevinci 688cc271d5 Update runtime logic
UpdatePackageVersionAsync()方法增加appendTimeTicks参数
2022-12-03 20:03:10 +08:00
hevinci a290353cfa Update runtime logic
在初始化失败的时候,销毁YooAssets会报异常。
2022-12-03 19:48:17 +08:00
hevinci 6038e7acd6 Update asset system 2022-12-03 19:13:11 +08:00
何冠峰 4abec5a389
Merge pull request #52 from gaozhou/main
为handle 添加 using 支持
2022-12-03 19:00:44 +08:00
hevinci a2b51a8044 Update samples 2022-12-03 18:49:05 +08:00
hevinci 19cb239746 Update logic code
优化补丁清单格式为二进制。
2022-12-03 18:48:51 +08:00
hevinci 7aab610be5 Add binary buffer class 2022-12-03 18:42:28 +08:00
hevinci 4ec5a126ac Remove BitMask files 2022-12-03 18:07:52 +08:00
zensyue 32643caf51
Merge pull request #1 from ZensYue/dev
Dev
2022-12-02 20:46:13 +08:00
ZensYue 114ebab6ae [bugfix]Convert the show name to the type name 把显示名字转换成类型名字 2022-12-02 20:39:28 +08:00
gaozhou d1463e1fc6 为handle 添加 using 支持 2022-12-02 14:23:58 +08:00
ZensYue aa49980231 [add]Add ShowEditorAlias 添加显示编辑器名字 2022-12-02 12:31:15 +08:00
hevinci 2696da092d update samples 2022-11-29 11:07:38 +08:00
hevinci 5415d95f36 Fix #46
修复资源包初始化失败之后,再次初始化提示异常的问题。
2022-11-29 11:06:24 +08:00
hevinci efa71c8bb7 Update FAQ.md 2022-11-28 22:24:36 +08:00
hevinci d59df4c561 update document 2022-11-27 15:40:09 +08:00
hevinci 140bcb037f Update CHANGELOG.md 2022-11-26 18:17:22 +08:00
hevinci 2a4384e093 Update package.json 2022-11-26 18:17:20 +08:00
521 changed files with 16877 additions and 9000 deletions

View File

@ -2,7 +2,453 @@
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.3.6] - 2022-11-26 ## [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
全新的太空战机Demo ! 全新的太空战机Demo !

View File

@ -39,12 +39,6 @@ namespace YooAsset.Editor
var buildParametersContext = new BuildParametersContext(buildParameters); var buildParametersContext = new BuildParametersContext(buildParameters);
_buildContext.SetContextObject(buildParametersContext); _buildContext.SetContextObject(buildParametersContext);
// 是否显示LOG
if (buildParameters.BuildMode == EBuildMode.SimulateBuild)
BuildRunner.EnableLog = false;
else
BuildRunner.EnableLog = true;
// 创建构建节点 // 创建构建节点
List<IBuildTask> pipeline; List<IBuildTask> pipeline;
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline) if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
@ -54,12 +48,13 @@ namespace YooAsset.Editor
new TaskPrepare(), //前期准备工作 new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表 new TaskGetBuildMap(), //获取构建列表
new TaskBuilding(), //开始执行构建 new TaskBuilding(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult(), //验证构建结果 new TaskVerifyBuildResult(), //验证构建结果
new TaskEncryption(), //加密资源文件 new TaskEncryption(), //加密资源文件
new TaskUpdateBuildInfo(), //更新构建信息 new TaskUpdateBundleInfo(), //更新资源包信息
new TaskCreatePatchManifest(), //创建清单文件 new TaskCreateManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件 new TaskCreateReport(), //创建报告文件
new TaskCreatePatchPackage(), //制作补丁 new TaskCreatePackage(), //制作
new TaskCopyBuildinFiles(), //拷贝内置文件 new TaskCopyBuildinFiles(), //拷贝内置文件
}; };
} }
@ -70,12 +65,13 @@ namespace YooAsset.Editor
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 TaskUpdateBuildInfo(), //更新构建信息 new TaskUpdateBundleInfo(), //更新补丁信息
new TaskCreatePatchManifest(), //创建清单文件 new TaskCreateManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件 new TaskCreateReport(), //创建报告文件
new TaskCreatePatchPackage(), //制作补丁包 new TaskCreatePackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件 new TaskCopyBuildinFiles(), //拷贝内置文件
}; };
} }
@ -84,19 +80,23 @@ namespace YooAsset.Editor
throw new NotImplementedException(); throw new NotImplementedException();
} }
// 初始化日志
BuildLogger.InitLogger(buildParameters.EnableLog);
// 执行构建流程 // 执行构建流程
var buildResult = BuildRunner.Run(pipeline, _buildContext); var buildResult = BuildRunner.Run(pipeline, _buildContext);
if (buildResult.Success) if (buildResult.Success)
{ {
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory(); buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
Debug.Log($"{buildParameters.BuildMode} pipeline build succeed !"); BuildLogger.Log($"{buildParameters.BuildMode} pipeline build succeed !");
} }
else else
{ {
Debug.LogWarning($"{buildParameters.BuildMode} pipeline build failed !"); BuildLogger.Warning($"{buildParameters.BuildMode} pipeline build failed !");
Debug.LogError($"Build task failed : {buildResult.FailedTask}"); BuildLogger.Error($"Build task failed : {buildResult.FailedTask}");
Debug.LogError($"Build task error : {buildResult.FailedInfo}"); BuildLogger.Error(buildResult.ErrorInfo);
} }
return buildResult; return buildResult;
} }
} }

View File

@ -58,14 +58,5 @@ namespace YooAsset.Editor
} }
} }
} }
/// <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,6 +3,7 @@ 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 = EditorHelper.LoadSettingData<AssetBundleBuilderSetting>(); _setting = SettingLoader.LoadSettingData<AssetBundleBuilderSetting>();
} }
/// <summary> /// <summary>

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 ShowExample() public static void OpenWindow()
{ {
AssetBundleBuilderWindow window = GetWindow<AssetBundleBuilderWindow>("资源包构建工具", true, EditorDefine.DockedWindowTypes); AssetBundleBuilderWindow window = GetWindow<AssetBundleBuilderWindow>("资源包构建工具", true, WindowsDefine.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 = EditorHelper.LoadWindowUXML<AssetBundleBuilderWindow>(); var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleBuilderWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
@ -60,7 +60,7 @@ namespace YooAsset.Editor
// 加密服务类 // 加密服务类
_encryptionServicesClassTypes = GetEncryptionServicesClassTypes(); _encryptionServicesClassTypes = GetEncryptionServicesClassTypes();
_encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.FullName).ToList(); _encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.Name).ToList();
// 输出目录 // 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot(); string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
@ -220,15 +220,27 @@ 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);
_compressionField.SetEnabled(enableElement); if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
_outputNameStyleField.SetEnabled(enableElement); {
_copyBuildinFileOptionField.SetEnabled(enableElement); _compressionField.SetEnabled(enableElement);
_copyBuildinFileTagsField.SetEnabled(enableElement); _outputNameStyleField.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()
@ -263,6 +275,8 @@ namespace YooAsset.Editor
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.AutoAnalyzeRedundancy = true;
buildParameters.ShareAssetPackRule = new DefaultShareAssetPackRule();
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

@ -18,12 +18,13 @@ namespace YooAsset.Editor
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.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion); string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}"; string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}";
return manifestFilePath; return manifestFilePath;
} }

View File

@ -7,8 +7,6 @@ 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>();
@ -17,6 +15,11 @@ 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>
@ -54,10 +57,10 @@ namespace YooAsset.Editor
public List<BuildAssetInfo> AllDependAssetInfos { private set; get; } public List<BuildAssetInfo> AllDependAssetInfos { private set; get; }
public BuildAssetInfo(ECollectorType collectorType, string mainBundleName, string address, string assetPath, bool isRawAsset) public BuildAssetInfo(ECollectorType collectorType, string bundleName, 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;
@ -133,24 +136,12 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool HasBundleName() public bool HasBundleName()
{ {
string bundleName = GetBundleName(); if (string.IsNullOrEmpty(BundleName))
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>
@ -164,50 +155,55 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 计算主资源或共享资源的完整包名 /// 计算共享资源的完整包名
/// </summary> /// </summary>
public void CalculateFullBundleName(bool uniqueBundleName, string packageName) public void CalculateShareBundleName(IShareAssetPackRule packRule, bool uniqueBundleName, string packageName, string shadersBundleName)
{ {
if (CollectorType == ECollectorType.None) if (CollectorType != ECollectorType.None)
return;
if (IsRawAsset)
throw new Exception("Should never get here !");
if (IsShaderAsset)
{ {
if (IsRawAsset) BundleName = shadersBundleName;
throw new Exception("Should never get here !");
if (IsShaderAsset)
{
string shareBundleName = YooAssetSettingsData.GetUnityShadersBundleFullName();
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
}
else
{
if (_referenceBundleNames.Count > 1)
{
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 else
{ {
if (IsRawAsset) if (_referenceBundleNames.Count > 1)
{ {
string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.RawFileVariant}"; PackRuleResult packRuleResult = packRule.GetPackRuleResult(AssetPath);
_mainBundleName = EditorTools.GetRegularPath(mainBundleName).ToLower(); BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName);
} }
else else
{ {
string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}"; // 注意被引用次数小于1的资源不需要设置资源包名称
_mainBundleName = EditorTools.GetRegularPath(mainBundleName).ToLower(); ; BundleName = string.Empty;
} }
} }
} }
/// <summary>
/// 判断是否为冗余资源
/// </summary>
public bool IsRedundancyAsset()
{
if (CollectorType != ECollectorType.None)
return false;
if (IsRawAsset)
throw new Exception("Should never get here !");
return _referenceBundleNames.Count > 1;
}
/// <summary>
/// 获取关联资源包的数量
/// </summary>
public int GetReferenceBundleCount()
{
return _referenceBundleNames.Count;
}
} }
} }

View File

@ -8,7 +8,7 @@ namespace YooAsset.Editor
{ {
public class BuildBundleInfo public class BuildBundleInfo
{ {
public class BuildPatchInfo public class InfoWrapper
{ {
/// <summary> /// <summary>
/// 构建内容的哈希值 /// 构建内容的哈希值
@ -18,17 +18,17 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
/// </summary> /// </summary>
public string PatchFileHash { set; get; } public string FileHash { set; get; }
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
/// </summary> /// </summary>
public string PatchFileCRC { set; get; } public string FileCRC { set; get; }
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
/// </summary> /// </summary>
public long PatchFileSize { set; get; } public long FileSize { set; get; }
/// <summary> /// <summary>
@ -39,7 +39,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 补丁包输出文件路径 /// 补丁包输出文件路径
/// </summary> /// </summary>
public string PatchOutputFilePath { set; get; } public string PackageOutputFilePath { set; get; }
} }
/// <summary> /// <summary>
@ -51,12 +51,12 @@ namespace YooAsset.Editor
/// 参与构建的资源列表 /// 参与构建的资源列表
/// 注意:不包含零依赖资源 /// 注意:不包含零依赖资源
/// </summary> /// </summary>
public readonly List<BuildAssetInfo> BuildinAssets = new List<BuildAssetInfo>(); public readonly List<BuildAssetInfo> AllMainAssets = new List<BuildAssetInfo>();
/// <summary> /// <summary>
/// 补丁文件信息 /// 补丁文件信息
/// </summary> /// </summary>
public readonly BuildPatchInfo PatchInfo = new BuildPatchInfo(); public readonly InfoWrapper BundleInfo = new InfoWrapper();
/// <summary> /// <summary>
/// Bundle文件的加载方法 /// Bundle文件的加载方法
@ -76,9 +76,9 @@ namespace YooAsset.Editor
{ {
get get
{ {
foreach (var asset in BuildinAssets) foreach (var assetInfo in AllMainAssets)
{ {
if (asset.IsRawAsset) if (assetInfo.IsRawAsset)
return true; return true;
} }
return false; return false;
@ -113,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}");
BuildinAssets.Add(assetInfo); AllMainAssets.Add(assetInfo);
} }
/// <summary> /// <summary>
@ -121,7 +121,7 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool IsContainsAsset(string assetPath) public bool IsContainsAsset(string assetPath)
{ {
foreach (var assetInfo in BuildinAssets) foreach (var assetInfo in AllMainAssets)
{ {
if (assetInfo.AssetPath == assetPath) if (assetInfo.AssetPath == assetPath)
{ {
@ -136,8 +136,8 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string[] GetBundleTags() public string[] GetBundleTags()
{ {
List<string> result = new List<string>(BuildinAssets.Count); List<string> result = new List<string>(AllMainAssets.Count);
foreach (var assetInfo in BuildinAssets) foreach (var assetInfo in AllMainAssets)
{ {
foreach (var assetTag in assetInfo.BundleTags) foreach (var assetTag in assetInfo.BundleTags)
{ {
@ -148,20 +148,43 @@ namespace YooAsset.Editor
return result.ToArray(); return result.ToArray();
} }
/// <summary>
/// 获取该资源包内的所有资源(包括零依赖资源)
/// </summary>
public List<string> GetAllBuiltinAssetPaths()
{
var packAssets = GetAllMainAssetPaths();
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>
/// 获取构建的资源路径列表 /// 获取构建的资源路径列表
/// </summary> /// </summary>
public string[] GetBuildinAssetPaths() public string[] GetAllMainAssetPaths()
{ {
return BuildinAssets.Select(t => t.AssetPath).ToArray(); return AllMainAssets.Select(t => t.AssetPath).ToArray();
} }
/// <summary> /// <summary>
/// 获取所有写入补丁清单的资源 /// 获取所有写入补丁清单的资源
/// </summary> /// </summary>
public BuildAssetInfo[] GetAllPatchAssetInfos() public BuildAssetInfo[] GetAllMainAssetInfos()
{ {
return BuildinAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray(); return AllMainAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray();
} }
/// <summary> /// <summary>
@ -173,23 +196,24 @@ 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 = GetBuildinAssetPaths(); build.assetNames = GetAllMainAssetPaths();
return build; return build;
} }
/// <summary> /// <summary>
/// 创建PatchBundle类 /// 创建PackageBundle类
/// </summary> /// </summary>
internal PatchBundle CreatePatchBundle() internal PackageBundle CreatePackageBundle()
{ {
string fileHash = PatchInfo.PatchFileHash; PackageBundle packageBundle = new PackageBundle();
string fileCRC = PatchInfo.PatchFileCRC; packageBundle.BundleName = BundleName;
long fileSize = PatchInfo.PatchFileSize; packageBundle.FileHash = BundleInfo.FileHash;
bool isRawFile = IsRawFile; packageBundle.FileCRC = BundleInfo.FileCRC;
byte loadMethod = (byte)LoadMethod; packageBundle.FileSize = BundleInfo.FileSize;
string[] tags = GetBundleTags(); packageBundle.IsRawFile = IsRawFile;
PatchBundle patchBundle = new PatchBundle(BundleName, fileHash, fileCRC, fileSize, isRawFile, loadMethod, tags); packageBundle.LoadMethod = (byte)LoadMethod;
return patchBundle; packageBundle.Tags = GetBundleTags();
return packageBundle;
} }
} }
} }

View File

@ -8,6 +8,13 @@ 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>
/// 参与构建的资源总数 /// 参与构建的资源总数
/// 说明:包括主动收集的资源以及其依赖的所有资源 /// 说明:包括主动收集的资源以及其依赖的所有资源
@ -25,9 +32,20 @@ namespace YooAsset.Editor
public bool UniqueBundleName; public bool UniqueBundleName;
/// <summary> /// <summary>
/// 资源包列表 /// 着色器统一的全名称
/// </summary> /// </summary>
public readonly List<BuildBundleInfo> BundleInfos = new List<BuildBundleInfo>(1000); public string ShadersBundleName;
/// <summary>
/// 资源包信息列表
/// </summary>
public Dictionary<string, BuildBundleInfo>.ValueCollection Collection
{
get
{
return _bundleInfoDic.Values;
}
}
/// <summary> /// <summary>
@ -35,11 +53,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public void PackAsset(BuildAssetInfo assetInfo) public void PackAsset(BuildAssetInfo assetInfo)
{ {
string bundleName = assetInfo.GetBundleName(); string bundleName = assetInfo.BundleName;
if (string.IsNullOrEmpty(bundleName)) if (string.IsNullOrEmpty(bundleName))
throw new Exception("Should never get here !"); throw new Exception("Should never get here !");
if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo)) if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo bundleInfo))
{ {
bundleInfo.PackAsset(assetInfo); bundleInfo.PackAsset(assetInfo);
} }
@ -47,33 +65,28 @@ namespace YooAsset.Editor
{ {
BuildBundleInfo newBundleInfo = new BuildBundleInfo(bundleName); BuildBundleInfo newBundleInfo = new BuildBundleInfo(bundleName);
newBundleInfo.PackAsset(assetInfo); newBundleInfo.PackAsset(assetInfo);
BundleInfos.Add(newBundleInfo); _bundleInfoDic.Add(bundleName, newBundleInfo);
} }
} }
/// <summary> /// <summary>
/// 获取所有的打包资源 /// 是否包含资源包
/// </summary> /// </summary>
public List<BuildAssetInfo> GetAllAssets() public bool IsContainsBundle(string bundleName)
{ {
List<BuildAssetInfo> result = new List<BuildAssetInfo>(BundleInfos.Count); return _bundleInfoDic.ContainsKey(bundleName);
foreach (var bundleInfo in BundleInfos)
{
result.AddRange(bundleInfo.BuildinAssets);
}
return result;
} }
/// <summary> /// <summary>
/// 获取AssetBundle内构建的资源路径列表 /// 获取资源包信息如果没找到返回NULL
/// </summary> /// </summary>
public string[] GetBuildinAssetPaths(string bundleName) public BuildBundleInfo GetBundleInfo(string bundleName)
{ {
if (TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo)) if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo result))
{ {
return bundleInfo.GetBuildinAssetPaths(); return result;
} }
throw new Exception($"Not found {nameof(BuildBundleInfo)} : {bundleName}"); throw new Exception($"Not found bundle : {bundleName}");
} }
/// <summary> /// <summary>
@ -81,8 +94,8 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public UnityEditor.AssetBundleBuild[] GetPipelineBuilds() public UnityEditor.AssetBundleBuild[] GetPipelineBuilds()
{ {
List<UnityEditor.AssetBundleBuild> builds = new List<UnityEditor.AssetBundleBuild>(BundleInfos.Count); List<UnityEditor.AssetBundleBuild> builds = new List<UnityEditor.AssetBundleBuild>(_bundleInfoDic.Count);
foreach (var bundleInfo in BundleInfos) foreach (var bundleInfo in _bundleInfoDic.Values)
{ {
if (bundleInfo.IsRawFile == false) if (bundleInfo.IsRawFile == false)
builds.Add(bundleInfo.CreatePipelineBuild()); builds.Add(bundleInfo.CreatePipelineBuild());
@ -91,25 +104,15 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 是否包含资源包 /// 创建着色器信息类
/// </summary> /// </summary>
public bool IsContainsBundle(string bundleName) public void CreateShadersBundleInfo(string shadersBundleName)
{ {
return TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo); if (IsContainsBundle(shadersBundleName) == false)
}
public bool TryGetBundleInfo(string bundleName, out BuildBundleInfo result)
{
foreach (var bundleInfo in BundleInfos)
{ {
if (bundleInfo.BundleName == bundleName) var shaderBundleInfo = new BuildBundleInfo(shadersBundleName);
{ _bundleInfoDic.Add(shadersBundleName, shaderBundleInfo);
result = bundleInfo;
return true;
}
} }
result = null;
return false;
} }
} }
} }

View File

@ -1,141 +0,0 @@
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

@ -67,13 +67,28 @@ 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>
public bool AutoAnalyzeRedundancy = true;
/// <summary> /// <summary>
/// 加密类 /// 共享资源的打包规则
/// </summary>
public IShareAssetPackRule ShareAssetPackRule = null;
/// <summary>
/// 资源的加密接口
/// </summary> /// </summary>
public IEncryptionServices EncryptionServices = null; public IEncryptionServices EncryptionServices = null;

View File

@ -7,8 +7,6 @@ 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;
@ -31,7 +29,7 @@ namespace YooAsset.Editor
{ {
if (string.IsNullOrEmpty(_pipelineOutputDirectory)) if (string.IsNullOrEmpty(_pipelineOutputDirectory))
{ {
_pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(Parameters.OutputRoot, Parameters.PackageName, Parameters.BuildTarget, Parameters.BuildMode); _pipelineOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{YooAssetSettings.OutputFolderName}";
} }
return _pipelineOutputDirectory; return _pipelineOutputDirectory;
} }
@ -43,7 +41,7 @@ namespace YooAsset.Editor
{ {
if (string.IsNullOrEmpty(_packageOutputDirectory)) if (string.IsNullOrEmpty(_packageOutputDirectory))
{ {
_packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.PackageName}/{Parameters.BuildTarget}/{Parameters.PackageVersion}"; _packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{Parameters.PackageVersion}";
} }
return _packageOutputDirectory; return _packageOutputDirectory;
} }
@ -117,22 +115,5 @@ 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

@ -27,6 +27,11 @@ 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>
/// 获取资源包信息类 /// 获取资源包信息类
@ -61,7 +66,7 @@ namespace YooAsset.Editor
File.Delete(savePath); File.Delete(savePath);
string json = JsonUtility.ToJson(buildReport, true); string json = JsonUtility.ToJson(buildReport, true);
FileUtility.CreateFile(savePath, json); FileUtility.WriteAllText(savePath, json);
} }
public static BuildReport Deserialize(string jsonData) public static BuildReport Deserialize(string jsonData)
{ {

View File

@ -48,6 +48,16 @@ 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

@ -0,0 +1,36 @@
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,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 4eacb00a7e3873740b599112dfcf0123 guid: 7fbb7b27f54d3b0439a951348fd9d785
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -22,7 +22,7 @@ namespace YooAsset.Editor
/// 构建时间 /// 构建时间
/// </summary> /// </summary>
public string BuildDate; public string BuildDate;
/// <summary> /// <summary>
/// 构建耗时(单位:秒) /// 构建耗时(单位:秒)
/// </summary> /// </summary>
@ -63,6 +63,16 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool UniqueBundleName; public bool UniqueBundleName;
/// <summary>
/// 自动分析冗余
/// </summary>
public bool AutoAnalyzeRedundancy;
/// <summary>
/// 共享资源的打包类名称
/// </summary>
public string ShareAssetPackRuleClassName;
/// <summary> /// <summary>
/// 加密服务类名称 /// 加密服务类名称
/// </summary> /// </summary>

View File

@ -0,0 +1,33 @@
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

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

View File

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

View File

@ -2,13 +2,19 @@
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
{ {
public static bool EnableLog = true; private static Stopwatch _buildWatch;
/// <summary>
/// 总耗时
/// </summary>
public static int TotalSeconds = 0;
/// <summary> /// <summary>
/// 执行构建流程 /// 执行构建流程
@ -23,45 +29,44 @@ 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>();
Log($"---------------------------------------->{taskAttribute.Desc}<---------------------------------------"); if (taskAttribute != null)
BuildLogger.Log($"---------------------------------------->{taskAttribute.Desc}<---------------------------------------");
task.Run(context); task.Run(context);
_buildWatch.Stop();
// 统计耗时
int seconds = GetBuildSeconds();
TotalSeconds += seconds;
if (taskAttribute != null)
BuildLogger.Log($"{taskAttribute.Desc}耗时:{seconds}秒");
} }
catch (Exception e) catch (Exception e)
{ {
EditorTools.ClearProgressBar();
buildResult.FailedTask = task.GetType().Name; buildResult.FailedTask = task.GetType().Name;
buildResult.FailedInfo = e.ToString(); buildResult.ErrorInfo = e.ToString();
buildResult.Success = false; buildResult.Success = false;
break; break;
} }
} }
// 返回运行结果 // 返回运行结果
BuildLogger.Log($"构建过程总计耗时:{TotalSeconds}秒");
return buildResult; return buildResult;
} }
/// <summary> private static int GetBuildSeconds()
/// 日志输出
/// </summary>
public static void Log(string info)
{ {
if (EnableLog) float seconds = _buildWatch.ElapsedMilliseconds / 1000f;
{ return (int)seconds;
UnityEngine.Debug.Log(info);
}
}
/// <summary>
/// 日志输出
/// </summary>
public static void Info(string info)
{
UnityEngine.Debug.Log(info);
} }
} }
} }

View File

@ -41,36 +41,10 @@ namespace YooAsset.Editor
throw new Exception("构建过程中发生严重错误!请查阅上下文日志!"); throw new Exception("构建过程中发生严重错误!请查阅上下文日志!");
} }
BuildRunner.Log("Unity引擎打包成功"); BuildLogger.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,44 +33,26 @@ namespace YooAsset.Editor
// 开始构建 // 开始构建
IBundleBuildResults buildResults; IBundleBuildResults buildResults;
var buildParameters = buildParametersContext.GetSBPBuildParameters(); var buildParameters = buildParametersContext.GetSBPBuildParameters();
var shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName(); var taskList = SBPBuildTasks.Create(buildMapContext.ShadersBundleName);
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.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 patchManifestContext = context.GetContextObject<PatchManifestContext>(); var manifestContext = context.GetContextObject<ManifestContext>();
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, patchManifestContext); CopyBuildinFilesToStreaming(buildParametersContext, manifestContext);
} }
} }
} }
@ -26,7 +26,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 拷贝首包资源文件 /// 拷贝首包资源文件
/// </summary> /// </summary>
private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, PatchManifestContext patchManifestContext) private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, ManifestContext manifestContext)
{ {
ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption; ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
@ -35,7 +35,7 @@ namespace YooAsset.Editor
string buildPackageVersion = buildParametersContext.Parameters.PackageVersion; string buildPackageVersion = buildParametersContext.Parameters.PackageVersion;
// 加载补丁清单 // 加载补丁清单
PatchManifest patchManifest = patchManifestContext.Manifest; PackageManifest manifest = manifestContext.Manifest;
// 清空流目录 // 清空流目录
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags)
@ -45,7 +45,7 @@ namespace YooAsset.Editor
// 拷贝补丁清单文件 // 拷贝补丁清单文件
{ {
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildPackageName, buildPackageVersion); string fileName = YooAssetSettingsData.GetManifestBinaryFileName(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.GetPatchManifestHashFileName(buildPackageName, buildPackageVersion); string fileName = YooAssetSettingsData.GetPackageHashFileName(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.GetPatchManifestVersionFileName(buildPackageName); string fileName = YooAssetSettingsData.GetPackageVersionFileName(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 patchBundle in patchManifest.BundleList) foreach (var packageBundle in manifest.BundleList)
{ {
string sourcePath = $"{packageOutputDirectory}/{patchBundle.FileName}"; string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}";
string destPath = $"{streamingAssetsDirectory}/{patchBundle.FileName}"; string destPath = $"{streamingAssetsDirectory}/{packageBundle.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 patchBundle in patchManifest.BundleList) foreach (var packageBundle in manifest.BundleList)
{ {
if (patchBundle.HasTag(tags) == false) if (packageBundle.HasTag(tags) == false)
continue; continue;
string sourcePath = $"{packageOutputDirectory}/{patchBundle.FileName}"; string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}";
string destPath = $"{streamingAssetsDirectory}/{patchBundle.FileName}"; string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}";
EditorTools.CopyFile(sourcePath, destPath, true); EditorTools.CopyFile(sourcePath, destPath, true);
} }
} }
// 刷新目录 // 刷新目录
AssetDatabase.Refresh(); AssetDatabase.Refresh();
BuildRunner.Log($"内置文件拷贝完成:{streamingAssetsDirectory}"); BuildLogger.Log($"内置文件拷贝完成:{streamingAssetsDirectory}");
} }
} }
} }

View File

@ -0,0 +1,44 @@
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,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 223f217ed81460541b5ea7eb7a7d82a4 guid: 3625d4b8b5b79324ebf7ec19a87677e7
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -0,0 +1,384 @@
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.EnableAddressable;
manifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
manifest.PackageName = buildParameters.PackageName;
manifest.PackageVersion = buildParameters.PackageVersion;
manifest.BundleList = GetAllPackageBundle(context);
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.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.GetAllMainAssetInfos();
foreach (var assetInfo in assetInfos)
{
PackageAsset packageAsset = new PackageAsset();
if (buildMapContext.EnableAddressable)
packageAsset.Address = assetInfo.Address;
else
packageAsset.Address = string.Empty;
packageAsset.AssetPath = assetInfo.AssetPath;
packageAsset.AssetTags = assetInfo.AssetTags.ToArray();
packageAsset.BundleID = GetAssetBundleID(assetInfo.BundleName, manifest);
packageAsset.DependIDs = GetAssetBundleDependIDs(packageAsset.BundleID, assetInfo, manifest);
result.Add(packageAsset);
}
}
return result;
}
private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PackageManifest manifest)
{
List<int> result = new List<int>();
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
{
if (dependAssetInfo.HasBundleName())
{
int bundleID = GetAssetBundleID(dependAssetInfo.BundleName, manifest);
if (mainBundleID != bundleID)
{
if (result.Contains(bundleID) == false)
result.Add(bundleID);
}
}
}
return result.ToArray();
}
private int GetAssetBundleID(string bundleName, PackageManifest manifest)
{
for (int index = 0; index < manifest.BundleList.Count; index++)
{
if (manifest.BundleList[index].BundleName == bundleName)
return index;
}
throw new Exception($"Not found bundle name : {bundleName}");
}
/// <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)
{
List<int> newDependIDs = new List<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];
List<string> newTags = new List<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 UpdateScriptPipelineReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext)
{
int progressValue;
int totalCount = manifest.BundleList.Count;
// 缓存资源包ID
_cachedBundleID.Clear();
progressValue = 0;
foreach (var packageBundle in manifest.BundleList)
{
int bundleID = GetAssetBundleID(packageBundle.BundleName, manifest);
_cachedBundleID.Add(packageBundle.BundleName, bundleID);
EditorTools.DisplayProgressBar("缓存资源包索引", ++progressValue, totalCount);
}
EditorTools.ClearProgressBar();
// 缓存资源包依赖
_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);
EditorTools.DisplayProgressBar("缓存资源包依赖列表", ++progressValue, totalCount);
}
EditorTools.ClearProgressBar();
// 计算资源包引用列表
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle);
EditorTools.DisplayProgressBar("计算资源包引用关系", ++progressValue, totalCount);
}
EditorTools.ClearProgressBar();
}
private void UpdateBuiltinPipelineReference(PackageManifest manifest, TaskBuilding.BuildResultContext buildResultContext)
{
int progressValue;
int totalCount = manifest.BundleList.Count;
// 缓存资源包ID
_cachedBundleID.Clear();
progressValue = 0;
foreach (var packageBundle in manifest.BundleList)
{
int bundleID = GetAssetBundleID(packageBundle.BundleName, manifest);
_cachedBundleID.Add(packageBundle.BundleName, bundleID);
EditorTools.DisplayProgressBar("缓存资源包索引", ++progressValue, totalCount);
}
EditorTools.ClearProgressBar();
// 缓存资源包依赖
_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);
EditorTools.DisplayProgressBar("缓存资源包依赖列表", ++progressValue, totalCount);
}
EditorTools.ClearProgressBar();
// 计算资源包引用列表
progressValue = 0;
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle);
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);
}
}
List<int> result = new List<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

@ -3,8 +3,8 @@ using System.Collections.Generic;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[TaskAttribute("制作补丁包")] [TaskAttribute("制作")]
public class TaskCreatePatchPackage : IBuildTask public class TaskCreatePackage : 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)
{ {
CopyPatchFiles(buildParameters, buildMapContext); CopyPackageFiles(buildParameters, buildMapContext);
} }
} }
/// <summary> /// <summary>
/// 拷贝补丁文件到补丁包目录 /// 拷贝补丁文件到补丁包目录
/// </summary> /// </summary>
private void CopyPatchFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext) private void CopyPackageFiles(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();
BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}"); BuildLogger.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 patchFileTotalCount = buildMapContext.BundleInfos.Count; int fileTotalCount = buildMapContext.Collection.Count;
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
EditorTools.CopyFile(bundleInfo.PatchInfo.BuildOutputFilePath, bundleInfo.PatchInfo.PatchOutputFilePath, true); EditorTools.CopyFile(bundleInfo.BundleInfo.BuildOutputFilePath, bundleInfo.BundleInfo.PackageOutputFilePath, true);
EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount); EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, fileTotalCount);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
} }

View File

@ -1,208 +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 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

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

View File

@ -27,17 +27,16 @@ 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) if (encryptionServices == null)
return; return;
if (encryptionServices.GetType() == typeof(EncryptionNone))
return;
int progressValue = 0; int progressValue = 0;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
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}";
@ -48,19 +47,19 @@ namespace YooAsset.Editor
// 注意:原生文件不支持加密 // 注意:原生文件不支持加密
if (bundleInfo.IsRawFile) if (bundleInfo.IsRawFile)
{ {
UnityEngine.Debug.LogWarning($"Encryption not support raw file : {bundleInfo.BundleName}"); BuildLogger.Warning($"Encryption not support raw file : {bundleInfo.BundleName}");
continue; continue;
} }
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt"; string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt";
FileUtility.CreateFile(filePath, encryptResult.EncryptedData); FileUtility.WriteAllBytes(filePath, encryptResult.EncryptedData);
bundleInfo.EncryptedFilePath = filePath; bundleInfo.EncryptedFilePath = filePath;
bundleInfo.LoadMethod = encryptResult.LoadMethod; bundleInfo.LoadMethod = encryptResult.LoadMethod;
BuildRunner.Log($"Bundle文件加密完成{filePath}"); BuildLogger.Log($"Bundle文件加密完成{filePath}");
} }
// 进度条 // 进度条
EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.BundleInfos.Count); EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.Collection.Count);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
} }

View File

@ -13,32 +13,213 @@ 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 = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.PackageName); var buildMapContext = CreateBuildMap(buildParametersContext.Parameters);
context.SetContextObject(buildMapContext); context.SetContextObject(buildMapContext);
BuildRunner.Log("构建内容准备完毕!"); BuildLogger.Log("构建内容准备完毕!");
// 检测构建结果 // 检测构建结果
CheckBuildMapContent(buildMapContext); CheckBuildMapContent(buildMapContext);
} }
/// <summary>
/// 资源构建上下文
/// </summary>
public BuildMapContext CreateBuildMap(BuildParameters buildParameters)
{
EBuildMode buildMode = buildParameters.BuildMode;
string packageName = buildParameters.PackageName;
IShareAssetPackRule sharePackRule = buildParameters.ShareAssetPackRule;
bool autoAnalyzeRedundancy = buildParameters.AutoAnalyzeRedundancy;
Dictionary<string, BuildAssetInfo> allBuildAssetInfoDic = new Dictionary<string, BuildAssetInfo>(1000);
// 1. 检测配置合法性
AssetBundleCollectorSettingData.Setting.CheckConfigError();
// 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.EnableAddressable = collectResult.Command.EnableAddressable;
context.UniqueBundleName = collectResult.Command.UniqueBundleName;
context.ShadersBundleName = collectResult.Command.ShadersBundleName;
// 8. 计算共享的资源包名
if (autoAnalyzeRedundancy)
{
var command = collectResult.Command;
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{
buildAssetInfo.CalculateShareBundleName(sharePackRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
}
}
else
{
// 记录冗余资源
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);
}
}
}
// 9. 移除不参与构建的资源
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);
}
// 10. 构建资源包
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 hasAnyDependAsset = false;
foreach (var collectAssetInfo in allCollectAssetInfos)
{
var collectorType = collectAssetInfo.CollectorType;
if (collectorType == ECollectorType.DependAssetCollector)
{
hasAnyDependAsset = true;
break;
}
}
if (hasAnyDependAsset == 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.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
// 注意:原生文件资源包只能包含一个原生文件 // 注意:原生文件资源包只能包含一个原生文件
bool isRawFile = bundleInfo.IsRawFile; bool isRawFile = bundleInfo.IsRawFile;
if (isRawFile) if (isRawFile)
{ {
if (bundleInfo.BuildinAssets.Count != 1) if (bundleInfo.AllMainAssets.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.BuildinAssets) foreach (var assetInfo in bundleInfo.AllMainAssets)
{ {
if (assetInfo.AllDependAssetInfos != null) if (assetInfo.AllDependAssetInfos != null)
{ {

View File

@ -12,8 +12,6 @@ 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;
// 检测构建参数合法性 // 检测构建参数合法性
@ -21,11 +19,18 @@ namespace YooAsset.Editor
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 (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("当前正在构建资源包,请结束后再试");
@ -42,6 +47,20 @@ namespace YooAsset.Editor
throw new Exception("首包资源标签不能为空!"); throw new Exception("首包资源标签不能为空!");
} }
// 检测共享资源打包规则
if (buildParameters.ShareAssetPackRule == 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))
@ -53,11 +72,11 @@ namespace YooAsset.Editor
if (buildParameters.BuildMode == EBuildMode.ForceRebuild) if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{ {
// 删除平台总目录 // 删除总目录
string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.PackageName}/{buildParameters.BuildTarget}"; string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.BuildTarget}/{buildParameters.PackageName}";
if (EditorTools.DeleteDirectory(platformDirectory)) if (EditorTools.DeleteDirectory(platformDirectory))
{ {
BuildRunner.Log($"删除平台总目录:{platformDirectory}"); BuildLogger.Log($"删除平台总目录:{platformDirectory}");
} }
} }
@ -65,7 +84,7 @@ namespace YooAsset.Editor
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory(); string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
if (EditorTools.CreateDirectory(pipelineOutputDirectory)) if (EditorTools.CreateDirectory(pipelineOutputDirectory))
{ {
BuildRunner.Log($"创建输出目录:{pipelineOutputDirectory}"); BuildLogger.Log($"创建输出目录:{pipelineOutputDirectory}");
} }
} }
} }

View File

@ -6,8 +6,8 @@ using UnityEditor;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[TaskAttribute("更新构建信息")] [TaskAttribute("更新资源包信息")]
public class TaskUpdateBuildInfo : IBuildTask public class TaskUpdateBundleInfo : IBuildTask
{ {
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
@ -17,39 +17,40 @@ namespace YooAsset.Editor
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle; int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle;
// 1.检测路径长度 // 1.检测文件名长度
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
// NOTE检测路径长度不要超过260字符。 // NOTE检测文件名长度不要超过260字符。
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; string fileName = bundleInfo.BundleName;
if (filePath.Length >= 260) if (fileName.Length >= 260)
throw new Exception($"The output bundle name is too long {filePath.Length} chars : {filePath}"); throw new Exception($"The output bundle name is too long {fileName.Length} chars : {fileName}");
} }
// 2.更新构建输出的文件路径 // 2.更新构建输出的文件路径
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
if (bundleInfo.IsEncryptedFile) if (bundleInfo.IsEncryptedFile)
bundleInfo.PatchInfo.BuildOutputFilePath = bundleInfo.EncryptedFilePath; bundleInfo.BundleInfo.BuildOutputFilePath = bundleInfo.EncryptedFilePath;
else else
bundleInfo.PatchInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}"; bundleInfo.BundleInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
} }
// 3.更新文件其它信息 // 3.更新文件其它信息
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
string buildOutputFilePath = bundleInfo.PatchInfo.BuildOutputFilePath; string buildOutputFilePath = bundleInfo.BundleInfo.BuildOutputFilePath;
bundleInfo.PatchInfo.ContentHash = GetBundleContentHash(bundleInfo, context); bundleInfo.BundleInfo.ContentHash = GetBundleContentHash(bundleInfo, context);
bundleInfo.PatchInfo.PatchFileHash = GetBundleFileHash(buildOutputFilePath, buildParametersContext); bundleInfo.BundleInfo.FileHash = GetBundleFileHash(buildOutputFilePath, buildParametersContext);
bundleInfo.PatchInfo.PatchFileCRC = GetBundleFileCRC(buildOutputFilePath, buildParametersContext); bundleInfo.BundleInfo.FileCRC = GetBundleFileCRC(buildOutputFilePath, buildParametersContext);
bundleInfo.PatchInfo.PatchFileSize = GetBundleFileSize(buildOutputFilePath, buildParametersContext); bundleInfo.BundleInfo.FileSize = GetBundleFileSize(buildOutputFilePath, buildParametersContext);
} }
// 4.更新补丁包输出的文件路径 // 4.更新补丁包输出的文件路径
foreach (var bundleInfo in buildMapContext.BundleInfos) foreach (var bundleInfo in buildMapContext.Collection)
{ {
string patchFileName = PatchManifest.CreateBundleFileName(outputNameStyle, bundleInfo.BundleName, bundleInfo.PatchInfo.PatchFileHash); string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleInfo.BundleName);
bundleInfo.PatchInfo.PatchOutputFilePath = $"{packageOutputDirectory}/{patchFileName}"; string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleInfo.BundleName, fileExtension, bundleInfo.BundleInfo.FileHash);
bundleInfo.BundleInfo.PackageOutputFilePath = $"{packageOutputDirectory}/{fileName}";
} }
} }
@ -63,7 +64,7 @@ namespace YooAsset.Editor
if (bundleInfo.IsRawFile) if (bundleInfo.IsRawFile)
{ {
string filePath = bundleInfo.PatchInfo.BuildOutputFilePath; string filePath = bundleInfo.BundleInfo.BuildOutputFilePath;
return HashUtility.FileMD5(filePath); return HashUtility.FileMD5(filePath);
} }

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

View File

@ -0,0 +1,11 @@

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

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: a6296859f09655c4191594304ddf378f guid: 46b8b200b841799498896403d9d427c2
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

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

View File

@ -45,6 +45,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string AssetTags = string.Empty; public string AssetTags = string.Empty;
/// <summary>
/// 用户自定义数据
/// </summary>
public string UserData = string.Empty;
/// <summary> /// <summary>
/// 收集器是否有效 /// 收集器是否有效
@ -142,11 +147,14 @@ 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 (isRawAsset && CollectorType != ECollectorType.MainAssetCollector) if (isRawFilePackRule && CollectorType != ECollectorType.MainAssetCollector)
throw new Exception($"The raw file must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}"); throw new Exception($"The raw file pack rule 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}");
@ -158,11 +166,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) && IsCollectAsset(assetPath)) if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(assetPath))
{ {
if (result.ContainsKey(assetPath) == false) if (result.ContainsKey(assetPath) == false)
{ {
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset); var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule);
result.Add(assetPath, collectAssetInfo); result.Add(assetPath, collectAssetInfo);
} }
else else
@ -175,9 +183,9 @@ namespace YooAsset.Editor
else else
{ {
string assetPath = CollectPath; string assetPath = CollectPath;
if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath)) if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(assetPath))
{ {
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset); var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule);
result.Add(assetPath, collectAssetInfo); result.Add(assetPath, collectAssetInfo);
} }
else else
@ -189,16 +197,17 @@ namespace YooAsset.Editor
// 检测可寻址地址是否重复 // 检测可寻址地址是否重复
if (command.EnableAddressable) if (command.EnableAddressable)
{ {
HashSet<string> adressTemper = new HashSet<string>(); var addressTemper = new Dictionary<string, 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;
if (adressTemper.Contains(address) == false) string assetPath = collectInfoPair.Value.AssetPath;
adressTemper.Add(address); 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}"); throw new Exception($"The address is existed : {address} in collector : {CollectPath} \nAssetPath:\n {existed}\n {assetPath}");
} }
} }
} }
@ -207,12 +216,12 @@ namespace YooAsset.Editor
return result.Values.ToList(); return result.Values.ToList();
} }
private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawAsset) private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawFilePackRule)
{ {
string address = GetAddress(group, assetPath); string address = GetAddress(command, group, assetPath);
string bundleName = GetBundleName(group, assetPath); string bundleName = GetBundleName(command, group, assetPath);
List<string> assetTags = GetAssetTags(group); List<string> assetTags = GetAssetTags(group);
CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, assetTags, isRawAsset); CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, isRawFilePackRule, assetTags);
// 注意:模拟构建模式下不需要收集依赖资源 // 注意:模拟构建模式下不需要收集依赖资源
if (command.BuildMode == EBuildMode.SimulateBuild) if (command.BuildMode == EBuildMode.SimulateBuild)
@ -222,7 +231,7 @@ namespace YooAsset.Editor
return collectAssetInfo; return collectAssetInfo;
} }
private bool IsValidateAsset(string assetPath) private bool IsValidateAsset(string assetPath, bool isRawFilePackRule)
{ {
if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false) if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false)
{ {
@ -235,15 +244,38 @@ namespace YooAsset.Editor
return false; return false;
// 忽略编辑器下的类型资源 // 忽略编辑器下的类型资源
Type type = AssetDatabase.GetMainAssetTypeAtPath(assetPath); Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (type == typeof(LightingDataAsset)) if (assetType == typeof(LightingDataAsset))
return false; return false;
// 忽略Unity无法识别的无效文件 // 检测原生文件是否合规
// 注意:只对非原生文件收集器处理 if (isRawFilePackRule)
if(PackRuleName != nameof(PackRawFile))
{ {
if (type == typeof(UnityEditor.DefaultAsset)) string extension = EditorTools.RemoveFirstChar(System.IO.Path.GetExtension(assetPath));
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;
@ -251,64 +283,60 @@ namespace YooAsset.Editor
} }
string fileExtension = System.IO.Path.GetExtension(assetPath); string fileExtension = System.IO.Path.GetExtension(assetPath);
if (IsIgnoreFile(fileExtension)) if (DefaultFilterRule.IsIgnoreFile(fileExtension))
return false; return false;
return true; return true;
} }
private bool IsIgnoreFile(string fileExtension)
{
foreach (var extension in YooAssetSettings.IgnoreFileExtensions)
{
if (extension == fileExtension)
return true;
}
return false;
}
private bool IsCollectAsset(string assetPath) 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)); return filterRuleInstance.IsCollectAsset(new FilterRuleData(assetPath));
} }
private string GetAddress(AssetBundleCollectorGroup group, string assetPath) private string GetAddress(CollectCommand command, 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)); string adressValue = addressRuleInstance.GetAssetAddress(new AddressRuleData(assetPath, CollectPath, group.GroupName, UserData));
return adressValue; return adressValue;
} }
private string GetBundleName(AssetBundleCollectorGroup group, string assetPath) private string GetBundleName(CollectCommand command, 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();
IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName); return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName);
string bundleName = packRuleInstance.GetBundleName(new PackRuleData(assetPath, CollectPath, group.GroupName)); }
return EditorTools.GetRegularPath(bundleName).ToLower(); else
{
// 获取其它资源打包规则结果
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 = StringUtility.StringToStringList(group.AssetTags, ';'); List<string> tags = EditorTools.StringToStringList(group.AssetTags, ';');
List<string> temper = StringUtility.StringToStringList(AssetTags, ';'); List<string> temper = EditorTools.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 (IsValidateAsset(assetPath, false))
{ {
// 注意:排除主资源对象 // 注意:排除主资源对象
if (assetPath != mainAssetPath) if (assetPath != mainAssetPath)

View File

@ -10,19 +10,21 @@ namespace YooAsset.Editor
{ {
public class AssetBundleCollectorConfig public class AssetBundleCollectorConfig
{ {
public const string ConfigVersion = "2.1"; public const string ConfigVersion = "2.4";
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 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";
@ -33,6 +35,7 @@ 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>
@ -65,6 +68,7 @@ namespace YooAsset.Editor
bool enableAddressable = false; bool enableAddressable = 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)
{ {
@ -75,10 +79,13 @@ namespace YooAsset.Editor
throw new Exception($"Not found attribute {XmlUniqueBundleName} in {XmlCommon}"); throw new Exception($"Not found attribute {XmlUniqueBundleName} in {XmlCommon}");
if (commonElement.HasAttribute(XmlShowPackageView) == false) if (commonElement.HasAttribute(XmlShowPackageView) == false)
throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}"); throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}");
if (commonElement.HasAttribute(XmlShowEditorAlias) == false)
throw new Exception($"Not found attribute {XmlShowEditorAlias} in {XmlCommon}");
enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false; enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false; uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false;
showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false; showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false;
showEditorAlias = commonElement.GetAttribute(XmlShowEditorAlias) == "True" ? true : false;
} }
// 读取包裹配置 // 读取包裹配置
@ -102,6 +109,8 @@ 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)
@ -110,6 +119,7 @@ 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);
@ -132,27 +142,37 @@ 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 = StringUtility.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType)); collector.CollectorType = EditorTools.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.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($"导入配置完毕!");
@ -183,6 +203,7 @@ namespace YooAsset.Editor
commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString()); commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.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配置
@ -197,6 +218,7 @@ 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);
@ -212,6 +234,7 @@ 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);
} }
@ -296,6 +319,62 @@ 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

@ -96,16 +96,17 @@ namespace YooAsset.Editor
// 检测可寻址地址是否重复 // 检测可寻址地址是否重复
if (command.EnableAddressable) if (command.EnableAddressable)
{ {
HashSet<string> adressTemper = new HashSet<string>(); var addressTemper = new Dictionary<string, 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;
if (adressTemper.Contains(address) == false) string assetPath = collectInfoPair.Value.AssetPath;
adressTemper.Add(address); 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}"); throw new Exception($"The address is existed : {address} in group : {GroupName} \nAssetPath:\n {existed}\n {assetPath}");
} }
} }
} }

View File

@ -76,16 +76,17 @@ namespace YooAsset.Editor
// 检测可寻址地址是否重复 // 检测可寻址地址是否重复
if (command.EnableAddressable) if (command.EnableAddressable)
{ {
HashSet<string> adressTemper = new HashSet<string>(); var addressTemper = new Dictionary<string, 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;
if (adressTemper.Contains(address) == false) string assetPath = collectInfoPair.Value.AssetPath;
adressTemper.Add(address); if (addressTemper.TryGetValue(address, out var existed) == false)
addressTemper.Add(address, assetPath);
else else
throw new Exception($"The address is existed : {address}"); throw new Exception($"The address is existed : {address} \nAssetPath:\n {existed}\n {assetPath}");
} }
} }
} }
@ -102,7 +103,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 = StringUtility.StringToStringList(group.AssetTags, ';'); List<string> groupTags = EditorTools.StringToStringList(group.AssetTags, ';');
foreach (var tag in groupTags) foreach (var tag in groupTags)
{ {
if (result.Contains(tag) == false) if (result.Contains(tag) == false)
@ -111,7 +112,7 @@ namespace YooAsset.Editor
foreach (var collector in group.Collectors) foreach (var collector in group.Collectors)
{ {
List<string> collectorTags = StringUtility.StringToStringList(collector.AssetTags, ';'); List<string> collectorTags = EditorTools.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,6 +6,7 @@ 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>
@ -23,6 +24,12 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool UniqueBundleName = false; public bool UniqueBundleName = false;
/// <summary>
/// 是否显示编辑器别名
/// </summary>
public bool ShowEditorAlias = false;
/// <summary> /// <summary>
/// 包裹列表 /// 包裹列表
/// </summary> /// </summary>
@ -94,8 +101,8 @@ namespace YooAsset.Editor
{ {
if (package.PackageName == packageName) if (package.PackageName == packageName)
{ {
CollectCommand command = new CollectCommand(buildMode, EnableAddressable); CollectCommand command = new CollectCommand(buildMode, packageName, EnableAddressable, UniqueBundleName);
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName); CollectResult collectResult = new CollectResult(command);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command)); collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
return collectResult; return collectResult;
} }
@ -103,21 +110,5 @@ namespace YooAsset.Editor
throw new Exception($"Not found collector pacakge : {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,110 +27,8 @@ namespace YooAsset.Editor
public static bool IsDirty { private set; get; } = false; public static bool IsDirty { private set; get; } = false;
private static AssetBundleCollectorSetting _setting = null; static AssetBundleCollectorSettingData()
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
{ {
// 清空缓存集合 // 清空缓存集合
@ -146,6 +44,7 @@ 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));
@ -193,7 +92,8 @@ namespace YooAsset.Editor
List<Type> types = new List<Type>(100) List<Type> types = new List<Type>(100)
{ {
typeof(AddressByFileName), typeof(AddressByFileName),
typeof(AddressByCollectorAndFileName), typeof(AddressByFilePath),
typeof(AddressByFolderAndFileName),
typeof(AddressByGroupAndFileName) typeof(AddressByGroupAndFileName)
}; };
@ -231,6 +131,17 @@ 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>
@ -266,7 +177,80 @@ 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))
@ -352,6 +336,11 @@ namespace YooAsset.Editor
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,22 +12,23 @@ 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 ShowExample() public static void OpenWindow()
{ {
AssetBundleCollectorWindow window = GetWindow<AssetBundleCollectorWindow>("资源包收集工具", true, EditorDefine.DockedWindowTypes); AssetBundleCollectorWindow window = GetWindow<AssetBundleCollectorWindow>("资源包收集工具", true, WindowsDefine.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<string> _activeRuleList; private List<RuleDisplayName> _activeRuleList;
private List<string> _addressRuleList; private List<RuleDisplayName> _addressRuleList;
private List<string> _packRuleList; private List<RuleDisplayName> _packRuleList;
private List<string> _filterRuleList; private List<RuleDisplayName> _filterRuleList;
private Toggle _showPackageToogle; private Toggle _showPackageToogle;
private Toggle _enableAddressableToogle; private Toggle _enableAddressableToogle;
private Toggle _uniqueBundleNameToogle; private Toggle _uniqueBundleNameToogle;
private Toggle _showEditorAliasToggle;
private VisualElement _packageContainer; private VisualElement _packageContainer;
private ListView _packageListView; private ListView _packageListView;
@ -42,7 +43,7 @@ namespace YooAsset.Editor
private VisualElement _collectorContainer; private VisualElement _collectorContainer;
private ScrollView _collectorScrollView; private ScrollView _collectorScrollView;
private PopupField<string> _activeRulePopupField; private PopupField<RuleDisplayName> _activeRulePopupField;
private int _lastModifyPackageIndex = 0; private int _lastModifyPackageIndex = 0;
private int _lastModifyGroupIndex = 0; private int _lastModifyGroupIndex = 0;
@ -69,7 +70,7 @@ namespace YooAsset.Editor
VisualElement root = this.rootVisualElement; VisualElement root = this.rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = EditorHelper.LoadWindowUXML<AssetBundleCollectorWindow>(); var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleCollectorWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
@ -95,6 +96,13 @@ namespace YooAsset.Editor
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");
fixBtn.clicked += FixBtn_clicked; fixBtn.clicked += FixBtn_clicked;
@ -140,6 +148,7 @@ namespace YooAsset.Editor
{ {
selectPackage.PackageName = evt.newValue; selectPackage.PackageName = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage); AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
FillPackageViewData();
} }
}); });
@ -152,6 +161,7 @@ namespace YooAsset.Editor
{ {
selectPackage.PackageDesc = evt.newValue; selectPackage.PackageDesc = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage); AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
FillPackageViewData();
} }
}); });
@ -236,21 +246,23 @@ namespace YooAsset.Editor
// 分组激活规则 // 分组激活规则
var activeRuleContainer = root.Q("ActiveRuleContainer"); var activeRuleContainer = root.Q("ActiveRuleContainer");
{ {
_activeRulePopupField = new PopupField<string>("Active Rule", _activeRuleList, 0); _activeRulePopupField = new PopupField<RuleDisplayName>("Active Rule", _activeRuleList, 0);
_activeRulePopupField.name = "ActiveRuleMaskField"; _activeRulePopupField.name = "ActiveRuleMaskField";
_activeRulePopupField.style.unityTextAlign = TextAnchor.MiddleLeft; _activeRulePopupField.style.unityTextAlign = TextAnchor.MiddleLeft;
activeRuleContainer.Add(_activeRulePopupField); _activeRulePopupField.formatListItemCallback = FormatListItemCallback;
_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; selectGroup.ActiveRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup); AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
FillGroupViewData(); FillGroupViewData();
} }
}); });
activeRuleContainer.Add(_activeRulePopupField);
} }
// 刷新窗体 // 刷新窗体
@ -290,6 +302,9 @@ namespace YooAsset.Editor
{ {
_showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView); _showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView);
_enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable); _enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable);
_uniqueBundleNameToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.UniqueBundleName);
_showEditorAliasToggle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowEditorAlias);
_groupContainer.visible = false; _groupContainer.visible = false;
_collectorContainer.visible = false; _collectorContainer.visible = false;
@ -321,6 +336,20 @@ namespace YooAsset.Editor
{ {
AssetBundleCollectorSettingData.SaveFile(); AssetBundleCollectorSettingData.SaveFile();
} }
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()
@ -334,7 +363,7 @@ namespace YooAsset.Editor
{ {
_packageListView.selectedIndex = _lastModifyPackageIndex; _packageListView.selectedIndex = _lastModifyPackageIndex;
} }
if (_showPackageToogle.value) if (_showPackageToogle.value)
_packageContainer.style.display = DisplayStyle.Flex; _packageContainer.style.display = DisplayStyle.Flex;
else else
@ -410,7 +439,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;
} }
@ -460,7 +489,7 @@ namespace YooAsset.Editor
_collectorContainer.visible = true; _collectorContainer.visible = true;
_lastModifyGroupIndex = _groupListView.selectedIndex; _lastModifyGroupIndex = _groupListView.selectedIndex;
_activeRulePopupField.SetValueWithoutNotify(selectGroup.ActiveRuleName); _activeRulePopupField.SetValueWithoutNotify(GetActiveRuleIndex(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);
@ -564,26 +593,35 @@ namespace YooAsset.Editor
} }
if (_enableAddressableToogle.value) if (_enableAddressableToogle.value)
{ {
var popupField = new PopupField<string>(_addressRuleList, 0); var popupField = new PopupField<RuleDisplayName>(_addressRuleList, 0);
popupField.name = "PopupField1"; popupField.name = "PopupField1";
popupField.style.unityTextAlign = TextAnchor.MiddleLeft; popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
popupField.style.width = 200; popupField.style.width = 220;
elementBottom.Add(popupField); elementBottom.Add(popupField);
} }
{ {
var popupField = new PopupField<string>(_packRuleList, 0); var popupField = new PopupField<RuleDisplayName>(_packRuleList, 0);
popupField.name = "PopupField2"; popupField.name = "PopupField2";
popupField.style.unityTextAlign = TextAnchor.MiddleLeft; popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
popupField.style.width = 150; popupField.style.width = 220;
elementBottom.Add(popupField); elementBottom.Add(popupField);
} }
{ {
var popupField = new PopupField<string>(_filterRuleList, 0); var popupField = new PopupField<RuleDisplayName>(_filterRuleList, 0);
popupField.name = "PopupField3"; popupField.name = "PopupField3";
popupField.style.unityTextAlign = TextAnchor.MiddleLeft; popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
popupField.style.width = 150; popupField.style.width = 150;
elementBottom.Add(popupField); elementBottom.Add(popupField);
} }
{
var textField = new TextField();
textField.name = "TextField0";
textField.label = "UserData";
textField.style.width = 200;
elementBottom.Add(textField);
var label = textField.Q<Label>();
label.style.minWidth = 63;
}
{ {
var textField = new TextField(); var textField = new TextField();
textField.name = "TextField1"; textField.name = "TextField1";
@ -667,7 +705,7 @@ namespace YooAsset.Editor
popupField0.index = GetCollectorTypeIndex(collector.CollectorType.ToString()); popupField0.index = GetCollectorTypeIndex(collector.CollectorType.ToString());
popupField0.RegisterValueChangedCallback(evt => popupField0.RegisterValueChangedCallback(evt =>
{ {
collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(evt.newValue); collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue);
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -676,13 +714,15 @@ namespace YooAsset.Editor
}); });
// Address Rule // Address Rule
var popupField1 = element.Q<PopupField<string>>("PopupField1"); var popupField1 = element.Q<PopupField<RuleDisplayName>>("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; collector.AddressRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -692,11 +732,13 @@ namespace YooAsset.Editor
} }
// Pack Rule // Pack Rule
var popupField2 = element.Q<PopupField<string>>("PopupField2"); var popupField2 = element.Q<PopupField<RuleDisplayName>>("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; collector.PackRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -705,11 +747,13 @@ namespace YooAsset.Editor
}); });
// Filter Rule // Filter Rule
var popupField3 = element.Q<PopupField<string>>("PopupField3"); var popupField3 = element.Q<PopupField<RuleDisplayName>>("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; collector.FilterRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
@ -717,6 +761,15 @@ 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);
@ -743,7 +796,7 @@ namespace YooAsset.Editor
try try
{ {
CollectCommand command = new CollectCommand(EBuildMode.DryRunBuild, _enableAddressableToogle.value); CollectCommand command = new CollectCommand(EBuildMode.SimulateBuild, _packageNameTxt.value, _enableAddressableToogle.value, _uniqueBundleNameToogle.value);
collectAssetInfos = collector.GetAllCollectAssets(command, group); collectAssetInfos = collector.GetAllCollectAssets(command, group);
} }
catch (System.Exception e) catch (System.Exception e)
@ -761,12 +814,7 @@ 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;
@ -815,7 +863,7 @@ namespace YooAsset.Editor
{ {
for (int i = 0; i < _addressRuleList.Count; i++) for (int i = 0; i < _addressRuleList.Count; i++)
{ {
if (_addressRuleList[i] == ruleName) if (_addressRuleList[i].ClassName == ruleName)
return i; return i;
} }
return 0; return 0;
@ -824,7 +872,7 @@ namespace YooAsset.Editor
{ {
for (int i = 0; i < _packRuleList.Count; i++) for (int i = 0; i < _packRuleList.Count; i++)
{ {
if (_packRuleList[i] == ruleName) if (_packRuleList[i].ClassName == ruleName)
return i; return i;
} }
return 0; return 0;
@ -833,11 +881,20 @@ namespace YooAsset.Editor
{ {
for (int i = 0; i < _filterRuleList.Count; i++) for (int i = 0; i < _filterRuleList.Count; i++)
{ {
if (_filterRuleList[i] == ruleName) if (_filterRuleList[i].ClassName == 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,4 +1,4 @@
<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"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<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);" />
@ -7,6 +7,7 @@
</uie:Toolbar> </uie:Toolbar>
<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="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:Toggle label="Show Packages" name="ShowPackages" 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="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:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement> </ui:VisualElement>

View File

@ -14,7 +14,7 @@ namespace YooAsset.Editor
/// 资源包名称 /// 资源包名称
/// </summary> /// </summary>
public string BundleName { private set; get; } public string BundleName { private set; get; }
/// <summary> /// <summary>
/// 可寻址地址 /// 可寻址地址
/// </summary> /// </summary>
@ -25,38 +25,30 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string AssetPath { private set; get; } public string AssetPath { private set; get; }
/// <summary>
/// 资源分类标签
/// </summary>
public List<string> AssetTags { private set; get; }
/// <summary> /// <summary>
/// 是否为原生资源 /// 是否为原生资源
/// </summary> /// </summary>
public bool IsRawAsset { private set; get; } public bool IsRawAsset { private set; get; }
/// <summary>
/// 资源分类标签
/// </summary>
public List<string> AssetTags { 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, List<string> assetTags, bool isRawAsset) public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset, List<string> assetTags)
{ {
CollectorType = collectorType; CollectorType = collectorType;
BundleName = bundleName; BundleName = bundleName;
Address = address; Address = address;
AssetPath = assetPath; AssetPath = assetPath;
AssetTags = assetTags;
IsRawAsset = isRawAsset; IsRawAsset = isRawAsset;
} AssetTags = assetTags;
/// <summary>
/// 资源包名称追加包裹名
/// </summary>
public void BundleNameAppendPackageName(string packageName)
{
BundleName = $"{packageName.ToLower()}_{BundleName}";
} }
} }
} }

View File

@ -8,15 +8,37 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public EBuildMode BuildMode { private set; get; } public EBuildMode BuildMode { private set; get; }
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary> /// <summary>
/// 是否启用可寻址资源定位 /// 是否启用可寻址资源定位
/// </summary> /// </summary>
public bool EnableAddressable { private set; get; } public bool EnableAddressable { private set; get; }
public CollectCommand(EBuildMode buildMode, bool enableAddressable) /// <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 uniqueBundleName)
{ {
BuildMode = buildMode; BuildMode = buildMode;
PackageName = packageName;
EnableAddressable = enableAddressable; EnableAddressable = enableAddressable;
UniqueBundleName = uniqueBundleName;
// 着色器统一全名称
var packRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
ShadersBundleName = packRuleResult.GetMainBundleName(packageName, uniqueBundleName);
} }
} }
} }

View File

@ -6,44 +6,22 @@ namespace YooAsset.Editor
public class CollectResult public class CollectResult
{ {
/// <summary> /// <summary>
/// 包裹名称 /// 收集命令
/// </summary> /// </summary>
public string PackageName { private set; get; } public CollectCommand Command { 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)
{ {
PackageName = packageName; Command = command;
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,9 +1,7 @@
 
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
/// <summary> [DisplayName("启用分组")]
/// 启用分组
/// </summary>
public class EnableGroup : IActiveRule public class EnableGroup : IActiveRule
{ {
public bool IsActiveGroup() public bool IsActiveGroup()
@ -12,9 +10,7 @@ namespace YooAsset.Editor
} }
} }
/// <summary> [DisplayName("禁用分组")]
/// 禁用分组
/// </summary>
public class DisableGroup : IActiveRule public class DisableGroup : IActiveRule
{ {
public bool IsActiveGroup() public bool IsActiveGroup()

View File

@ -2,9 +2,7 @@
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
/// <summary> [DisplayName("定位地址: 文件名")]
/// 以文件名为定位地址
/// </summary>
public class AddressByFileName : IAddressRule public class AddressByFileName : IAddressRule
{ {
string IAddressRule.GetAssetAddress(AddressRuleData data) string IAddressRule.GetAssetAddress(AddressRuleData data)
@ -13,9 +11,16 @@ namespace YooAsset.Editor
} }
} }
/// <summary> [DisplayName("定位地址: 文件路径")]
/// 以组名+文件名为定位地址 public class AddressByFilePath : IAddressRule
/// </summary> {
string IAddressRule.GetAssetAddress(AddressRuleData data)
{
return data.AssetPath;
}
}
[DisplayName("定位地址: 分组名+文件名")]
public class AddressByGroupAndFileName : IAddressRule public class AddressByGroupAndFileName : IAddressRule
{ {
string IAddressRule.GetAssetAddress(AddressRuleData data) string IAddressRule.GetAssetAddress(AddressRuleData data)
@ -25,16 +30,14 @@ namespace YooAsset.Editor
} }
} }
/// <summary> [DisplayName("定位地址: 文件夹名+文件名")]
/// 以收集器名+文件名为定位地址 public class AddressByFolderAndFileName : IAddressRule
/// </summary>
public class AddressByCollectorAndFileName : IAddressRule
{ {
string IAddressRule.GetAssetAddress(AddressRuleData data) string IAddressRule.GetAssetAddress(AddressRuleData data)
{ {
string fileName = Path.GetFileNameWithoutExtension(data.AssetPath); string fileName = Path.GetFileNameWithoutExtension(data.AssetPath);
string collectorName = Path.GetFileNameWithoutExtension(data.CollectPath); FileInfo fileInfo = new FileInfo(data.AssetPath);
return $"{collectorName}_{fileName}"; return $"{fileInfo.Directory.Name}_{fileName}";
} }
} }
} }

View File

@ -1,12 +1,28 @@
using UnityEngine; using System.Collections;
using UnityEditor; using System.Collections.Generic;
using System.IO; using System.IO;
using UnityEngine;
using UnityEditor;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
/// <summary> public class DefaultFilterRule
/// 收集所有资源 {
/// </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)
@ -15,9 +31,7 @@ namespace YooAsset.Editor
} }
} }
/// <summary> [DisplayName("收集场景")]
/// 只收集场景
/// </summary>
public class CollectScene : IFilterRule public class CollectScene : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)
@ -25,10 +39,8 @@ namespace YooAsset.Editor
return Path.GetExtension(data.AssetPath) == ".unity"; return Path.GetExtension(data.AssetPath) == ".unity";
} }
} }
/// <summary> [DisplayName("收集预制体")]
/// 只收集预制体
/// </summary>
public class CollectPrefab : IFilterRule public class CollectPrefab : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)
@ -37,15 +49,13 @@ namespace YooAsset.Editor
} }
} }
/// <summary> [DisplayName("收集精灵类型的纹理")]
/// 只收集精灵类型的资源
/// </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)
@ -60,9 +70,7 @@ namespace YooAsset.Editor
} }
} }
/// <summary> [DisplayName("收集着色器变种集合")]
/// 只收集着色器变种收集文件
/// </summary>
public class CollectShaderVariants : IFilterRule public class CollectShaderVariants : IFilterRule
{ {
public bool IsCollectAsset(FilterRuleData data) public bool IsCollectAsset(FilterRuleData data)

View File

@ -4,18 +4,50 @@ using UnityEditor;
namespace YooAsset.Editor 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> /// <summary>
/// 以文件路径作为资源包名 /// 以文件路径作为资源包名
/// 注意:每个文件独自打资源包 /// 注意:每个文件独自打资源包
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image_backgroud.bundle" /// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image_backgroud.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view_main.bundle" /// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view_main.bundle"
/// </summary> /// </summary>
[DisplayName("资源包名: 文件路径")]
public class PackSeparately : IPackRule public class PackSeparately : IPackRule
{ {
string IPackRule.GetBundleName(PackRuleData data) PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{ {
string bundleName = StringUtility.RemoveExtension(data.AssetPath); string bundleName = PathUtility.RemoveExtension(data.AssetPath);
return EditorTools.GetRegularPath(bundleName).Replace('/', '_'); PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
} }
} }
@ -25,14 +57,19 @@ namespace YooAsset.Editor
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image.bundle" /// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view.bundle" /// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view.bundle"
/// </summary> /// </summary>
[DisplayName("资源包名: 父类文件夹路径")]
public class PackDirectory : IPackRule public class PackDirectory : IPackRule
{ {
public static PackDirectory StaticPackRule = new PackDirectory(); PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
string IPackRule.GetBundleName(PackRuleData data)
{ {
string bundleName = Path.GetDirectoryName(data.AssetPath); string bundleName = Path.GetDirectoryName(data.AssetPath);
return EditorTools.GetRegularPath(bundleName).Replace('/', '_'); PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
} }
} }
@ -43,9 +80,10 @@ namespace YooAsset.Editor
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop.bundle" /// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop.bundle"
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop.bundle" /// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop.bundle"
/// </summary> /// </summary>
[DisplayName("资源包名: 收集器下顶级文件夹路径")]
public class PackTopDirectory : IPackRule public class PackTopDirectory : IPackRule
{ {
string IPackRule.GetBundleName(PackRuleData data) PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{ {
string assetPath = data.AssetPath.Replace(data.CollectPath, string.Empty); string assetPath = data.AssetPath.Replace(data.CollectPath, string.Empty);
assetPath = assetPath.TrimStart('/'); assetPath = assetPath.TrimStart('/');
@ -55,34 +93,48 @@ namespace YooAsset.Editor
if (Path.HasExtension(splits[0])) if (Path.HasExtension(splits[0]))
throw new Exception($"Not found root directory : {assetPath}"); throw new Exception($"Not found root directory : {assetPath}");
string bundleName = $"{data.CollectPath}/{splits[0]}"; string bundleName = $"{data.CollectPath}/{splits[0]}";
return EditorTools.GetRegularPath(bundleName).Replace('/', '_'); PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
} }
else else
{ {
throw new Exception($"Not found root directory : {assetPath}"); throw new Exception($"Not found root directory : {assetPath}");
} }
} }
bool IPackRule.IsRawFilePackRule()
{
return false;
}
} }
/// <summary> /// <summary>
/// 以收集器路径作为资源包名 /// 以收集器路径作为资源包名
/// 注意:收集的所有文件打进一个资源包 /// 注意:收集的所有文件打进一个资源包
/// </summary> /// </summary>
[DisplayName("资源包名: 收集器路径")]
public class PackCollector : IPackRule public class PackCollector : IPackRule
{ {
string IPackRule.GetBundleName(PackRuleData data) PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{ {
string bundleName;
string collectPath = data.CollectPath; string collectPath = data.CollectPath;
if (AssetDatabase.IsValidFolder(collectPath)) if (AssetDatabase.IsValidFolder(collectPath))
{ {
string bundleName = collectPath; bundleName = collectPath;
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
} }
else else
{ {
string bundleName = StringUtility.RemoveExtension(collectPath); bundleName = PathUtility.RemoveExtension(collectPath);
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
} }
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
} }
} }
@ -90,49 +142,55 @@ namespace YooAsset.Editor
/// 以分组名称作为资源包名 /// 以分组名称作为资源包名
/// 注意:收集的所有文件打进一个资源包 /// 注意:收集的所有文件打进一个资源包
/// </summary> /// </summary>
[DisplayName("资源包名: 分组名称")]
public class PackGroup : IPackRule public class PackGroup : IPackRule
{ {
string IPackRule.GetBundleName(PackRuleData data) PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
{ {
return data.GroupName; string bundleName = data.GroupName;
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return false;
} }
} }
/// <summary> /// <summary>
/// 原生文件打包模式 /// 打包原生文件
/// 注意:原生文件打包支持:图片,音频,视频,文本
/// </summary> /// </summary>
[DisplayName("打包原生文件")]
public class PackRawFile : IPackRule public class PackRawFile : IPackRule
{ {
string IPackRule.GetBundleName(PackRuleData data) PackRuleResult IPackRule.GetPackRuleResult(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; string bundleName = data.AssetPath;
return EditorTools.GetRegularPath(bundleName).Replace('/', '_').Replace('.', '_'); PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.RawFileExtension);
return result;
}
bool IPackRule.IsRawFilePackRule()
{
return true;
} }
} }
/// <summary> /// <summary>
/// 着色器变种收集文件 /// 打包着色器变种集合
/// </summary> /// </summary>
[DisplayName("打包着色器变种集合文件")]
public class PackShaderVariants : IPackRule public class PackShaderVariants : IPackRule
{ {
public string GetBundleName(PackRuleData data) public PackRuleResult GetPackRuleResult(PackRuleData data)
{ {
return YooAssetSettings.UnityShadersBundleName; return DefaultPackRule.CreateShadersPackRuleResult();
}
bool IPackRule.IsRawFilePackRule()
{
return false;
} }
} }
} }

View File

@ -0,0 +1,16 @@
using System;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
public class DefaultShareAssetPackRule : IShareAssetPackRule
{
public PackRuleResult GetPackRuleResult(string assetPath)
{
string bundleName = Path.GetDirectoryName(assetPath);
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
}
}

View File

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

View File

@ -0,0 +1,36 @@
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

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

View File

@ -6,12 +6,14 @@ 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) public AddressRuleData(string assetPath, string collectPath, string groupName, string userData)
{ {
AssetPath = assetPath; AssetPath = assetPath;
CollectPath = collectPath; CollectPath = collectPath;
GroupName = groupName; GroupName = groupName;
UserData = userData;
} }
} }

View File

@ -3,21 +3,64 @@ namespace YooAsset.Editor
{ {
public struct PackRuleData public struct PackRuleData
{ {
public string AssetPath; public string AssetPath;
public string CollectPath; public string CollectPath;
public string GroupName; public string GroupName;
public string UserData;
public PackRuleData(string assetPath) public PackRuleData(string assetPath)
{ {
AssetPath = assetPath; AssetPath = assetPath;
CollectPath = string.Empty; CollectPath = string.Empty;
GroupName = string.Empty; GroupName = string.Empty;
UserData = string.Empty;
} }
public PackRuleData(string assetPath, string collectPath, string groupName) public PackRuleData(string assetPath, string collectPath, string groupName, string userData)
{ {
AssetPath = assetPath; AssetPath = assetPath;
CollectPath = collectPath; CollectPath = collectPath;
GroupName = groupName; 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('.', '_').ToLower();
if (uniqueBundleName)
fullName = $"{packageName}_{bundleName}.{_bundleExtension}";
else
fullName = $"{bundleName}.{_bundleExtension}";
return fullName.ToLower();
}
/// <summary>
/// 获取共享资源包全名称
/// </summary>
public string GetShareBundleName(string packageName, bool uniqueBundleName)
{
string fullName;
string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower();
if (uniqueBundleName)
fullName = $"{packageName}_share_{bundleName}.{_bundleExtension}";
else
fullName = $"share_{bundleName}.{_bundleExtension}";
return fullName.ToLower();
} }
} }
@ -27,8 +70,13 @@ namespace YooAsset.Editor
public interface IPackRule public interface IPackRule
{ {
/// <summary> /// <summary>
/// 获取资源打包所属的资源包名称 /// 获取打包规则结果
/// </summary> /// </summary>
string GetBundleName(PackRuleData data); PackRuleResult GetPackRuleResult(PackRuleData data);
/// <summary>
/// 是否为原生文件打包规则
/// </summary>
bool IsRawFilePackRule();
} }
} }

View File

@ -0,0 +1,14 @@

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

View File

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

View File

@ -0,0 +1,9 @@

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

View File

@ -0,0 +1,11 @@
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 ShowExample() public static void OpenWindow()
{ {
AssetBundleDebuggerWindow wnd = GetWindow<AssetBundleDebuggerWindow>("资源包调试工具", true, EditorDefine.DockedWindowTypes); AssetBundleDebuggerWindow wnd = GetWindow<AssetBundleDebuggerWindow>("资源包调试工具", true, WindowsDefine.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 = EditorHelper.LoadWindowUXML<AssetBundleDebuggerWindow>(); var visualAsset = UxmlLoader.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.CreateFile(filePath, fileContent); FileUtility.WriteAllText(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 = EditorHelper.LoadWindowUXML<DebuggerAssetListViewer>(); _visualAsset = UxmlLoader.LoadWindowUXML<DebuggerAssetListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -45,6 +45,10 @@ 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 = EditorHelper.LoadWindowUXML<DebuggerBundleListViewer>(); _visualAsset = UxmlLoader.LoadWindowUXML<DebuggerBundleListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -45,6 +45,10 @@ 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 ShowExample() public static void OpenWindow()
{ {
AssetBundleReporterWindow window = GetWindow<AssetBundleReporterWindow>("资源包报告工具", true, EditorDefine.DockedWindowTypes); AssetBundleReporterWindow window = GetWindow<AssetBundleReporterWindow>("资源包报告工具", true, WindowsDefine.DockedWindowTypes);
window.minSize = new Vector2(800, 600); window.minSize = new Vector2(800, 600);
} }
@ -35,12 +35,18 @@ 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;
@ -55,7 +61,7 @@ namespace YooAsset.Editor
VisualElement root = this.rootVisualElement; VisualElement root = this.rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = EditorHelper.LoadWindowUXML<AssetBundleReporterWindow>(); var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleReporterWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
@ -70,6 +76,7 @@ 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");
@ -87,6 +94,10 @@ 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();
@ -109,11 +120,12 @@ namespace YooAsset.Editor
return; return;
_reportFilePath = selectFilePath; _reportFilePath = selectFilePath;
string jsonData = FileUtility.ReadFile(_reportFilePath); string jsonData = FileUtility.ReadAllText(_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);
_summaryViewer.FillViewData(_buildReport); _redundancyListViewer.FillViewData(_buildReport, _searchKeyWord);
} }
private void OnSearchKeyWordChange(ChangeEvent<string> e) private void OnSearchKeyWordChange(ChangeEvent<string> e)
{ {
@ -134,6 +146,7 @@ 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)
@ -146,6 +159,7 @@ 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)
@ -158,6 +172,20 @@ 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)
@ -181,6 +209,13 @@ 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

@ -38,7 +38,7 @@ namespace YooAsset.Editor
public void InitViewer() public void InitViewer()
{ {
// 加载布局文件 // 加载布局文件
_visualAsset = EditorHelper.LoadWindowUXML<ReporterAssetListViewer>(); _visualAsset = UxmlLoader.LoadWindowUXML<ReporterAssetListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -68,6 +68,10 @@ 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" editor-extension-mode="False"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<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;" /> <ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1; flex-basis: 60px;" />
</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 = EditorHelper.LoadWindowUXML<ReporterBundleListViewer>(); _visualAsset = UxmlLoader.LoadWindowUXML<ReporterBundleListViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -76,6 +76,10 @@ 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>

View File

@ -1,21 +1,19 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="Viewer" style="flex-grow: 1; 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;">
<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="Bundle Name" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
<uie:ToolbarButton text="Bundle Name" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" /> <uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="TopBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="Size" display-tooltip-when-elided="true" name="TopBar2" style="width: 100px; -unity-text-align: middle-left; flex-grow: 0;" /> <uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="TopBar3" style="width: 280px; -unity-text-align: middle-left;" />
<uie:ToolbarButton text="Hash" display-tooltip-when-elided="true" name="TopBar3" style="width: 280px; -unity-text-align: middle-left;" /> <uie:ToolbarButton text="LoadMethod" display-tooltip-when-elided="true" name="TopBar4" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
<uie:ToolbarButton text="LoadMethod" display-tooltip-when-elided="true" name="TopBar4" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" /> <uie:ToolbarButton text="Tags" display-tooltip-when-elided="true" name="TopBar5" style="width: 80px; -unity-text-align: middle-left; flex-grow: 1;" />
<uie:ToolbarButton text="Tags" display-tooltip-when-elided="true" name="TopBar5" style="width: 80px; -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;"> <uie:ToolbarButton text="Include Assets" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
<uie:ToolbarButton text="Include Assets" display-tooltip-when-elided="true" name="BottomBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" /> <uie:ToolbarButton text="GUID" display-tooltip-when-elided="true" name="BottomBar2" style="width: 280px; -unity-text-align: middle-left;" />
<uie:ToolbarButton text="GUID" display-tooltip-when-elided="true" name="BottomBar2" style="width: 280px; -unity-text-align: middle-left;" /> </uie:Toolbar>
</uie:Toolbar> <ui:ListView focusable="true" name="BottomListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
<ui:ListView focusable="true" name="BottomListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
</ui:VisualElement>
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@ -0,0 +1,317 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
internal class ReporterRedundancyListViewer
{
private enum ESortMode
{
AssetPath,
AssetType,
FileSize,
Number,
}
private VisualTreeAsset _visualAsset;
private TemplateContainer _root;
private ToolbarButton _topBar1;
private ToolbarButton _topBar2;
private ToolbarButton _topBar3;
private ToolbarButton _topBar4;
private ListView _assetListView;
private BuildReport _buildReport;
private string _searchKeyWord;
private ESortMode _sortMode = ESortMode.AssetPath;
private bool _descendingSort = false;
/// <summary>
/// 初始化页面
/// </summary>
public void InitViewer()
{
// 加载布局文件
_visualAsset = UxmlLoader.LoadWindowUXML<ReporterRedundancyListViewer>();
if (_visualAsset == null)
return;
_root = _visualAsset.CloneTree();
_root.style.flexGrow = 1f;
// 顶部按钮栏
_topBar1 = _root.Q<ToolbarButton>("TopBar1");
_topBar2 = _root.Q<ToolbarButton>("TopBar2");
_topBar3 = _root.Q<ToolbarButton>("TopBar3");
_topBar4 = _root.Q<ToolbarButton>("TopBar4");
_topBar1.clicked += TopBar1_clicked;
_topBar2.clicked += TopBar2_clicked;
_topBar3.clicked += TopBar3_clicked;
_topBar4.clicked += TopBar4_clicked;
// 资源列表
_assetListView = _root.Q<ListView>("TopListView");
_assetListView.makeItem = MakeAssetListViewItem;
_assetListView.bindItem = BindAssetListViewItem;
}
/// <summary>
/// 填充页面数据
/// </summary>
public void FillViewData(BuildReport buildReport, string searchKeyWord)
{
_buildReport = buildReport;
_searchKeyWord = searchKeyWord;
RefreshView();
}
private void RefreshView()
{
_assetListView.Clear();
_assetListView.ClearSelection();
_assetListView.itemsSource = FilterAndSortViewItems();
_assetListView.Rebuild();
RefreshSortingSymbol();
}
private List<ReportRedundancyInfo> FilterAndSortViewItems()
{
List<ReportRedundancyInfo> result = new List<ReportRedundancyInfo>(_buildReport.RedundancyInfos.Count);
// 过滤列表
foreach (var redundancyInfo in _buildReport.RedundancyInfos)
{
if (string.IsNullOrEmpty(_searchKeyWord) == false)
{
if (redundancyInfo.AssetPath.Contains(_searchKeyWord) == false)
continue;
}
result.Add(redundancyInfo);
}
// 排序列表
if (_sortMode == ESortMode.AssetPath)
{
if (_descendingSort)
return result.OrderByDescending(a => a.AssetPath).ToList();
else
return result.OrderBy(a => a.AssetPath).ToList();
}
else if(_sortMode == ESortMode.AssetType)
{
if (_descendingSort)
return result.OrderByDescending(a => a.AssetType).ToList();
else
return result.OrderBy(a => a.AssetType).ToList();
}
else if (_sortMode == ESortMode.FileSize)
{
if (_descendingSort)
return result.OrderByDescending(a => a.FileSize).ToList();
else
return result.OrderBy(a => a.FileSize).ToList();
}
else if (_sortMode == ESortMode.Number)
{
if (_descendingSort)
return result.OrderByDescending(a => a.Number).ToList();
else
return result.OrderBy(a => a.Number).ToList();
}
else
{
throw new System.NotImplementedException();
}
}
private void RefreshSortingSymbol()
{
_topBar1.text = $"Asset Path ({_assetListView.itemsSource.Count})";
_topBar2.text = "Asset Type";
_topBar3.text = "File Size";
_topBar4.text = "Redundancy Num";
if (_sortMode == ESortMode.AssetPath)
{
if (_descendingSort)
_topBar1.text = $"Asset Path ({_assetListView.itemsSource.Count}) ↓";
else
_topBar1.text = $"Asset Path ({_assetListView.itemsSource.Count}) ↑";
}
else if(_sortMode == ESortMode.AssetType)
{
if (_descendingSort)
_topBar2.text = "Asset Type ↓";
else
_topBar2.text = "Asset Type ↑";
}
else if (_sortMode == ESortMode.FileSize)
{
if (_descendingSort)
_topBar3.text = "File Size ↓";
else
_topBar3.text = "File Size ↑";
}
else if (_sortMode == ESortMode.Number)
{
if (_descendingSort)
_topBar4.text = "Redundancy Num ↓";
else
_topBar4.text = "Redundancy Num ↑";
}
else
{
throw new System.NotImplementedException();
}
}
/// <summary>
/// 挂接到父类页面上
/// </summary>
public void AttachParent(VisualElement parent)
{
parent.Add(_root);
}
/// <summary>
/// 从父类页面脱离开
/// </summary>
public void DetachParent()
{
_root.RemoveFromHierarchy();
}
// 资源列表相关
private VisualElement MakeAssetListViewItem()
{
VisualElement element = new VisualElement();
element.style.flexDirection = FlexDirection.Row;
{
var label = new Label();
label.name = "Label1";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
label.style.flexGrow = 1f;
label.style.width = 280;
element.Add(label);
}
{
var label = new Label();
label.name = "Label2";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
label.style.flexGrow = 0;
label.style.width = 125;
element.Add(label);
}
{
var label = new Label();
label.name = "Label3";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
label.style.flexGrow = 0;
label.style.width = 125;
element.Add(label);
}
{
var label = new Label();
label.name = "Label4";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.marginLeft = 3f;
label.style.flexGrow = 0;
label.style.width = 125;
element.Add(label);
}
return element;
}
private void BindAssetListViewItem(VisualElement element, int index)
{
var sourceData = _assetListView.itemsSource as List<ReportRedundancyInfo>;
var redundancyInfo = sourceData[index];
// Asset Path
var label1 = element.Q<Label>("Label1");
label1.text = redundancyInfo.AssetPath;
// Asset Type
var label2 = element.Q<Label>("Label2");
label2.text = redundancyInfo.AssetType;
// File Size
var label3 = element.Q<Label>("Label3");
label3.text = EditorUtility.FormatBytes(redundancyInfo.FileSize);
// Number
var label4 = element.Q<Label>("Label4");
label4.text = redundancyInfo.Number.ToString();
}
private void TopBar1_clicked()
{
if (_sortMode != ESortMode.AssetPath)
{
_sortMode = ESortMode.AssetPath;
_descendingSort = false;
RefreshView();
}
else
{
_descendingSort = !_descendingSort;
RefreshView();
}
}
private void TopBar2_clicked()
{
if (_sortMode != ESortMode.AssetType)
{
_sortMode = ESortMode.AssetType;
_descendingSort = false;
RefreshView();
}
else
{
_descendingSort = !_descendingSort;
RefreshView();
}
}
private void TopBar3_clicked()
{
if (_sortMode != ESortMode.FileSize)
{
_sortMode = ESortMode.FileSize;
_descendingSort = false;
RefreshView();
}
else
{
_descendingSort = !_descendingSort;
RefreshView();
}
}
private void TopBar4_clicked()
{
if (_sortMode != ESortMode.Number)
{
_sortMode = ESortMode.Number;
_descendingSort = false;
RefreshView();
}
else
{
_descendingSort = !_descendingSort;
RefreshView();
}
}
}
}
#endif

View File

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

View File

@ -0,0 +1,11 @@
<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;">
<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 Type" display-tooltip-when-elided="true" name="TopBar2" style="width: 125px; -unity-text-align: middle-left; flex-grow: 0; flex-shrink: 1;" />
<uie:ToolbarButton text="File Size" display-tooltip-when-elided="true" name="TopBar3" style="width: 125px; -unity-text-align: middle-left; flex-grow: 0; flex-shrink: 1;" />
<uie:ToolbarButton text="Redundancy Num" display-tooltip-when-elided="true" name="TopBar4" style="width: 125px; -unity-text-align: middle-left; flex-grow: 0; flex-shrink: 1;" />
</uie:Toolbar>
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1; flex-basis: 60px;" />
</ui:VisualElement>
</ui:UXML>

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a5296d9c037ce3944b5c197cbdd78a8b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View File

@ -27,7 +27,6 @@ namespace YooAsset.Editor
private TemplateContainer _root; private TemplateContainer _root;
private ListView _listView; private ListView _listView;
private BuildReport _buildReport;
private readonly List<ItemWrapper> _items = new List<ItemWrapper>(); private readonly List<ItemWrapper> _items = new List<ItemWrapper>();
@ -37,7 +36,7 @@ namespace YooAsset.Editor
public void InitViewer() public void InitViewer()
{ {
// 加载布局文件 // 加载布局文件
_visualAsset = EditorHelper.LoadWindowUXML<ReporterSummaryViewer>(); _visualAsset = UxmlLoader.LoadWindowUXML<ReporterSummaryViewer>();
if (_visualAsset == null) if (_visualAsset == null)
return; return;
@ -55,14 +54,12 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public void FillViewData(BuildReport buildReport) public void FillViewData(BuildReport buildReport)
{ {
_buildReport = buildReport;
_items.Clear(); _items.Clear();
_items.Add(new ItemWrapper("YooAsset版本", buildReport.Summary.YooVersion)); _items.Add(new ItemWrapper("YooAsset版本", buildReport.Summary.YooVersion));
_items.Add(new ItemWrapper("引擎版本", buildReport.Summary.UnityVersion)); _items.Add(new ItemWrapper("引擎版本", buildReport.Summary.UnityVersion));
_items.Add(new ItemWrapper("构建时间", buildReport.Summary.BuildDate)); _items.Add(new ItemWrapper("构建时间", buildReport.Summary.BuildDate));
_items.Add(new ItemWrapper("构建耗时", $"{buildReport.Summary.BuildSeconds}秒")); _items.Add(new ItemWrapper("构建耗时", ConvertTime(buildReport.Summary.BuildSeconds)));
_items.Add(new ItemWrapper("构建平台", $"{buildReport.Summary.BuildTarget}")); _items.Add(new ItemWrapper("构建平台", $"{buildReport.Summary.BuildTarget}"));
_items.Add(new ItemWrapper("构建管线", $"{buildReport.Summary.BuildPipeline}")); _items.Add(new ItemWrapper("构建管线", $"{buildReport.Summary.BuildPipeline}"));
_items.Add(new ItemWrapper("构建模式", $"{buildReport.Summary.BuildMode}")); _items.Add(new ItemWrapper("构建模式", $"{buildReport.Summary.BuildMode}"));
@ -71,7 +68,9 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}")); _items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}"));
_items.Add(new ItemWrapper("资源包名唯一化", $"{buildReport.Summary.UniqueBundleName}")); _items.Add(new ItemWrapper("资源包名唯一化", $"{buildReport.Summary.UniqueBundleName}"));
_items.Add(new ItemWrapper("加密服务类名称", $"{buildReport.Summary.EncryptionServicesClassName}")); _items.Add(new ItemWrapper("自动分析冗余资源", $"{buildReport.Summary.AutoAnalyzeRedundancy}"));
_items.Add(new ItemWrapper("共享资源的打包类名称", buildReport.Summary.ShareAssetPackRuleClassName));
_items.Add(new ItemWrapper("加密服务类名称", buildReport.Summary.EncryptionServicesClassName));
_items.Add(new ItemWrapper(string.Empty, string.Empty)); _items.Add(new ItemWrapper(string.Empty, string.Empty));
_items.Add(new ItemWrapper("构建参数", string.Empty)); _items.Add(new ItemWrapper("构建参数", string.Empty));
@ -154,16 +153,23 @@ namespace YooAsset.Editor
label2.text = itemWrapper.Value; label2.text = itemWrapper.Value;
} }
private string ConvertTime(int time)
{
if (time <= 60)
{
return $"{time}秒钟";
}
else
{
int minute = time / 60;
return $"{minute}分钟";
}
}
private string ConvertSize(long size) private string ConvertSize(long size)
{ {
if (size == 0) if (size == 0)
return "0"; return "0";
if (size < 1024) return EditorUtility.FormatBytes(size);
return $"{size} Bytes";
else if (size < 1024 * 1024)
return $"{(int)(size / 1024)} KB";
else
return $"{(int)(size / (1024 * 1024))} MB";
} }
} }
} }

View File

@ -2,13 +2,13 @@
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
public class EditorDefine public class WindowsDefine
{ {
#if UNITY_2019_4_OR_NEWER #if UNITY_2019_4_OR_NEWER
/// <summary> /// <summary>
/// 停靠窗口类型集合 /// 停靠窗口类型集合
/// </summary> /// </summary>
public static readonly Type[] DockedWindowTypes = public static readonly Type[] DockedWindowTypes =
{ {
typeof(AssetBundleBuilderWindow), typeof(AssetBundleBuilderWindow),
typeof(AssetBundleCollectorWindow), typeof(AssetBundleCollectorWindow),

View File

@ -1,132 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace YooAsset.Editor
{
public class EditorHelper
{
#if UNITY_2019_4_OR_NEWER
private readonly static Dictionary<System.Type, string> _uxmlDic = new Dictionary<System.Type, string>();
/*
static EditorHelper()
{
// 资源包收集
_uxmlDic.Add(typeof(AssetBundleCollectorWindow), "355c4ac5cdebddc4c8362bed6f17a79e");
// 资源包构建
_uxmlDic.Add(typeof(AssetBundleBuilderWindow), "28ba29adb4949284e8c48893218b0d9a");
// 资源包调试
_uxmlDic.Add(typeof(AssetBundleDebuggerWindow), "790db12999afd334e8fb6ba70ef0a947");
_uxmlDic.Add(typeof(DebuggerAssetListViewer), "31c6096c1cb29b4469096b7b4942a322");
_uxmlDic.Add(typeof(DebuggerBundleListViewer), "932a25ffd05c13c47994d66e9d73bc37");
// 构建报告
_uxmlDic.Add(typeof(AssetBundleReporterWindow), "9052b72c383e95043a0c7e7f369b1ad7");
_uxmlDic.Add(typeof(ReporterSummaryViewer), "f8929271050855e42a1ccc6b14993a04");
_uxmlDic.Add(typeof(ReporterAssetListViewer), "5f81bc15a55ee0a49a266f9d71e2372b");
_uxmlDic.Add(typeof(ReporterBundleListViewer), "56d6dbe0d65ce334a8996beb19612989");
}
/// <summary>
/// 加载窗口的布局文件
/// </summary>
public static UnityEngine.UIElements.VisualTreeAsset LoadWindowUXML<TWindow>() where TWindow : class
{
var windowType = typeof(TWindow);
if (_uxmlDic.TryGetValue(windowType, out string uxmlGUID))
{
string assetPath = AssetDatabase.GUIDToAssetPath(uxmlGUID);
if (string.IsNullOrEmpty(assetPath))
throw new System.Exception($"Invalid YooAsset uxml guid : {uxmlGUID}");
var visualTreeAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.UIElements.VisualTreeAsset>(assetPath);
if (visualTreeAsset == null)
throw new System.Exception($"Failed to load {windowType}.uxml");
return visualTreeAsset;
}
else
{
throw new System.Exception($"Invalid YooAsset window type : {windowType}");
}
}
*/
/// <summary>
/// 加载窗口的布局文件
/// </summary>
public static UnityEngine.UIElements.VisualTreeAsset LoadWindowUXML<TWindow>() where TWindow : class
{
var windowType = typeof(TWindow);
// 缓存里查询并加载
if (_uxmlDic.TryGetValue(windowType, out string uxmlGUID))
{
string assetPath = AssetDatabase.GUIDToAssetPath(uxmlGUID);
if (string.IsNullOrEmpty(assetPath))
{
_uxmlDic.Clear();
throw new System.Exception($"Invalid UXML GUID : {uxmlGUID} ! Please close the window and open it again !");
}
var treeAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.UIElements.VisualTreeAsset>(assetPath);
return treeAsset;
}
// 全局搜索并加载
string[] guids = AssetDatabase.FindAssets(windowType.Name);
if (guids.Length == 0)
throw new System.Exception($"Not found any assets : {windowType.Name}");
foreach (string assetGUID in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
var assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.UIElements.VisualTreeAsset))
{
_uxmlDic.Add(windowType, assetGUID);
var treeAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.UIElements.VisualTreeAsset>(assetPath);
return treeAsset;
}
}
throw new System.Exception($"Not found UXML file : {windowType.Name}");
}
#endif
/// <summary>
/// 加载相关的配置文件
/// </summary>
public static TSetting LoadSettingData<TSetting>() where TSetting : ScriptableObject
{
var settingType = typeof(TSetting);
var guids = AssetDatabase.FindAssets($"t:{settingType.Name}");
if (guids.Length == 0)
{
Debug.LogWarning($"Create new {settingType.Name}.asset");
var setting = ScriptableObject.CreateInstance<TSetting>();
string filePath = $"Assets/{settingType.Name}.asset";
AssetDatabase.CreateAsset(setting, filePath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return setting;
}
else
{
if (guids.Length != 1)
{
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Debug.LogWarning($"Found multiple file : {path}");
}
throw new System.Exception($"Found multiple {settingType.Name} files !");
}
string filePath = AssetDatabase.GUIDToAssetPath(guids[0]);
var setting = AssetDatabase.LoadAssetAtPath<TSetting>(filePath);
return setting;
}
}
}
}

View File

@ -285,6 +285,46 @@ namespace YooAsset.Editor
} }
#endregion #endregion
#region StringUtility
public static string RemoveFirstChar(string str)
{
if (string.IsNullOrEmpty(str))
return str;
return str.Substring(1);
}
public static string RemoveLastChar(string str)
{
if (string.IsNullOrEmpty(str))
return str;
return str.Substring(0, str.Length - 1);
}
public static List<string> StringToStringList(string str, char separator)
{
List<string> result = new List<string>();
if (!String.IsNullOrEmpty(str))
{
string[] splits = str.Split(separator);
foreach (string split in splits)
{
string value = split.Trim(); //移除首尾空格
if (!String.IsNullOrEmpty(value))
{
result.Add(value);
}
}
}
return result;
}
public static T NameToEnum<T>(string name)
{
if (Enum.IsDefined(typeof(T), name) == false)
{
throw new ArgumentException($"Enum {typeof(T)} is not defined name {name}");
}
return (T)Enum.Parse(typeof(T), name);
}
#endregion
#region 文件 #region 文件
/// <summary> /// <summary>
/// 创建文件所在的目录 /// 创建文件所在的目录
@ -553,7 +593,7 @@ namespace YooAsset.Editor
/// <param name="key">关键字</param> /// <param name="key">关键字</param>
/// <param name="includeKey">分割的结果里是否包含关键字</param> /// <param name="includeKey">分割的结果里是否包含关键字</param>
/// <param name="searchBegin">是否使用初始匹配的位置,否则使用末尾匹配的位置</param> /// <param name="searchBegin">是否使用初始匹配的位置,否则使用末尾匹配的位置</param>
private static string Substring(string content, string key, bool includeKey, bool firstMatch = true) public static string Substring(string content, string key, bool includeKey, bool firstMatch = true)
{ {
if (string.IsNullOrEmpty(key)) if (string.IsNullOrEmpty(key))
return content; return content;

View File

@ -0,0 +1,17 @@
#if UNITY_2019_4_OR_NEWER
using System;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
internal class HomePageWindow
{
[MenuItem("YooAsset/Home Page", false, 1)]
public static void OpenWindow()
{
Application.OpenURL("https://www.yooasset.com/");
}
}
}
#endif

View File

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

View File

@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace YooAsset.Editor
{
public class SettingLoader
{
/// <summary>
/// 加载相关的配置文件
/// </summary>
public static TSetting LoadSettingData<TSetting>() where TSetting : ScriptableObject
{
var settingType = typeof(TSetting);
var guids = AssetDatabase.FindAssets($"t:{settingType.Name}");
if (guids.Length == 0)
{
Debug.LogWarning($"Create new {settingType.Name}.asset");
var setting = ScriptableObject.CreateInstance<TSetting>();
string filePath = $"Assets/{settingType.Name}.asset";
AssetDatabase.CreateAsset(setting, filePath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return setting;
}
else
{
if (guids.Length != 1)
{
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Debug.LogWarning($"Found multiple file : {path}");
}
throw new System.Exception($"Found multiple {settingType.Name} files !");
}
string filePath = AssetDatabase.GUIDToAssetPath(guids[0]);
var setting = AssetDatabase.LoadAssetAtPath<TSetting>(filePath);
return setting;
}
}
}
}

View File

@ -12,134 +12,169 @@ namespace YooAsset.Editor
{ {
public static class ShaderVariantCollector public static class ShaderVariantCollector
{ {
private enum ESteps
{
None,
Prepare,
CollectAllMaterial,
CollectVariants,
CollectSleeping,
WaitingDone,
}
private const float WaitMilliseconds = 1000f; private const float WaitMilliseconds = 1000f;
private static string _saveFilePath; private const float SleepMilliseconds = 100f;
private static bool _isStarted = false; private static string _savePath;
private static readonly Stopwatch _elapsedTime = new Stopwatch(); private static string _packageName;
private static int _processMaxNum;
private static Action _completedCallback; private static Action _completedCallback;
private static void EditorUpdate() private static ESteps _steps = ESteps.None;
{ private static Stopwatch _elapsedTime;
// 注意:一定要延迟保存才会起效 private static List<string> _allMaterials;
if (_isStarted && _elapsedTime.ElapsedMilliseconds > WaitMilliseconds) private static List<GameObject> _allSpheres = new List<GameObject>(1000);
{
_isStarted = false;
_elapsedTime.Stop();
EditorApplication.update -= EditorUpdate;
// 保存结果
ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_saveFilePath);
// 创建清单
CreateManifest();
Debug.Log($"搜集SVC完毕");
_completedCallback?.Invoke();
}
}
/// <summary> /// <summary>
/// 开始收集 /// 开始收集
/// </summary> /// </summary>
public static void Run(string saveFilePath, Action completedCallback) public static void Run(string savePath, string packageName, int processMaxNum, Action completedCallback)
{ {
if (_isStarted) if (_steps != ESteps.None)
return; return;
if (Path.HasExtension(saveFilePath) == false) if (Path.HasExtension(savePath) == false)
saveFilePath = $"{saveFilePath}.shadervariants"; savePath = $"{savePath}.shadervariants";
if (Path.GetExtension(saveFilePath) != ".shadervariants") if (Path.GetExtension(savePath) != ".shadervariants")
throw new System.Exception("Shader variant file extension is invalid."); throw new System.Exception("Shader variant file extension is invalid.");
if (string.IsNullOrEmpty(packageName))
throw new System.Exception("Package name is null or empty !");
// 注意先删除再保存否则ShaderVariantCollection内容将无法及时刷新 // 注意先删除再保存否则ShaderVariantCollection内容将无法及时刷新
AssetDatabase.DeleteAsset(ShaderVariantCollectorSettingData.Setting.SavePath); AssetDatabase.DeleteAsset(savePath);
EditorTools.CreateFileDirectory(saveFilePath); EditorTools.CreateFileDirectory(savePath);
_saveFilePath = saveFilePath; _savePath = savePath;
_packageName = packageName;
_processMaxNum = processMaxNum;
_completedCallback = completedCallback; _completedCallback = completedCallback;
// 聚焦到游戏窗口 // 聚焦到游戏窗口
EditorTools.FocusUnityGameWindow(); EditorTools.FocusUnityGameWindow();
// 清空旧数据
ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection();
// 创建临时测试场景 // 创建临时测试场景
CreateTempScene(); CreateTempScene();
// 收集着色器变种 _steps = ESteps.Prepare;
var materials = GetAllMaterials();
CollectVariants(materials);
EditorApplication.update += EditorUpdate; EditorApplication.update += EditorUpdate;
_isStarted = true;
_elapsedTime.Reset();
_elapsedTime.Start();
} }
private static void EditorUpdate()
{
if (_steps == ESteps.None)
return;
if (_steps == ESteps.Prepare)
{
ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection();
_steps = ESteps.CollectAllMaterial;
return; //等待一帧
}
if (_steps == ESteps.CollectAllMaterial)
{
_allMaterials = GetAllMaterials();
_steps = ESteps.CollectVariants;
return; //等待一帧
}
if (_steps == ESteps.CollectVariants)
{
int count = Mathf.Min(_processMaxNum, _allMaterials.Count);
List<string> range = _allMaterials.GetRange(0, count);
_allMaterials.RemoveRange(0, count);
CollectVariants(range);
if (_allMaterials.Count > 0)
{
_elapsedTime = Stopwatch.StartNew();
_steps = ESteps.CollectSleeping;
}
else
{
_elapsedTime = Stopwatch.StartNew();
_steps = ESteps.WaitingDone;
}
}
if (_steps == ESteps.CollectSleeping)
{
if (_elapsedTime.ElapsedMilliseconds > SleepMilliseconds)
{
DestroyAllSpheres();
_elapsedTime.Stop();
_steps = ESteps.CollectVariants;
}
}
if (_steps == ESteps.WaitingDone)
{
// 注意:一定要延迟保存才会起效
if (_elapsedTime.ElapsedMilliseconds > WaitMilliseconds)
{
_elapsedTime.Stop();
_steps = ESteps.None;
// 保存结果并创建清单
ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_savePath);
CreateManifest();
Debug.Log($"搜集SVC完毕");
EditorApplication.update -= EditorUpdate;
_completedCallback?.Invoke();
}
}
}
private static void CreateTempScene() private static void CreateTempScene()
{ {
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
} }
private static List<Material> GetAllMaterials() private static List<string> GetAllMaterials()
{ {
int progressValue = 0; int progressValue = 0;
List<string> allAssets = new List<string>(1000); List<string> allAssets = new List<string>(1000);
// 获取所有打包的资源 // 获取所有打包的资源
List<CollectAssetInfo> allCollectAssetInfos = new List<CollectAssetInfo>(); CollectResult collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(EBuildMode.DryRunBuild, _packageName);
List<CollectResult> collectResults = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild); foreach (var assetInfo in collectResult.CollectAssets)
foreach (var collectResult in collectResults)
{ {
allCollectAssetInfos.AddRange(collectResult.CollectAssets); string[] depends = AssetDatabase.GetDependencies(assetInfo.AssetPath, true);
} foreach (var dependAsset in depends)
List<string> allAssetPath = allCollectAssetInfos.Select(t => t.AssetPath).ToList();
foreach (var assetPath in allAssetPath)
{
string[] depends = AssetDatabase.GetDependencies(assetPath, true);
foreach (var depend in depends)
{ {
if (allAssets.Contains(depend) == false) if (allAssets.Contains(dependAsset) == false)
allAssets.Add(depend); allAssets.Add(dependAsset);
} }
EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, allAssetPath.Count); EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, collectResult.CollectAssets.Count);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
// 搜集所有材质球 // 搜集所有材质球
progressValue = 0; progressValue = 0;
var shaderDic = new Dictionary<Shader, List<Material>>(100); List<string> allMaterial = new List<string>(1000);
foreach (var assetPath in allAssets) foreach (var assetPath in allAssets)
{ {
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Material)) if (assetType == typeof(UnityEngine.Material))
{ {
var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath); allMaterial.Add(assetPath);
var shader = material.shader;
if (shader == null)
continue;
if (shaderDic.ContainsKey(shader) == false)
{
shaderDic.Add(shader, new List<Material>());
}
if (shaderDic[shader].Contains(material) == false)
{
shaderDic[shader].Add(material);
}
} }
EditorTools.DisplayProgressBar("搜集所有材质球", ++progressValue, allAssets.Count); EditorTools.DisplayProgressBar("搜集所有材质球", ++progressValue, allAssets.Count);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
// 返回结果 // 返回结果
var materials = new List<Material>(1000); return allMaterial;
foreach (var valuePair in shaderDic)
{
materials.AddRange(valuePair.Value);
}
return materials;
} }
private static void CollectVariants(List<Material> materials) private static void CollectVariants(List<string> materials)
{ {
Camera camera = Camera.main; Camera camera = Camera.main;
if (camera == null) if (camera == null)
@ -164,7 +199,9 @@ namespace YooAsset.Editor
{ {
var material = materials[i]; var material = materials[i];
var position = new Vector3(x - halfWidth + 1f, y - halfHeight + 1f, 0f); var position = new Vector3(x - halfWidth + 1f, y - halfHeight + 1f, 0f);
CreateSphere(material, position, i); var go = CreateSphere(material, position, i);
if (go != null)
_allSpheres.Add(go);
if (x == xMax) if (x == xMax)
{ {
x = 0; x = 0;
@ -174,27 +211,44 @@ namespace YooAsset.Editor
{ {
x++; x++;
} }
EditorTools.DisplayProgressBar("测试所有材质球", ++progressValue, materials.Count); EditorTools.DisplayProgressBar("照射所有材质球", ++progressValue, materials.Count);
} }
EditorTools.ClearProgressBar(); EditorTools.ClearProgressBar();
} }
private static void CreateSphere(Material material, Vector3 position, int index) private static GameObject CreateSphere(string assetPath, Vector3 position, int index)
{ {
var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
var shader = material.shader;
if (shader == null)
return null;
var go = GameObject.CreatePrimitive(PrimitiveType.Sphere); var go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
go.GetComponent<Renderer>().material = material; go.GetComponent<Renderer>().sharedMaterial = material;
go.transform.position = position; go.transform.position = position;
go.name = $"Sphere_{index}|{material.name}"; go.name = $"Sphere_{index} | {material.name}";
return go;
}
private static void DestroyAllSpheres()
{
foreach(var go in _allSpheres)
{
GameObject.DestroyImmediate(go);
}
_allSpheres.Clear();
// 尝试释放编辑器加载的资源
EditorUtility.UnloadUnusedAssetsImmediate(true);
} }
private static void CreateManifest() private static void CreateManifest()
{ {
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath<ShaderVariantCollection>(_saveFilePath); ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath<ShaderVariantCollection>(_savePath);
if (svc != null) if (svc != null)
{ {
var wrapper = ShaderVariantCollectionManifest.Extract(svc); var wrapper = ShaderVariantCollectionManifest.Extract(svc);
string jsonData = JsonUtility.ToJson(wrapper, true); string jsonData = JsonUtility.ToJson(wrapper, true);
string savePath = _saveFilePath.Replace(".shadervariants", ".json"); string savePath = _savePath.Replace(".shadervariants", ".json");
File.WriteAllText(savePath, jsonData); File.WriteAllText(savePath, jsonData);
} }

View File

@ -2,11 +2,22 @@
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[CreateAssetMenu(fileName = "ShaderVariantCollectorSetting", menuName = "YooAsset/Create ShaderVariant Collector Settings")]
public class ShaderVariantCollectorSetting : ScriptableObject public class ShaderVariantCollectorSetting : ScriptableObject
{ {
/// <summary> /// <summary>
/// 文件存储路径 /// 文件存储路径
/// </summary> /// </summary>
public string SavePath = "Assets/MyShaderVariants.shadervariants"; public string SavePath = "Assets/MyShaderVariants.shadervariants";
/// <summary>
/// 收集的包裹名称
/// </summary>
public string CollectPackage = string.Empty;
/// <summary>
/// 容器值
/// </summary>
public int ProcessCapacity = 1000;
} }
} }

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEditor; using UnityEditor;
@ -20,12 +19,17 @@ namespace YooAsset.Editor
} }
} }
/// <summary>
/// 配置数据是否被修改
/// </summary>
public static bool IsDirty { set; get; } = false;
/// <summary> /// <summary>
/// 加载配置文件 /// 加载配置文件
/// </summary> /// </summary>
private static void LoadSettingData() private static void LoadSettingData()
{ {
_setting = EditorHelper.LoadSettingData<ShaderVariantCollectorSetting>(); _setting = SettingLoader.LoadSettingData<ShaderVariantCollectorSetting>();
} }
/// <summary> /// <summary>
@ -35,6 +39,7 @@ namespace YooAsset.Editor
{ {
if (Setting != null) if (Setting != null)
{ {
IsDirty = false;
EditorUtility.SetDirty(Setting); EditorUtility.SetDirty(Setting);
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
Debug.Log($"{nameof(ShaderVariantCollectorSetting)}.asset is saved!"); Debug.Log($"{nameof(ShaderVariantCollectorSetting)}.asset is saved!");

View File

@ -12,16 +12,21 @@ namespace YooAsset.Editor
public class ShaderVariantCollectorWindow : EditorWindow public class ShaderVariantCollectorWindow : EditorWindow
{ {
[MenuItem("YooAsset/ShaderVariant Collector", false, 201)] [MenuItem("YooAsset/ShaderVariant Collector", false, 201)]
public static void ShowExample() public static void OpenWindow()
{ {
ShaderVariantCollectorWindow window = GetWindow<ShaderVariantCollectorWindow>("着色器变种收集工具", true, EditorDefine.DockedWindowTypes); ShaderVariantCollectorWindow window = GetWindow<ShaderVariantCollectorWindow>("着色器变种收集工具", true, WindowsDefine.DockedWindowTypes);
window.minSize = new Vector2(800, 600); window.minSize = new Vector2(800, 600);
} }
private List<string> _packageNames;
private Button _saveButton;
private Button _collectButton; private Button _collectButton;
private TextField _collectOutputField; private TextField _collectOutputField;
private Label _currentShaderCountField; private Label _currentShaderCountField;
private Label _currentVariantCountField; private Label _currentVariantCountField;
private SliderInt _processCapacitySlider;
private PopupField<string> _packageField;
public void CreateGUI() public void CreateGUI()
{ {
@ -30,36 +35,103 @@ namespace YooAsset.Editor
VisualElement root = this.rootVisualElement; VisualElement root = this.rootVisualElement;
// 加载布局文件 // 加载布局文件
var visualAsset = EditorHelper.LoadWindowUXML<ShaderVariantCollectorWindow>(); var visualAsset = UxmlLoader.LoadWindowUXML<ShaderVariantCollectorWindow>();
if (visualAsset == null) if (visualAsset == null)
return; return;
visualAsset.CloneTree(root); visualAsset.CloneTree(root);
// 配置保存按钮
_saveButton = root.Q<Button>("SaveButton");
_saveButton.clicked += SaveBtn_clicked;
// 包裹名称列表
_packageNames = GetBuildPackageNames();
// 文件输出目录 // 文件输出目录
_collectOutputField = root.Q<TextField>("CollectOutput"); _collectOutputField = root.Q<TextField>("CollectOutput");
_collectOutputField.SetValueWithoutNotify(ShaderVariantCollectorSettingData.Setting.SavePath); _collectOutputField.SetValueWithoutNotify(ShaderVariantCollectorSettingData.Setting.SavePath);
_collectOutputField.RegisterValueChangedCallback(evt => _collectOutputField.RegisterValueChangedCallback(evt =>
{ {
ShaderVariantCollectorSettingData.IsDirty = true;
ShaderVariantCollectorSettingData.Setting.SavePath = _collectOutputField.value; ShaderVariantCollectorSettingData.Setting.SavePath = _collectOutputField.value;
}); });
// 收集的包裹
var packageContainer = root.Q("PackageContainer");
if (_packageNames.Count > 0)
{
int defaultIndex = GetDefaultPackageIndex(ShaderVariantCollectorSettingData.Setting.CollectPackage);
_packageField = new PopupField<string>(_packageNames, defaultIndex);
_packageField.label = "Package";
_packageField.style.width = 350;
_packageField.RegisterValueChangedCallback(evt =>
{
ShaderVariantCollectorSettingData.IsDirty = true;
ShaderVariantCollectorSettingData.Setting.CollectPackage = _packageField.value;
});
packageContainer.Add(_packageField);
}
else
{
_packageField = new PopupField<string>();
_packageField.label = "Package";
_packageField.style.width = 350;
packageContainer.Add(_packageField);
}
// 容器值
_processCapacitySlider = root.Q<SliderInt>("ProcessCapacity");
_processCapacitySlider.SetValueWithoutNotify(ShaderVariantCollectorSettingData.Setting.ProcessCapacity);
#if !UNITY_2020_3_OR_NEWER
_processCapacitySlider.label = $"Capacity ({_processCapacitySlider.value})";
_processCapacitySlider.RegisterValueChangedCallback(evt =>
{
ShaderVariantCollectorSettingData.IsDirty = true;
ShaderVariantCollectorSettingData.Setting.ProcessCapacity = _processCapacitySlider.value;
_processCapacitySlider.label = $"Capacity ({_processCapacitySlider.value})";
});
#else
_processCapacitySlider.RegisterValueChangedCallback(evt =>
{
ShaderVariantCollectorSettingData.IsDirty = true;
ShaderVariantCollectorSettingData.Setting.ProcessCapacity = _processCapacitySlider.value;
});
#endif
_currentShaderCountField = root.Q<Label>("CurrentShaderCount"); _currentShaderCountField = root.Q<Label>("CurrentShaderCount");
_currentVariantCountField = root.Q<Label>("CurrentVariantCount"); _currentVariantCountField = root.Q<Label>("CurrentVariantCount");
// 变种收集按钮 // 变种收集按钮
_collectButton = root.Q<Button>("CollectButton"); _collectButton = root.Q<Button>("CollectButton");
_collectButton.clicked += CollectButton_clicked; _collectButton.clicked += CollectButton_clicked;
//RefreshWindow();
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogError(e.ToString()); Debug.LogError(e.ToString());
} }
} }
public void OnDestroy()
{
if (ShaderVariantCollectorSettingData.IsDirty)
ShaderVariantCollectorSettingData.SaveFile();
}
private void Update() private void Update()
{ {
if (_saveButton != null)
{
if (ShaderVariantCollectorSettingData.IsDirty)
{
if (_saveButton.enabledSelf == false)
_saveButton.SetEnabled(true);
}
else
{
if (_saveButton.enabledSelf)
_saveButton.SetEnabled(false);
}
}
if (_currentShaderCountField != null) if (_currentShaderCountField != null)
{ {
int currentShaderCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount(); int currentShaderCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount();
@ -73,9 +145,40 @@ namespace YooAsset.Editor
} }
} }
private void SaveBtn_clicked()
{
ShaderVariantCollectorSettingData.SaveFile();
}
private void CollectButton_clicked() private void CollectButton_clicked()
{ {
ShaderVariantCollector.Run(ShaderVariantCollectorSettingData.Setting.SavePath, null); string savePath = ShaderVariantCollectorSettingData.Setting.SavePath;
string packageName = ShaderVariantCollectorSettingData.Setting.CollectPackage;
int processCapacity = _processCapacitySlider.value;
ShaderVariantCollector.Run(savePath, packageName, processCapacity, null);
}
// 构建包裹相关
private int GetDefaultPackageIndex(string packageName)
{
for (int index = 0; index < _packageNames.Count; index++)
{
if (_packageNames[index] == packageName)
{
return index;
}
}
ShaderVariantCollectorSettingData.Setting.CollectPackage = _packageNames[0];
return 0;
}
private List<string> GetBuildPackageNames()
{
List<string> result = new List<string>();
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
{
result.Add(package.PackageName);
}
return result;
} }
} }
} }

View File

@ -1,9 +1,13 @@
<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"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;" /> <uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;">
<ui:VisualElement name="BuildContainer"> <ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="background-color: rgb(40, 106, 42);" />
<ui:TextField picking-mode="Ignore" label="文件保存路径" name="CollectOutput" /> </uie:Toolbar>
<ui:Label text="Current Shader Count" display-tooltip-when-elided="true" name="CurrentShaderCount" /> <ui:VisualElement name="CollectContainer">
<ui:Label text="Current Variant Count" display-tooltip-when-elided="true" name="CurrentVariantCount" /> <ui:TextField picking-mode="Ignore" label="文件保存路径" name="CollectOutput" style="height: 22px;" />
<ui:VisualElement name="PackageContainer" style="height: 24px;" />
<ui:Label text="Current Shader Count" display-tooltip-when-elided="true" name="CurrentShaderCount" style="height: 20px; padding-left: 4px;" />
<ui:Label text="Current Variant Count" display-tooltip-when-elided="true" name="CurrentVariantCount" style="height: 20px; padding-left: 4px;" />
<ui:SliderInt picking-mode="Ignore" label="Capacity" value="9999" high-value="1000" name="ProcessCapacity" low-value="10" show-input-field="true" />
<ui:Button text="开始搜集" display-tooltip-when-elided="true" name="CollectButton" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" /> <ui:Button text="开始搜集" display-tooltip-when-elided="true" name="CollectButton" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@ -0,0 +1,39 @@
#if UNITY_2020_3_OR_NEWER
using System;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
/// <summary>
/// 分屏控件
/// </summary>
public class SplitView : TwoPaneSplitView
{
public new class UxmlFactory : UxmlFactory<SplitView, TwoPaneSplitView.UxmlTraits>
{
}
/// <summary>
/// 窗口分屏适配
/// </summary>
public static void Adjuster(VisualElement root)
{
var topGroup = root.Q<VisualElement>("TopGroup");
var bottomGroup = root.Q<VisualElement>("BottomGroup");
topGroup.style.minHeight = 100f;
bottomGroup.style.minHeight = 100f;
root.Remove(topGroup);
root.Remove(bottomGroup);
var spliteView = new SplitView();
spliteView.fixedPaneInitialDimension = 300;
spliteView.orientation = TwoPaneSplitViewOrientation.Vertical;
spliteView.contentContainer.Add(topGroup);
spliteView.contentContainer.Add(bottomGroup);
root.Add(spliteView);
}
}
}
#endif

View File

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

View File

@ -0,0 +1,55 @@
#if UNITY_2019_4_OR_NEWER
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
public class UxmlLoader
{
private readonly static Dictionary<System.Type, string> _uxmlDic = new Dictionary<System.Type, string>();
/// <summary>
/// 加载窗口的布局文件
/// </summary>
public static UnityEngine.UIElements.VisualTreeAsset LoadWindowUXML<TWindow>() where TWindow : class
{
var windowType = typeof(TWindow);
// 缓存里查询并加载
if (_uxmlDic.TryGetValue(windowType, out string uxmlGUID))
{
string assetPath = AssetDatabase.GUIDToAssetPath(uxmlGUID);
if (string.IsNullOrEmpty(assetPath))
{
_uxmlDic.Clear();
throw new System.Exception($"Invalid UXML GUID : {uxmlGUID} ! Please close the window and open it again !");
}
var treeAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.UIElements.VisualTreeAsset>(assetPath);
return treeAsset;
}
// 全局搜索并加载
string[] guids = AssetDatabase.FindAssets(windowType.Name);
if (guids.Length == 0)
throw new System.Exception($"Not found any assets : {windowType.Name}");
foreach (string assetGUID in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
var assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.UIElements.VisualTreeAsset))
{
_uxmlDic.Add(windowType, assetGUID);
var treeAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.UIElements.VisualTreeAsset>(assetPath);
return treeAsset;
}
}
throw new System.Exception($"Not found UXML file : {windowType.Name}");
}
}
}
#endif

View File

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

View File

@ -187,7 +187,7 @@
identification within third-party archives. identification within third-party archives.
Copyright 2018-2021 何冠峰 Copyright 2018-2021 何冠峰
Copyright 2021-2022 TuYoo Games Copyright 2021-2023 TuYoo Games
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

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