关于 2d-pixel-perfect
用于诊断和修复 Unity 像素级 2D 渲染的技能。它区分 URP 与 Built-in 的不同实现,并提供对应的设置、故障排查和迁移检查。
主要功能
- 01设置前检测 URP 或 Built-in
- 02配置匹配的 Pixel Perfect Camera
- 03诊断精灵导入与相机设置
- 04排查瓦片地图缝隙和图像模糊
- 05检查兼容性与迁移问题
适用场景
- 01修复像素艺术精灵模糊
- 02设置 Unity 像素级渲染相机
- 03排查瓦片地图中的缝隙
- 04检查项目是否使用错误的相机组件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ unity-technologies/ skills --skill 2d-pixel-perfect安装后在 Claude Code 中输入/2d-pixel-perfect确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-reference.mdcamera-setup-builtin.cscamera-setup-urp.cspipeline-detection.cssprite-settings.cs详细介绍
在 Unity 项目中设置、诊断并修复像素级精准的 2D 渲染。
⚠ 两套完全独立的实现
Unity 中的像素级精准渲染并非一个系统,而是两套彼此不兼容的实现,分别对应一种渲染管线。编写或诊断任何代码之前,务必先检测渲染管线。
| URP | Built-in | |
|---|---|---|
| 组件 | UnityEngine.Rendering.Universal.PixelPerfectCamera | UnityEngine.U2D.PixelPerfectCamera |
| 软件包 | 内置于 URP,无需额外安装 | com.unity.2d.pixel-perfect v6.0.0+ |
| API 风格 | 枚举(gridSnapping、cropFrame) | 布尔值(pixelSnapping、upscaleRT、cropFrameX/Y) |
不要在 URP 项目中安装 com.unity.2d.pixel-perfect。
→ 务必先调用 DetectPipeline()(references/pipeline-detection.cs),再根据检测结果分支设置、诊断和修复。
不应使用此技能的情况
- HD 2D 或高分辨率 2D 游戏——像素吸附和点过滤会让平滑的美术效果显得不自然
- 仅包含 UI 的场景——改用 Canvas Scaler
- HDRP 项目——不支持 Pixel Perfect Camera
重要提醒
⚠ 先检测渲染管线——URP 和 Built-in 使用不同的 Pixel Perfect Camera 组件,二者不可互换。
⚠ Filter Mode = Point 是首要修复方法——双线性过滤是 Unity 的默认设置,几乎总是导致精灵模糊的原因。
⚠ 必须禁用抗锯齿——在 Quality Settings 和摄像机上都要禁用。抗锯齿会主动模糊像素边缘。
核心原则
1. 渲染管线检测与摄像机组件选择
请参阅本文件顶部的两种方案对比表。关于程序集名称的说明:独立的 Built-in 软件包会安装到 Runtime/ 文件夹,但 asmdef 的 "name" 字段为 Unity.2D.PixelPerfect——没有 Runtime 后缀。HDRP 不受支持——请参阅“常见问题”下的 HDRP 替代方案部分。
→ 代码:references/pipeline-detection.cs——DetectPipeline()、GetPixelPerfectCameraType() 和迁移不匹配检查。
2. 先诊断
始终先诊断,再进行更改。报告检查结果,然后只修复存在问题的部分。
3. 在正确的范围内操作
默认仅针对场景范围。只有用户明确要求时,才扫描整个项目。
诊断清单
精灵导入设置:
- 所有目标范围内的精灵均设置 Filter Mode =
Point (no filter) - 禁用 Mip Maps
- Compression =
None/ Uncompressed - 场景中所有精灵的 PPU 保持一致
- 精灵轴心设为 Custom / Pixels 模式——奇数尺寸精灵(例如 15×15)的中心轴心会落在 7.5 px 处,导致 0.5 px 错位
→ 代码:references/sprite-settings.cs——GetImporter() 和 FixSpriteImportSettings()。
编辑器吸附设置:
- 所有轴上的 Grid Size =
1 / assetsPPU(例如 PPU 为 16 → 0.0625,PPU 为 100 → 0.01) - 在 Grid and Snap 覆盖层中启用 Grid Snapping
- 吸附现有 GameObject:选中它们 → Align Selected → All Axes
摄像机设置:
- 摄像机投影模式 = Orthographic
- 存在 Pixel Perfect Camera 组件,且类型与渲染管线匹配
-
allowHDR、allowMSAA、allowDynamicResolution均为false - Scene 视图中的摄像机辅助图标显示两个绿色边界框——实线框 = 可见区域,虚线框 = 参考分辨率
→ 代码:references/camera-setup-urp.cs——URP 摄像机和 PP Camera 的完整配置。
→ 代码:references/camera-setup-builtin.cs——Built-in 独立配置。
项目质量设置:
- Quality Settings 中的 Anti-Aliasing = 0
- Anisotropic Filtering = Disabled
API 参考
完整的属性/方法表、GridSnapping 和 CropFrame 枚举值,以及推荐配置:
→ references/api-reference.md — 编写或审查相机设置代码时,请阅读此文档。
枚举快速摘要:
GridSnapping:None · PixelSnapping(标准)· UpscaleRenderTexture(真实低分辨率;与后处理和 UI 文本不兼容)
CropFrame:None · Pillarbox · Letterbox · Windowbox(最安全的默认选项)· StretchFill
参考分辨率
在构建任何资源前选择。资源制作开始后切勿更改。
| 参考分辨率 | 1080p | 1440p | 4K |
|---|---|---|---|
| 320 × 180 | 6× | 8× | 12× |
| 480 × 270 | 4× | ~5.3× | 8× |
| 640 × 360 | 3× | 4× | 6× |
320×180 是最稳妥的通用选择。对于无法整数倍适配的屏幕(例如 1366×768),请使用 cropFrame = Windowbox 添加黑边,而不要拉伸到非整数倍比例。
迁移与兼容性
使用 Built-in 独立组件的 URP 项目
症状:DetectPipeline() 返回 URP,但相机具有 UnityEngine.U2D.PixelPerfectCamera。由于独立组件包含 ENABLE_URP 条件代码,因此症状并不明显。
修复:
- 从 Package Manager 移除
com.unity.2d.pixel-perfect - 从每个相机中移除
UnityEngine.U2D.PixelPerfectCamera - 添加
UnityEngine.Rendering.Universal.PixelPerfectCamera - 重新配置 — 布尔值(
pixelSnapping、upscaleRT、cropFrameX/Y)将变为枚举(gridSnapping、cropFrame)
→ 检测代码:references/pipeline-detection.cs(文件底部)。
旧版 URP 命名空间(Unity 2022 之前/URP 13.x 之前)
症状:编译器报错,提示引用了 UnityEngine.Experimental.Rendering.Universal。
修复:将 using UnityEngine.Experimental.Rendering.Universal; 替换为 using UnityEngine.Rendering.Universal;。更新所有程序集限定类型字符串。[MovedFrom] 属性会自动处理序列化 — GameObject 上的组件在升级后仍会保留。
常见问题与解决方案
精灵模糊
修复:将所有相关精灵的 Filter Mode 设为 Point,禁用 Mip Maps,并在 Quality Settings 中禁用 AA。
→ 代码:references/sprite-settings.cs
Tilemap 瓦片之间有缝隙
按顺序逐项排查 — 诸如负 cell gap 或 PPU = 31.99 的变通方法会在相机移动时失效。
| # | 检查项 | 修复 |
|---|---|---|
| 1 | Sprite Atlas 是否关闭了 Tight Packing、将 Padding 设为 ≥ 4,并启用了 Sprite Packer Mode? | 在 Editor 设置中启用 Sprite Packer Mode;在图集中将 Padding 设为 ≥ 4 并关闭 Tight Packing |
| 2 | Tileset 纹理和图集是否禁用了 Mipmaps? | 禁用 Generate Mip Maps |
| 3 | AA = 0,且相机已关闭 MSAA? | 全局禁用 AA |
| 4 | Compression = None? | 使用 RGBA 32 位无压缩 |
| 5 | 所有瓦片精灵的像素尺寸是否为偶数? | 奇数尺寸会导致 0.5px 网格偏移 |
| 6 | PPU = 瓦片像素宽度?(16×16 → PPU 16) | PPU 不匹配会留下物理间隙 |
| 7 | 以上各项均通过后,仅在相机移动时出现缝隙? | 使用 PP Camera 像素对齐;不要使用 cellGap = -0.01f |
Cinemachine 冲突
原因:Cinemachine 和 Pixel Perfect Camera 每帧都会写入正交尺寸。
修复:通过每个 Virtual Camera 上的 Add Extension 下拉菜单添加 CinemachinePixelPerfect 扩展。不要在代码中通过 AddComponent 添加。
已知限制:
- 虚拟相机之间的混合在过渡期间无法做到像素完美
UpscaleRenderTexture会减少有效的像素完美正交尺寸,可能导致取景偏移- Target Group + Framing Transposer 会造成明显卡顿(暂无解决方法)
使用 upscaleRT 后的后处理模糊
原因:后处理在 PP Camera 放大渲染纹理后运行。
简单修复:禁用 upscaleRT。这样后处理便会以屏幕原生分辨率运行。
进阶修复(Unity 6 URP):在 RenderPassEvent2D.AfterRenderingPostProcessing 注入一个 ScriptableRendererFeature2D。使用专为 2D 设计的基类——ScriptableRendererFeature(3D 基类)在 URP 2D 渲染器中会被静默忽略。
使用 upscaleRT 后的 UI 文本模糊
状态:已知 Unity Bug,官方拒绝修复(Unity 6 中仍存在,2025 年)。
根本原因:(A) Canvas 渲染到低分辨率缓冲区后,随场景一起放大。(B) TMP 的 SDF 渐变阈值在低参考分辨率下校准不准确。
按可靠性排序的修复方法:
- 在 Canvas 上设置
Screen Space - Overlay——绕过摄像机,以原生分辨率渲染 - 使用不带 PP Camera 组件的专用 UI 摄像机,并设置为
Screen Space - Camera模式 - 仅限 Unity 6:
Font Material → Debug Settings → Sharpness = 1(可缓解 B,不能缓解 A)
物理与渲染不同步(微卡顿)
原因:物理以固定时间步长运行;插值后的位置会产生小数值,导致物体每帧跳到不同的像素位置。
修复方法:
- 为受物理驱动的精灵启用
Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate - 设置
Time.fixedDeltaTime = 1f / 60f,使其与目标帧率一致 - 将摄像机跟踪逻辑放在
LateUpdate中,而不是FixedUpdate
非整数缩放/像素抽取
原因:屏幕分辨率不是参考分辨率的整数倍。
修复方法:从上表中选择参考分辨率。如果无法实现整数倍适配,则使用 cropFrame = Windowbox。
缺少 URP 2D Renderer
修复方法:
Assets > Create > Rendering > URP 2D Renderer Data- 在 URP Asset 的 Renderer List 中指定该项
- 需要
com.unity.render-pipelines.universal12.0+
HDRP 回退方案
HDRP 不支持 Pixel Perfect Camera。
Built-in / Unity 5.x:使用 RenderTexture + Graphics.Blit,并设置 FilterMode.Point。
Unity 6 URP:使用 ScriptableRendererFeature2D + ScriptableRenderPass2D,通过 AddRasterRenderPass 在 RenderPassEvent2D.AfterRendering 注入。注意:OnRenderImage 和 Graphics.Blit 与 Unity 6 的渲染图不兼容。