拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Unity Artifacts 文件夹清理指南:从构建缓存原理到安全瘦身实践

1. 从“磁盘爆红”说起Artifacts文件夹到底装了什么Unity 项目的 Library 文件夹大是出了名的但最近很多朋友开始被另一个东西困扰——Artifacts 文件夹。我接手的一个老项目C 盘空间从 60G 可用一路跌到 8G排查一圈罪魁祸首不是 Library而是项目根目录下一个叫 Artifacts 的文件夹占了将近 35G。当时第一反应是哪个实习生把测试资源丢进去了打开一看全是Asset Bundle 的中间产物、增量构建缓存、Shader 变体烘焙数据还有一个后缀特别眼熟的路径_artifacts\winui_packages\sdk\build\native\microsoft.windowsappsdk.props。这里先解释清楚Unity 的 Artifacts 文件夹是2019.3 版本之后引入的 Scriptable Build PipelineSBP的默认输出目录。它的职责是存放构建过程中产生的临时数据、可寻址资产Addressables的构建缓存、Asset Bundle 的中间文件以及部分平台比如 Windows 的 WinUI 包的原生 SDK 解析文件。它不是多余的垃圾而是构建系统的“半成品仓库”。但问题恰恰出在“半成品”三个字上。很多团队把它当临时目录用删了怕下次构建变慢不删又看着它一天天膨胀。更糟的是有些同学把这文件夹直接提交到了 Git 仓库里导致克隆项目时体积爆炸甚至因为文件锁冲突导致构建失败。2. 先搞清楚“谁”在变大Artifacts 内部结构拆解在动手清理之前必须先知道东西是怎么长胖的。我拉了一台测试机把 Artifacts 目录完整导出来做了个占比分析结论很典型。2.1 按目录层级拆分常见的“重量级选手”Artifacts/ ├── AssetBundleBuildCache/ # 增量构建缓存最大的坑 │ ├── shader/ # Shader 变体集合与烘焙结果 │ ├── serialized/ # 序列化之后的资源中间文件 │ └── globalmanifests/ # 全局依赖清单 ├── BuildData/ # SBP 构建流程的状态存档 ├── Logs/ # 构建日志与崩溃转储 ├── PackageCache/ # 包管理器缓存的临时副本 ├── StreamingAssets/ # 构建时生成的流式资源 └── winui_packages/ # 目标平台为 Windows 时的 WinUI 依赖 └── sdk/build/native/ └── microsoft.windowsappsdk.props实测下来AssetBundleBuildCache占整个 Artifacts 体积的70% 以上。Shader 变体缓存又是其中最容易失控的。如果你项目里用了 URP 或 HDRP加上开了一些第三方后处理插件变体数量轻松突破几万每一个变体都会在构建时序列化出一份完整的数据这个量级是 GB 级别的。2.2 为什么 Library 和 Artifacts 会“双胖”有经验的朋友会问Library 里不是也有 AssetBundle 相关的缓存吗是的但两者的分工不同。Library 缓存的是导入阶段的结果比如纹理压缩后的贴图、模型导入后的 Mesh而Artifacts 缓存的是构建阶段的产物AssetBundle 打包、依赖关系图、Shader 烘焙。你每次修改 C# 脚本或者调整了构建管线配置并不会触发 Library 全面重建但会走一遍 SBP导致 Artifacts 里的增量缓存不断叠加旧版本文件。这里有个反常识的地方Incremental Build 并不是“每次只写新增文件”而是“把旧文件保留一段时间以防回滚”。Unity 的构建系统为了防止你回退代码后需要全量重编会保留上一次构建留下的 tons of 中间产物。这就是为什么你改了一行 UI 代码Artifacts 却涨了 2G 的原因。3. 实战清理从“手动删除”到“安全瘦身”的完整过程接下来是重头戏。先说结论在没有做好构建缓存失效机制前直接右键删除 Artifacts 是可行的但次日构建会慢 20% 到 50%而且某些 Addressables 组会因为找不到缓存而触发全量重建。所以我不推荐无脑删下面的方案按“日常清理 → 定期解决 → 最后手段”三个层级来。3.1 安全删除哪些子目录可以直接清哪些要留子目录能否直接删删除后影响建议AssetBundleBuildCache/可删下次 AssetBundle 构建会全量重来日常清理首选Logs/可删无实质影响放心删PackageCache/可删包管理器会重新解析依赖首次进入会卡一下偶尔清理BuildData/可删增量构建的断点续传失效构建失败排查时别删平时可清StreamingAssets/看情况如果里面是你的正式资源删错会导致打包缺文件非构建期可清winui_packages/可删下次 Windows 平台构建会自动还原只在构建失败排查时保留注意如果你团队里有人用 Unity 版本低于 2020.3Artifacts 内还有ScriptableBuildPipeline.Targets这类文件删除时建议连Library/BuildPipeline一起清否则会出现“残留的构建目标引用”报错。实际操作时我建议直接写一个清理脚本不要手点。以下是我在 Windows 和 macOS 上跑过的 PowerShell / Bash 版本。# Windows PowerShell 清理脚本保存为 Clean-Artifacts.ps1 $projectRoot D:\UnityProject $paths ( $projectRoot\Artifacts\AssetBundleBuildCache, $projectRoot\Artifacts\Logs, $projectRoot\Artifacts\BuildData\obj, $projectRoot\Artifacts\PackageCache ) foreach ($p in $paths) { if (Test-Path $p) { Remove-Item -Path $p -Recurse -Force Write-Host [清理完毕] $p } } Write-Host 当前 Artifacts 剩余体积: $size (Get-ChildItem $projectRoot\Artifacts -Recurse | Measure-Object Length -Sum).Sum Write-Host ({0:N2} MB -f ($size / 1MB))# macOS / Linux Bash 版本 #!/bin/bash PROJECT_ROOT/Users/me/UnityProject rm -rf $PROJECT_ROOT/Artifacts/AssetBundleBuildCache rm -rf $PROJECT_ROOT/Artifacts/Logs rm -rf $PROJECT_ROOT/Artifacts/BuildData du -sh $PROJECT_ROOT/Artifacts这套脚本执行完一般能把 Artifacts 从 30G 压到 3G 左右。因为AssetBundleBuildCache是“用空间换时间”的产物删除后表面体积大减但构建时会在半个小时内把缓存重新生成。3.2 清理之后一定要做的验证很多人删完就完事了结果第二天构建报错Failed to load script build pipeline或者Cannot find artifact: xxx就开始骂 Unity。其实原因是删了BuildData后工程里的 BuildProfile 配置还在引用旧的构建 GUID。清理后测试构建时注意两个点打开Window Asset Management Addressables Settings确认 Profiles 里的BuildTarget路径没有指向已删除的目录。手动触发一次Build Clean Build不是“Build”是“Clean Build”让 SBP 重置所有状态标志再走一次增量构建。实测这样能避免 90% 的“假报错”。如果你用的是命令行构建比如 CI 上跑Unity -batchmode -executeMethod BuildScript.PerformBuild记得在构建参数里加一行-batchmode -quit -projectPath $PROJECT_ROOT -executeMethod BuildScript.CleanArtifacts我习惯在 CI 管道里先调一个清理 Artifacts 的方法再执行正式构建。别担心这样每次都全量构建实际上 SBP 有文件 hash 校验只要源码和资源没变清理缓存后的构建时间和原来几乎一样。花的时间主要是重新生成缓存目录结构实际资源处理不会重做。4. 源头治理为项目建立 Artifacts 体积基线如果你只有一个项目删删旧缓存确实能救急。但做 Unity 外包或长期维护项目的人都知道每个交付版本都要留档Artifacts 随着版本迭代只增不减是常态。这时候光靠删没意义得从构建配置层面控制它。4.1 把 Artifacts 移出项目根目录Unity 的 Artifacts 默认路径是ProjectRoot/Artifacts但它是可以改的。在ProjectSettings/EditorBuildSettings.asset里搜useBuildCache或者直接在构建脚本里重定向// 放在 BuildScript.cs 里构建前调用 [MenuItem(Tools/SetArtifactsPath)] public static void SetArtifactsPath() { // 重定向到项目外的全局缓存目录 var externalPath Path.Combine(D:\\BuildCache, PlayerSettings.productName); Directory.CreateDirectory(externalPath); ScriptableBuildPipeline.artifactsOutputPath externalPath; }这个做法的核心逻辑是把 Artifacts 从“项目文件”变为“本机缓存”它就不需要进版本控制也不占 C 盘项目空间。多人协作时每个人的本机缓存彼此独立互不干扰也不会出现 A 同学生成的缓存被 B 同学拉到本地导致 File In Use 的报错。改动之后原先项目里的 Artifacts 文件夹可以直接删掉一了百了。唯一需要注意的坑是Unity 2021.2 以下版本不支持直接改 SBP 输出路径需要升级包或在构建参数里传-buildCachePath。4.2 版本控制.gitignore 的完整配置如果你的团队还在用 Git 管项目这件事情优先级很高。好多项目把 Artifacts 传到仓库后出现各种诡异问题别人拉代码后构建报错、构建产物被提交导致仓库体积暴涨、texture 文件冲突…… 但问题根源不是 Git 本身而是忽略规则没写全。这是我目前用的.gitignore相关段落覆盖了 Artifacts 和周边目录# Unity 生成目录 /[Ll]ibrary/ /[Tt]emp/ /[Oo]bj/ /[Bb]uild/ /[Bb]uilds/ /[Ll]ogs/ /[Uu]ser[Ss]ettings/ /[Mm]emoryCaptures/ # SBP 与 Artifacts重点 /[Aa]rtifacts/ /[Bb]uildCache/ /[Pp]ackage[Cc]ache/ # 构建日志 *.log *.trc注意最后一行*.log如果 CI 系统把构建日志输出到项目根目录这些日志文件很容易被顺手提交一次构建几百 MB 的 log仓库也会被拖垮。4.3 控制 Shader 变体从根源减少缓存上面说过 Shader 变体缓存是 Artifacts 体积的“头号元凶”但很多同学不知道它有办法从源头控制。Unity 的 ShaderVariantCollection 是可以手动管理的但更实用的做法是用IPreprocessShaders接口构建一个变体过滤器在构建阶段直接丢弃不需要的变体。using UnityEditor; using UnityEditor.Build; using UnityEditor.Rendering; using UnityEngine; using UnityEngine.Rendering; public class ShaderVariantStripper : IPreprocessShaders { private const string KEYWORD_TO_REMOVE DIRECTIONAL_SHADOWS; public int callbackOrder 0; public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IListShaderCompilerData data) { for (int i data.Count - 1; i 0; i--) { // 剔除不在全局启用的关键词组合 if (data[i].shaderKeywordSet.ShouldStrip(KEYWORD_TO_REMOVE)) { data.RemoveAt(i); } } } }当然具体要去掉哪些关键词得看你的渲染管线和业务需求。我团队用 URP 时一般会默认剔除DIRECTIONAL_SHADOWS、POINT_SHADOWS等不使用的阴影关键词以及各类 Debug 显示关键词。做了变体剔除之后Artifacts 里 shader 相关缓存体积能下降 60% 以上而且包体大小也会跟着缩水——一箭双雕。5. 当 Artifacts 与 Addressables 耦合时的排查与迁移这里单独写一节是因为 Artifacts 在 Addressables 项目里的表现和普通构建完全不一样而且报错方式很迷惑。5.1 症状Artifacts 被删后Addressables 组状态异常删掉 Artifacts 后打开 Addressables Groups 窗口很多组会显示为“Cannot build”或“Not All Asset Bundles Present”。如果你不知道这是缓存缺失引起的很容易去检查 BuildScript 代码浪费一两个小时。原因是 Addressables 的 build 脚本AddressableAssetsBuildScript.cs会把上一次构建的 manifest 存在 Artifacts 里加载这些组的 Bundle 列表时如果找不到对应文件就会判定为“资源缺失”。解决办法是在删缓存之后对 Addressables 做一次Clean Addressables Build菜单栏Window Asset Management Addressables Clean Build All它会重置所有状态再执行Build New Build即可恢复。5.2 迁移 Artifacts 到 SSD 分区做大型项目时有同学问我Artifacts 能放到机械硬盘上吗—— 能但你会明显感到增量构建速度下降Shader 烘焙阶段 CPU 等待 IO 的时间暴增构建时间至少翻倍。因为 SBP 的增量构建机制是靠检查文件时间戳和 hash 来判断是否需要重新处理的大量小文件的随机读写就是它的性能瓶颈。所以我个人的方案是把 Artifacts 重定向到SSD 上独立的一个目录比如D:\BuildCache\ProjectNameD 盘是 NVMe。同时确保这个目录所在分区至少有 40G 空闲空间。做项目交付时把 Artifacts 整个归档压缩放到 NAS 或对象存储上——这比每次重新构建要快得多也能保留增量构建的状态。这里再补充一个迁移时容易踩的坑如果你重定向了 Artifacts 路径但 CI 机上还挂着旧项目的绝对路径比如E:\Jenkins\workspace\Project\Artifacts构建时偶尔会报类似Invalid artifact target: ...的错误。这时候别去翻构建日志的堆栈直接检查 CI 的环境变量或者 BuildScript 里的absolutePath赋值是不是写死了旧路径。6. 用数据说话清理前后的对比与性能影响最后放一组实测数据。测试环境是配置项数值Unity 版本2022.3.8f1渲染管线URP目标平台Android Windows项目资源量256 个目录包约 40,000 个资源初始 Artifacts 体积31.4 GB清理方案只删AssetBundleBuildCacheLogs保留BuildData和PackageCache。指标清理前清理后变化Artifacts 体积31.4 GB2.1 GB减少 93%全量构建耗时Android47 分 32 秒49 分 05 秒增加约 2 分钟增量构建耗时改一行 UI3 分 10 秒3 分 44 秒增加约 34 秒首次打开 Editor 时间1 分 45 秒1 分 20 秒提升约 20%注意看“首次打开 Editor 时间”反而下降了——因为 Artifacts 里堆积的旧缓存会让 Editor 启动时做一次依赖校验文件越多校验越慢。删掉以后这层校验逻辑变得清爽启动反而更快了。这个测试结果说明一个道理Artifacts 的缓存红利主要体现在“大版本频繁切换分支”的工作流里对于日常小改动它对增量构建的加速效果并没有想象中那么显著。如果你团队不是每天反复切换 build 分支定期清一次缓存没有任何心理负担。7. 再分享两个实际运维中总结的小习惯写到最后聊点不放进正文但在项目里很有用的操作习惯。第一个是每次发版前给 Artifacts 打一个归档快照。我习惯发版后跑一次tar -czf Artifacts_20250115.tar.gz Artifacts存到团队的共享盘里。如果线上出了问题需要快速热修可以直接把这包缓存解压回去节省一次全量构建的时间。这个习惯在带机型的 XR 项目或大型单机项目上特别有用。第二个是给团队内写一份《Artifacts 清理 SOP》。因为大多数非专业的 Unity 同学策划、TA并不知道 SBP 缓存机制他们看到磁盘红了第一反应是删 Library后果往往是第二天全部资源重新导入坐等半小时。而这份 SOP 里就三行字运行Clean-Artifacts.ps1路径比如Tools/CleanArtifacts。如果构建报错先执行一次编译CtrlF7。如果还报错执行 Unity 菜单栏Assets Reimport All再构建。以上都不行再来找我不要自己删 Library。几个月运行下来这类磁盘问题的人工介入次数少了大半。你要是在团队里遇到类似困扰可以直接抄这个思路——问题的关键从来不是“怎么删一下”而是“怎么让所有人删得对、删得安全、删完不慌”。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门