itsakeyfut/uasset-lens

GitHub: itsakeyfut/uasset-lens

一款无需 Unreal Editor 即可在 CI 环境中直接解析 .uasset 二进制文件的静态分析 CLI 工具,用于依赖分析、无用资产检测和资产质量管控。

Stars: 0 | Forks: 0

# uasset-lens **在 CI 中强制执行资产质量关卡——无需打开 Unreal Editor。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/f1d91b3a2d100936.svg)](https://github.com/itsakeyfut/uasset-lens/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) uasset-lens 是一款专为 Unreal Engine 5 `.uasset` / `.umap` 文件打造的快速、CLI 优先的静态分析工具。它直接读取二进制格式,因此可以在任何 CI 服务器上几秒钟内运行完毕,无需 editor 进程、无需编译项目,也不需要 GPU。 ## 为什么选择 uasset-lens? Unreal Engine 的内置工具(Reference Viewer、Size Map、Data Validation)功能强大,但它们都有一个根本的限制:**它们需要 editor 处于运行状态**。这使得它们不适用于 CI pipeline、PR 自动化以及长期趋势跟踪。uasset-lens 填补了 UE 留下的三个空白: ### 1. 随时间推移的质量跟踪 UE 只能向你展示当前的状态。它无法告诉你今天提交的 PR 中 Blueprint 的复杂度是否增加了,或者上个月的总纹理大小是否增长了 20%。uasset-lens 为资产提供了与 linter 为代码提供的相同类型的静态分析反馈循环。 ### 2. 无需 editor,CI 原生执行 一个大型 UE 项目在 editor 中打开需要 2-5 分钟。而 uasset-lens 通过直接解析 `.uasset` 二进制文件,能在 5 秒内扫描 1,000 个资产。它可以在任何机器上运行,无需 GPU、无需编译项目,也无需 editor 许可证——包括 GitHub Actions 的 runner。 ### 3. 软引用的可见性 UE 的 Reference Viewer 只会跟踪硬引用。通过 `DataTable` 行、`AnimMontage` 插槽或 `TSoftObjectPtr` 字段加载的资产会显示为未引用状态,这会导致在检测无用资产时出现误报,并使得依赖图不完整。uasset-lens 能够明确跟踪这些软引用。 ## 系统要求 | 要求 | 详情 | |---|---| | Unreal Engine | **5.1 或更高版本**(不支持 UE4) | | 操作系统 | Windows、macOS、Linux (x86_64) | | 资产格式 | `.uasset` 和 `.umap` 文件 | | **不支持** | IoStore 容器(`.pak`、`.utoc`、`.ucas`) | ## 安装说明 ### 预编译二进制文件(推荐) 从 [GitHub Releases](https://github.com/itsakeyfut/uasset-lens/releases/latest) 下载最新的二进制文件: | 平台 | 文件 | |---|---| | Linux x86_64 | `uasset-lens-linux-x86_64.tar.gz` | | macOS x86_64 | `uasset-lens-macos-x86_64.tar.gz` | | Windows x86_64 | `uasset-lens-windows-x86_64.zip` | 解压压缩包,并将 `uasset-lens`(或 `uasset-lens.exe`)放置在你的 `PATH` 路径中。 ### 从源码编译 需要 Rust 1.96+: ``` git clone https://github.com/itsakeyfut/uasset-lens cd uasset-lens cargo install --path apps/uasset-lens-cli ``` ## 快速开始 ``` # 1. 将所有 asset 索引到本地数据库(1000 个 asset 约需 5 秒) uasset-lens scan ./MyProject # 2. 查找没有被任何内容引用的 asset —— 删除候选 uasset-lens dead-assets ./MyProject # 3. 查看重命名或删除一个 asset 会破坏哪些内容 uasset-lens impact ./MyProject/Content/Characters/BP_Player.uasset # 4. 一次性运行所有健康检查(如果有任何问题将退出并返回状态码 1) uasset-lens check ./MyProject # 5. 输出 JSON 以供脚本使用 uasset-lens dead-assets ./MyProject --format json | jq '.[] | .path' ``` 数据库会自动写入到 `/.uasset-lens/uasset-lens.db`。请将此路径添加到 `.gitignore` 中。 ## 命令参考 所有命令共享三个全局 flag: | Flag | 描述 | |---|---| | `--format ` | 输出格式(默认:`text`) | | `--db ` | 覆盖数据库文件的存储位置 | | `-y` / `--yes` | 跳过确认提示(用于 CI) | ### `scan` 将项目目录中的所有 `.uasset` / `.umap` 文件索引到本地数据库中。 ``` uasset-lens scan [options] ``` | 选项 | 描述 | |---|---| | `--full-scan` | 无论修改时间如何,重新扫描所有文件 | | `--diff` | 显示与上次扫描相比的差异 | | `--save-baseline ` | 将扫描结果保存为指定的 baseline | | `--diff-from ` | 与指定的 baseline 进行差异对比(隐含 `--diff`) | **输出:** ``` Scanning ./MyProject/Content... (1000 files) + 3 new assets indexed ~ 5 assets updated (mtime changed) ? 2 assets removed from disk The following DB records have no corresponding file on disk: /Game/Old/BP_Deprecated.uasset /Game/Temp/M_Test.uasset Remove these records from DB? [y/N]: y ✓ 998 assets total, 2 records cleaned, 2 skipped (parse error) Skipped: WARN Content/Broken/BP_X.uasset: invalid magic number WARN Content/Old/M_Y.uasset: unsupported version ``` ### `graph` 显示依赖关系图摘要并检测循环依赖。 ``` uasset-lens graph [options] ``` | 选项 | 描述 | |---|---| | `--cycles-only` | 仅显示循环依赖(如果发现任何循环依赖,则以退出码 1 退出) | **输出:** ``` Dependency Graph Summary Total assets : 998 Total edges : 4,231 Circular deps : 2 cycles detected Cycles: [1] BP_Player → BP_Enemy → BP_GameMode → BP_Player [2] M_Rock → MF_Shared → M_Rock ``` ### `dead-assets` 列出未被任何其他资产引用的资产。 ``` uasset-lens dead-assets [options] ``` | 选项 | 描述 | |---|---| | `--type ` | 按资产类型过滤(例如 `Texture2D`、`Blueprint`) | | `--sort-by-size` | 按文件大小对结果进行排序,最大的排在最前 | | `--min-size ` | 排除小于此大小的资产 | | `--exclude ` | 排除包含此子字符串的路径(可多次使用) | | `--group ` | 按资产类型或顶级目录聚合结果 | **输出:** ``` /Game/Unused/T_OldTexture (Texture2D, 2.1 MB) /Game/Characters/SK_OldEnemy (SkeletalMesh, 8.4 MB) Dead Assets (47 found) ``` 当发现无用资产时退出码为 `1`,未发现时为 `0`。 ### `deps` 显示某个资产的前向依赖树——即它依赖的所有内容。 ``` uasset-lens deps [options] ``` | 选项 | 描述 | |---|---| | `--depth ` | 最大递归深度(默认:无限制) | | `--size-only` | 仅打印摘要行,不打印完整的依赖树 | **输出:** ``` /Game/Characters/BP_Player /Game/Characters/SK_Player (SkeletalMesh, 12.3 MB) /Game/Materials/M_Player (Material, 1.2 MB) /Game/Textures/T_Player_D (Texture2D, 4.0 MB) /Game/Textures/T_Player_N (Texture2D, 2.0 MB) 4 dependencies, 19.5 MB total ``` ### `impact` 显示如果目标资产被删除或重命名,哪些资产将会受损。 ``` uasset-lens impact [options] ``` | 选项 | 描述 | |---|---| | `--tree` | 显示完整的传播树,而不是扁平列表 | **输出:** ``` Impact Analysis: /Game/Characters/BP_Player Direct referencing (3): /Game/Levels/L_Main.umap /Game/UI/WBP_HUD.uasset /Game/GameModes/BP_GameMode.uasset Transitive referencing (12): /Game/Levels/L_Tutorial.umap ... (9 more) Total impact: 12 assets ``` 当影响集不为空时退出码为 `1`,如果没有资产引用该目标则退出码为 `0`。 ### `redirectors` 列出项目中所有的 `ObjectRedirector` 资产。这些资产是在 editor 中移动或重命名资产时遗留下来的;积累它们会使 package 变得臃肿并增加 cook 时间。 ``` uasset-lens redirectors ``` **输出:** ``` ObjectRedirectors (5 found) =========================== /Game/Characters/OldName /Game/Meshes/SM_OldRock /Game/Materials/M_Deprecated /Game/UI/WBP_OldWidget /Game/Blueprints/BP_OldEnemy Note: redirect target resolution is available in Phase 4 analysis. ``` 当发现 redirector 时退出码为 `1`,未发现时为 `0`。 ### `find` 按类型、大小或路径模式搜索和过滤资产。 ``` uasset-lens find [options] ``` | 选项 | 描述 | |---|---| | `--type ` | 按资产类型过滤(例如 `Texture2D`、`Blueprint`) | | `--larger-than ` | 最小文件大小 | | `--smaller-than ` | 最大文件大小 | | `--unreferenced` | 仅显示未被任何内容引用的资产 | | `--path ` | 按 glob 路径模式过滤(例如 `"**/Characters/**"`) | | `--sort-by-size` | 按文件大小对结果进行排序,最大的排在最前 | | `--refs ` | 仅显示引用此游戏路径的资产 | | `--deps ` | 仅显示此游戏路径直接依赖的资产 | **示例:** ``` uasset-lens find ./Project --type Texture2D --larger-than 4194304 uasset-lens find ./Project --unreferenced --type StaticMesh uasset-lens find ./Project --path "**/Characters/**" ``` **输出:** ``` /Game/Textures/T_Rock_D (Texture2D, 4.0 MB) /Game/Textures/T_Rock_N (Texture2D, 2.0 MB) 2 assets found ``` ### `blueprint` 按节点数和其他指标显示 Blueprint 资产的复杂度排名。 ``` uasset-lens blueprint ``` **输出:** ``` Blueprint Complexity Report =========================== Rank Asset Nodes Ticks Casts Depth 1 /Game/Player/BP_PlayerController 842 31 5 7 2 /Game/AI/BP_EnemyAI 631 18 3 5 3 /Game/UI/WBP_MainMenu 412 7 1 2 3 Blueprint asset(s) ranked ``` ### `stats` 显示项目的大小和组成概览。 ``` uasset-lens stats [options] ``` | 选项 | 描述 | |---|---| | `--top ` | 要显示的文件夹和最大资产的数量(默认:5 个文件夹,10 个资产) | **输出:** ``` Project Stats: ./MyProject Total assets : 998 Total size : 1.2 GB Asset types : 12 Top folders by size: /Game/Characters 342 MB (28%) /Game/Environments 289 MB (24%) Largest assets: /Game/Environments/SM_LargeRock (StaticMesh, 52.4 MB) ``` ### `budget` 报告超出 `.uasset-lens.toml` 中定义的各类型大小预算的资产。 ``` uasset-lens budget ``` **输出:** ``` Budget Report OVER /Game/Textures/T_Landscape_D Texture2D 12.4 MB (limit 10.0 MB, +24%) OVER /Game/Meshes/SM_Building StaticMesh 67.1 MB (limit 50.0 MB, +34%) 2 assets over budget ``` 当有任何资产超出其预算时退出码为 `1`,当所有资产都在限制范围内时退出码为 `0`。 ### `duplicates` 查找可能存在冗余的同名或同大小纹理资产组。 ``` uasset-lens duplicates ``` **输出:** ``` Duplicate Groups (3 found) [same-name] T_Rock_D /Game/Environments/T_Rock_D (Texture2D, 4.0 MB) /Game/Characters/T_Rock_D (Texture2D, 4.0 MB) ``` ### `lint` 运行所有 lint 规则并报告违规情况。如果发现任何违规,退出码为 `1`。 规则包括:命名前缀规范、Blueprint 节点数限制、纹理预算阈值等。请在 `.uasset-lens.toml` 中配置规则。 ``` uasset-lens lint ``` **输出:** ``` Lint Results ERROR /Game/Blueprints/gamemode Blueprint name should start with 'BP_' WARN /Game/Textures/Rock_Diffuse Texture name should start with 'T_' WARN /Game/Blueprints/BP_Player Node count 312 exceeds limit 150 3 violations (1 error, 2 warnings) ``` ### `check` 一次性运行所有(或选定的)健康检查。如果任何检查发现问题,退出码为 `1`。 ``` uasset-lens check [options] ``` | 选项 | 描述 | |---|---| | `--only ` | 仅运行这些检查(以逗号分隔) | | `--skip ` | 跳过这些检查(以逗号分隔) | 可用的检查项:`dead-assets`、`cycles`、`redirectors`、`lint`、`budget`、`duplicates` **示例:** ``` uasset-lens check ./Project # run all checks uasset-lens check ./Project --only cycles,lint # only cycles and lint uasset-lens check ./Project --skip dead-assets # skip dead-asset detection ``` ### `clean` 从磁盘删除已确认的无用资产。除非传递了 `-y`,否则会提示确认。 ``` uasset-lens clean [options] ``` | 选项 | 描述 | |---|---| | `--dry-run` | 列出要删除的目标但不实际删除;退出码为 0 | | `--min-size ` | 排除小于此大小的资产 | | `--exclude ` | 排除包含此子字符串的路径(可多次使用) | | `--path ` | 按 glob 路径模式过滤 | ### `watch` 监控项目目录的文件更改,并在资产被修改时输出新问题。按 Ctrl+C 停止。 ``` uasset-lens watch ``` ### `path` 在文件系统路径和 UE 游戏路径(`/Game/...`)之间进行转换。 ``` uasset-lens path [options] ``` | 选项 | 描述 | |---|---| | `--to-file` | 将游戏路径转换为文件系统路径 | | `--content-root ` | Content 根目录(如省略则自动检测) | **示例:** ``` uasset-lens path ./MyProject/Content/Characters/BP_Player.uasset # → /Game/Characters/BP_Player uasset-lens path /Game/Characters/BP_Player --to-file # → ./MyProject/Content/Characters/BP_Player.uasset ``` ### `completions` 生成 shell 自动补全脚本。 ``` uasset-lens completions ``` 支持的 shell:`bash`、`zsh`、`fish`、`powershell`、`elvish` **设置:** ``` # bash uasset-lens completions bash >> ~/.bash_completion # zsh uasset-lens completions zsh > ~/.zfunc/_uasset-lens # fish uasset-lens completions fish > ~/.config/fish/completions/uasset-lens.fish ``` ## 配置 在项目根目录下创建 `.uasset-lens.toml` 并将其提交到版本控制中,以便整个团队共享相同的配置。 ``` # .uasset-lens.toml [scan] # 扫描期间要排除的路径(相对于项目根目录,前缀匹配) exclude_paths = [ "Content/Dev/", "Content/Test/", "Content/Developers/", ] # 被视为外部的 Game 路径前缀(永远不会被标记为 dead) external_roots = ["/Engine/", "/Script/"] [lint] blueprint_max_nodes = 150 blueprint_max_event_tick = 3 blueprint_max_cast_count = 20 # Asset 命名前缀规则:type → 必需的前缀 [lint.naming_prefix] Blueprint = "BP_" Texture2D = "T_" StaticMesh = "SM_" Material = "M_" [budget] # 按 type 划分的最大文件大小(以字节为单位) Texture2D.max_size = 10485760 # 10 MB StaticMesh.max_size = 52428800 # 50 MB SoundWave.max_size = 5242880 # 5 MB [diff] # 当 asset 在两次扫描之间增长超过此百分比时发出警告 size_increase_threshold_pct = 10 ``` 所有部分都是可选的——缺失的部分将使用内置默认值。 ## CI 集成 将 `uasset-lens` 集成到你的 CI pipeline 中,以阻止引入循环依赖或 lint 违规的 PR。 **快速开始** —— 将 [`docs/ci/github-actions.yml`](docs/ci/github-actions.yml) 复制到 `.github/workflows/` 目录下,并将 `./YourProject` 替换为你的项目目录名称。 **Git 中的资产存储** —— 请参阅 [`docs/ci/git-lfs-guide.md`](docs/ci/git-lfs-guide.md) 获取关于在直接提交和 Git LFS 之间进行选择的指南。 ### 退出码 | 退出码 | 含义 | |-----------|---------| | `0` | 成功 —— 未发现问题 | | `1` | 检测到问题(违规、循环依赖、无用资产等) | | `2` | 工具错误(IO 故障、未找到数据库、解析错误) | `lint`、`graph --cycles-only`、`budget` 和 `check` 在发现问题时会以退出码 `1` 退出,这将自动导致 GitHub Actions 步骤失败并阻止 PR 被合并。 ### GitHub Actions 标注 传递 `--format github-actions` 以针对 lint 和预算违规输出内联的 PR 标注: ``` - name: Lint assets run: uasset-lens lint ./MyProject --format github-actions ``` ## 贡献 欢迎提交 Bug 报告、功能请求和提问 —— 请[创建一个 issue](https://github.com/itsakeyfut/uasset-lens/issues)。 在提交 Bug 时,请附上 `uasset-lens --version` 的输出以及失败的相关命令。 ## 许可证 MIT —— 详情请参阅 [LICENSE](LICENSE)。
标签:WebSocket, 云安全监控, 依赖分析, 可视化界面, 开源框架, 持续集成, 文档结构分析, 虚幻引擎, 通知系统, 静态分析