unity-2d-pixel-perfect

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

unity-2d-pixel-perfect — two components with the same name, and only one of them is yours

unity-2d-pixel-perfect — 两个同名组件,但只有一个是你需要的

Pixel perfect is not one Unity feature, it is two incompatible implementations of one name. URP ships
UnityEngine.Rendering.Universal.PixelPerfectCamera
, driven by enums. The standalone
com.unity.2d.pixel-perfect
package ships
UnityEngine.U2D.PixelPerfectCamera
, driven by booleans. Adding the wrong one costs you nothing at compile time and everything at runtime, so the pipeline in force decides the component, and you resolve it first.
Pixel perfect 并不是一项 Unity 功能,而是同一名称下两种互不兼容的实现。 URP 自带
UnityEngine.Rendering.Universal.PixelPerfectCamera
,由枚举驱动。独立的
com.unity.2d.pixel-perfect
包自带
UnityEngine.U2D.PixelPerfectCamera
,由布尔值驱动。 添加错误的组件在编译期不会带来任何问题,却会在运行时造成所有问题,因此, 当前生效的管线决定使用哪个组件,而第一步就是解析它。

Start here — symptom → where to look

从这里开始 — 症状 → 查看位置

SymptomGo to
"Which
PixelPerfectCamera
do I add"; the pipeline in force decides which same-named component
§1
The component is on the camera and nothing snaps; it compiles but does nothing after a render-pipeline change§1, §9 — wrong implementation for the pipeline
PixelPerfectCamera
will not resolve in an Editor script
§1 — assembly names
Sprites are soft or washed out at every zoom§2
Sprites sharp at one zoom, soft at another; choosing a reference resolution§3 — non-integer scale factor
Hairline gaps between tilemap tiles§5
Pixels crawl or shimmer while the camera pans§4
gridSnapping
, then §8
The camera jitters and framing pops between shots; Cinemachine and the pixel camera fight over orthographic size§6 — Cinemachine
UI text went soft; the scene did not§7
Post-processing blurs the entire frame§7
A physics-driven sprite stutters while everything else is smooth§8
Black bars, or the scene stretched to a wrong aspect§4
cropFrame
, §3
Compiler errors naming
UnityEngine.Experimental.Rendering.Universal
§9
Property tables, enum values, old-bool mapping
reference/api-and-enums.md
症状查看位置
应该添加哪个
PixelPerfectCamera
;由当前生效的管线决定同名组件
§1
相机上已经挂载了组件,但没有任何吸附效果;能够编译,却在切换渲染管线后不起作用§1、§9 — 管线对应的实现错误
PixelPerfectCamera
在 Editor 脚本中无法解析
§1 — 程序集名称
Sprite 在任何缩放倍率下都显得模糊或发白§2
Sprite 在某个缩放倍率下清晰,在另一个倍率下模糊;需要选择参考分辨率§3 — 非整数缩放系数
Tilemap Tile 之间出现发丝般的缝隙§5
相机平移时像素爬行或闪烁§4
gridSnapping
,然后查看 §8
相机抖动,镜头切换时构图跳变;Cinemachine 与像素相机争夺 orthographic size§6 — Cinemachine
UI 文本变软,但场景没有变软§7
后处理模糊了整个画面§7
由物理系统驱动的 Sprite 卡顿,而其他内容都很流畅§8
出现黑边,或场景被拉伸到错误的宽高比§4
cropFrame
、§3
编译错误提到
UnityEngine.Experimental.Rendering.Universal
§9
属性表、枚举值和旧布尔值映射
reference/api-and-enums.md

1. Resolve the pipeline, then pick the component

1. 先解析管线,再选择组件

Read
GraphicsSettings.currentRenderPipeline
, not
RenderPipelineManager.currentPipeline
.
The second holds the pipeline instance, which does not exist until a frame has rendered, so it reports "built-in" on startup paths and on headless checks. On a project running URP,
RenderPipelineManager.currentPipeline
can be null while
GraphicsSettings.currentRenderPipeline
names the URP asset. Two APIs, opposite answers, same instant.
URPStandalone built-in
Type
UnityEngine.Rendering.Universal.PixelPerfectCamera
UnityEngine.U2D.PixelPerfectCamera
Assembly
Unity.RenderPipelines.Universal.2D.Runtime
Unity.2D.PixelPerfect
(confirm by reflection)
Comes fromURP itself — nothing to install
com.unity.2d.pixel-perfect
API shapeEnums:
gridSnapping
,
cropFrame
Booleans:
pixelSnapping
,
upscaleRT
,
cropFrameX/Y
,
stretchFill
Confirm the standalone assembly name by reflection on a project that has the package —
reference/pipeline-and-migration.md
§2, with why a guessed
Runtime
suffix breaks
Type.GetType
and the lockfile check.
Do not add
com.unity.2d.pixel-perfect
to a URP project.
It installs and compiles without complaint, and leaves the project carrying two different components under one name — remove the package rather than working out which one wins. On a URP project the type you want is already there; a project that arrived with the package already on a camera is §9.
A null default pipeline does not mean built-in. A project can have an empty default with every quality tier overriding it;
currentRenderPipeline
folds the tier in and is the one to trust. The six reads and the grep trap:
reference/pipeline-and-migration.md
§1; the full procedure:
unity-render-urp
→
reference/resolve-active-pipeline.md
.
Code:
resources/PipelineDetection.cs
— pipeline probe, component-type lookup for either pipeline, and the mismatch check §9 uses.
Report, then wait. Fixing import settings reimports textures and rewrites
.meta
files across the art folder; adding or swapping a camera component changes a scene. Survey first, list what you would change with before/after values, and wait for confirmation. Default to the open scene — sweep the whole project only when asked for it.
Reaching a live Editor for any of these reads:
unity-debug
→
reference/editor-control.md
.
请读取
GraphicsSettings.currentRenderPipeline
,而不是
RenderPipelineManager.currentPipeline
。
后者保存的是管线 实例,该实例在渲染一帧之前并不存在,因此 在启动路径和 headless 检查中会报告为“built-in”。在运行 URP 的项目中,
RenderPipelineManager.currentPipeline
可能为 null,而
GraphicsSettings.currentRenderPipeline
则会给出 URP asset 名称。两个 API 在同一时刻会给出相反的答案。
URP独立包(Built-in)
类型
UnityEngine.Rendering.Universal.PixelPerfectCamera
UnityEngine.U2D.PixelPerfectCamera
程序集
Unity.RenderPipelines.Universal.2D.Runtime
Unity.2D.PixelPerfect
(通过反射确认)
来源URP 自身 — 无需安装
com.unity.2d.pixel-perfect
API 形式枚举:
gridSnapping
、
cropFrame
布尔值:
pixelSnapping
、
upscaleRT
、
cropFrameX/Y
、
stretchFill
在已安装该包的项目中,通过反射确认独立包的程序集名称—— 另请参阅
reference/pipeline-and-migration.md
§2,了解猜测
Runtime
后缀为何会导致
Type.GetType
和 lockfile 检查失败。
不要在 URP 项目中添加
com.unity.2d.pixel-perfect
。
它安装和编译时都不会报错, 却会让项目同时携带两个同名但不同的组件——应当移除该包,而不是尝试判断哪个组件会生效。 在 URP 项目中,你需要的类型已经存在;如果项目中的相机原本就挂载了该包中的组件,请参阅 §9。
默认管线为 null 并不意味着使用 Built-in。 项目可能将默认管线设为空, 但每个 quality tier 都覆盖了它;
currentRenderPipeline
会将 tier 的覆盖合并计算, 因此应以此为准。六种读取方式以及 grep 陷阱:参阅
reference/pipeline-and-migration.md
§1; 完整流程:
unity-render-urp
→
reference/resolve-active-pipeline.md
。
代码:
resources/PipelineDetection.cs
— 包含管线探测、 两种管线的组件类型查找,以及 §9 使用的组件不匹配检查。
先报告,再等待。 修改导入设置会重新导入纹理,并重写整个美术目录中的
.meta
文件;添加或替换相机组件会修改场景。请先进行排查,列出准备更改的内容及前后值, 然后等待确认。默认只检查当前打开的场景;仅在用户明确要求时才扫描整个项目。
如需在实时 Editor 中执行其中任何读取操作:
unity-debug
→
reference/editor-control.md
。

2. The four import settings that decide sharpness

2. 决定清晰度的四项导入设置

Bilinear filtering is the import default and the most common cause of soft pixel art. Set
filterMode = Point
, mipmaps off,
Uncompressed
, one
spritePixelsPerUnit
project-wide; AA 0 in the active quality level, MSAA 1 on the URP asset, and
allowHDR
/
allowMSAA
/
allowDynamicResolution
off on the camera. A centre pivot on an odd-sized sprite lands on half a pixel ("only this one sprite is blurry"). Editor grid snapping:
1 / assetsPPU
. The table, the why and the snapping steps:
reference/sharpness.md
§2. Code:
resources/SpriteImportFix.cs
. Frames shipped upscaled by F (
frames.json
pixel.block_px
) import at F × the art-pixel PPU;
assetsPPU
is their PPU ÷ F (
codex-visual
→
reference/pixel-grid.md
).
双线性过滤是默认导入设置,也是像素艺术发软最常见的原因。将
filterMode = Point
、关闭 mipmaps、使用
Uncompressed
,并为整个项目统一设置一个
spritePixelsPerUnit
;在当前生效的 quality level 中将 AA 设为 0,在 URP asset 中将 MSAA 设为 1,并关闭相机上的
allowHDR
/
allowMSAA
/
allowDynamicResolution
。 奇数尺寸 Sprite 使用中心 pivot 时会落在半个像素上(“只有这一个 Sprite 模糊”)。 Editor 网格吸附:
1 / assetsPPU
。相关表格、原理和吸附步骤:
reference/sharpness.md
§2。代码:
resources/SpriteImportFix.cs
。 以 F 倍尺寸发布的帧(
frames.json
中的
pixel.block_px
)应按 F × 美术像素 PPU 导入;
assetsPPU
为其 PPU ÷ F(
codex-visual
→
reference/pixel-grid.md
)。

3. Reference resolution, chosen once

3. 只选择一次的参考分辨率

Pick it before art production: 320×180 fits 1080p, 1440p and 2160p at whole numbers (6×, 8×, 12×), which is why it is the safe default; a fractional factor ribs the art, and a screen with no integer fit gets
cropFrame = Windowbox
, not a stretch.
Camera.orthographicSize = (refResolutionY / 2f) / assetsPPU
(320×180 at PPU 16 → 5.625), separate from the component's own read-only value. The table:
reference/sharpness.md
§3.
在制作美术资源前选定参考分辨率:320×180 可分别以整数倍适配 1080p、1440p 和 2160p (6×、8×、12×),因此是安全的默认值;非整数缩放系数会让画面出现波纹, 而无法与整数倍率匹配的屏幕应使用
cropFrame = Windowbox
,而不是拉伸。
Camera.orthographicSize = (refResolutionY / 2f) / assetsPPU
(320×180、PPU 16 → 5.625),该值与组件自身的只读值相互独立。 相关表格:
reference/sharpness.md
§3。

4.
gridSnapping
and
cropFrame

4.
gridSnapping
与
cropFrame

GridSnapping
is
None
,
PixelSnapping
,
UpscaleRenderTexture
;
CropFrame
is
None
,
Pillarbox
,
Letterbox
,
Windowbox
,
StretchFill
;
PixelPerfectFilterMode
is
RetroAA
,
Point
— all enumerated from the assembly.
PixelSnapping
+
Windowbox
is the default worth reaching for: it snaps sprite renderers at render time, leaves transforms at float precision, and stays compatible with post-processing and with UI.
UpscaleRenderTexture
renders the frame at reference resolution and scales the whole buffer up — the authentic look, and the source of both problems in §7.
PixelPerfectFilterMode
has no public property on the URP component.
Only the serialized private
m_FilterMode
, so the Inspector can set it and script cannot — author it in a prefab or scene. It is documented to apply only under
cropFrame = StretchFill
, and it is unrelated to per-texture
filterMode
(§2).
Property tables for both components, the old-bool mapping, recommended combinations and the
pixelSnapSpacing
formula:
reference/api-and-enums.md
.
GridSnapping
包含
None
、
PixelSnapping
、
UpscaleRenderTexture
;
CropFrame
包含
None
、
Pillarbox
、
Letterbox
、
Windowbox
、
StretchFill
;
PixelPerfectFilterMode
包含
RetroAA
、
Point
— 以上均可从程序集的枚举中取得。 推荐采用的默认组合是
PixelSnapping
+
Windowbox
:它在渲染时吸附 Sprite Renderer, 让 Transform 保持浮点精度,并兼容后处理和 UI。
UpscaleRenderTexture
会以参考分辨率渲染画面,再放大整个缓冲区——这能呈现原汁原味的像素观感, 同时也是 §7 中两种问题的根源。
URP 组件上的
PixelPerfectFilterMode
没有公开属性。
它只有序列化私有字段
m_FilterMode
,因此 Inspector 可以设置,而脚本不能设置——请在 prefab 或 scene 中预先配置。 文档说明它仅在
cropFrame = StretchFill
下生效,并且与单张纹理的
filterMode
(§2)无关。
两个组件的属性表、旧布尔值映射、推荐组合和
pixelSnapSpacing
公式:
reference/api-and-enums.md
。

5. Tilemap seams — work the ladder in order

5. Tilemap 接缝 — 按顺序逐级排查

Hairline gaps have six ordinary causes and one that appears only in motion; work them top to bottom, never a negative cell gap or PPU 31.99: atlas Tight Packing off and Padding ≥ 4 → mipmaps off on tileset and atlas → AA and MSAA off →
Uncompressed
→ even pixel dimensions →
assetsPPU
equal to the tile's width → gaps only while the camera moves:
gridSnapping = PixelSnapping
. The ladder with each failure:
reference/sharpness.md
§5. Rows 1 and 2 are
unity-sprite-atlas
; authoring the tilemap is
unity-tilemap
.
发丝般的缝隙有六个常见原因,以及一个仅在运动时出现的原因;请从上到下逐项排查, 绝不要使用负的 cell gap 或 31.99 的 PPU:关闭 atlas 的 Tight Packing 并将 Padding 设为 ≥ 4 → 关闭 tileset 和 atlas 的 mipmaps → 关闭 AA 和 MSAA → 使用
Uncompressed
→ 使用偶数像素尺寸 → 使
assetsPPU
等于 Tile 的宽度 → 仅在相机移动时出现缝隙:
gridSnapping = PixelSnapping
。包含每种失败情况的排查阶梯:
reference/sharpness.md
§5。第 1、2 行对应
unity-sprite-atlas
; Tilemap 制作属于
unity-tilemap
。

6. Cinemachine writes orthographic size too

6. Cinemachine 也会写入 orthographic size

The pixel camera owns orthographic size, and Cinemachine writes it every frame too: jitter, plus framing that pops between shots. Put the
CinemachinePixelPerfect
extension
on every camera rig, through its Add Extension dropdown. Follow, dead zones, confiners, blends and the component names for each Cinemachine major:
unity-camera
→
reference/pixel-perfect-follow.md
.
像素相机负责管理 orthographic size,而 Cinemachine 也会每帧写入该值,造成抖动, 并在镜头切换时引发构图跳变。请通过 Add Extension 下拉菜单,为每个相机 rig 添加
CinemachinePixelPerfect
extension
。关于 Follow、dead zone、confiner、blend, 以及各个主要版本 Cinemachine 的组件名称:
unity-camera
→
reference/pixel-perfect-follow.md
。

7.
UpscaleRenderTexture
versus UI text and post-processing

7.
UpscaleRenderTexture
与 UI 文本及后处理

One cause, two symptoms: the scene is rendered small and then scaled up, and anything that runs after that scale-up — or gets caught inside it — is working at the wrong resolution. Post-processing then filters an enlarged image: leave
gridSnapping = PixelSnapping
, or inject a 2D renderer feature after post-processing, since a plain
ScriptableRendererFeature
on a URP 2D renderer is ignored without an error. UI text on a Screen Space – Camera canvas softens with the scene: set the canvas to Screen Space – Overlay, the route that holds. The ranked alternatives and where canvas and font work goes:
reference/motion-and-upscale.md
§2. Confirm either fix in a windowed run with the canvas and a volume in the scene — a headless check shows neither symptom.
一个原因会产生两种症状:场景先以较小尺寸渲染再放大,而任何在放大之后运行的内容, 或被包含在放大过程中的内容,都会使用错误的分辨率工作。 后处理随后会过滤放大后的图像:请保持
gridSnapping = PixelSnapping
, 或者在后处理之后注入 2D renderer feature,因为普通的
ScriptableRendererFeature
添加到 URP 2D renderer 上时会被静默忽略,不会报错。 使用 Screen Space – Camera Canvas 的 UI 文本也会随场景一起变软: 请将 Canvas 设置为 Screen Space – Overlay,这是能够保持清晰的方案。 按优先级排列的备选方案,以及 Canvas 和字体相关工作的归属:
reference/motion-and-upscale.md
§2。请在窗口模式下运行场景,并同时放入 Canvas 和 Volume, 以确认任一修复是否生效;headless 检查无法显示这两种症状。

8. Micro-stutter is physics, not rendering

8. 微小卡顿来自物理系统,而不是渲染

A sprite driven by
Rigidbody2D
stutters while everything else is smooth: physics advances on a fixed timestep and rendering does not, and snapping makes the sub-pixel error visible. The fix is
Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate
on every physics-driven sprite; a matched fixed timestep and camera follow in
LateUpdate
tighten it —
reference/motion-and-upscale.md
§3. Confirm it in play mode with a moving rigidbody. The movement code itself is
unity-2d-controller
.
由
Rigidbody2D
驱动的 Sprite 会卡顿,而其他内容都很流畅:物理系统按固定时间步推进, 渲染却不是如此,而吸附会放大并显现亚像素误差。修复方式是在每个由物理驱动的 Sprite 上设置
Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate
; 匹配的 fixed timestep 设置以及在
LateUpdate
中执行相机跟随,可进一步收紧抖动 —
reference/motion-and-upscale.md
§3。请在 play mode 下使用移动中的 rigidbody 进行确认。 移动代码本身属于
unity-2d-controller
。

9. Migration

9. 迁移

Wrong component for the pipeline — URP in force,
UnityEngine.U2D.PixelPerfectCamera
on the camera: remove the package and the component, add the URP one, re-enter the settings (booleans do not migrate into enums).
PipelineDetection.HasWrongComponent
finds it. Deprecated booleans on the right component still compile, as a warning, not an error — so bool-style code compiling proves nothing about which component you are on. Read the type, not the property names.
Old URP namespace (
UnityEngine.Experimental.Rendering.Universal
), no 2D renderer under URP, and HDRP, which has no Pixel Perfect Camera at all: steps for all five cases, and the bool → enum mapping, via
reference/pipeline-and-migration.md
§3.
管线对应错误 — 当前生效的是 URP,但相机上使用了
UnityEngine.U2D.PixelPerfectCamera
:移除该包和组件,添加 URP 版本,并重新填写设置 (布尔值不会自动迁移到枚举)。
PipelineDetection.HasWrongComponent
可检测此问题。 正确组件上的已弃用布尔值仍可编译,但只会产生警告,而不是错误—— 因此,bool 风格代码能够编译并不能证明当前使用的是哪个组件。请读取类型,而不是属性名称。
旧 URP namespace(
UnityEngine.Experimental.Rendering.Universal
)、 URP 下没有 2D renderer,以及完全没有 Pixel Perfect Camera 的 HDRP: 这五种情况各自的处理步骤,以及 bool → enum 映射,参阅
reference/pipeline-and-migration.md
§3。

Scope — what this skill does NOT do

范围 — 此 skill 不负责的内容

Slicing sheets, pivots, rects, 9-slice borders and outlines are
unity-2d-sprites
— this skill only says which pivot values keep a sprite on the grid. Atlas packing, padding, packer mode and atlas memory are
unity-sprite-atlas
, which rows 1 and 2 of §5 hand off to. Tilemaps, palettes and rule tiles are
unity-tilemap
; §5 ends at "the seam is not the tilemap's fault". Parallax and sorting are
unity-2d-rendering
.
Resolving the active render pipeline, URP asset and renderer configuration, Volumes and Render Graph passes are
unity-render-urp
— §1 reads the pipeline, it does not set it. The canvas itself — render mode, scaler, layout — is
unity-ui-ugui
, and font assets and CJK glyph coverage are
unity-game-ui
; §7 only says which canvas mode escapes the upscale. Before/after screenshots and connecting to a live Editor at all are
unity-debug
.
Art direction is out of scope in both directions: this skill will not tell you a resolution is too low for your art, and it does not apply to high-resolution or hand-painted 2D, where point filtering and snapping make smooth art look wrong.
Sprite sheet 切片、pivot、rect、9-slice 边框和 outline 属于
unity-2d-sprites
— 此 skill 只说明哪些 pivot 值能让 Sprite 保持在网格上。 Atlas 打包、Padding、packer mode 和 atlas 内存属于
unity-sprite-atlas
, §5 的第 1、2 行会将其转交出去。Tilemap、调色板和规则 Tile 属于
unity-tilemap
; §5 的范围止于“接缝并非 Tilemap 本身的问题”。视差和排序属于
unity-2d-rendering
。
解析当前生效的渲染管线、URP asset 和 renderer 配置、Volume 以及 Render Graph pass, 属于
unity-render-urp
— §1 只读取管线,不负责设置它。 Canvas 本身 — render mode、scaler、layout — 属于
unity-ui-ugui
; font asset 和 CJK 字形覆盖属于
unity-game-ui
;§7 只说明哪种 Canvas 模式能够避开放大问题。 前后对比截图以及任何连接到实时 Editor 的操作都属于
unity-debug
。
美术方向不在此 skill 的范围内:它不会判断某个分辨率是否低于美术资源所需的分辨率, 也不适用于高分辨率或手绘 2D 内容,因为 Point 过滤和吸附会让平滑画面看起来不正确。

Reference

参考资料

  • reference/api-and-enums.md
    — both components member by member, enums with old-bool equivalents, combinations,
    pixelSnapSpacing
    .
  • reference/sharpness.md
    — the import settings table, reference resolutions, the tilemap seam ladder.
  • reference/pipeline-and-migration.md
    — pipeline reads, assembly names, migration steps.
  • reference/motion-and-upscale.md
    — the Cinemachine rule, the upscale's side effects, physics stutter.
  • Code:
    PipelineDetection.cs
    (resolve the pipeline, pick the type, detect a mismatch),
    CameraSetupURP.cs
    (enum-style),
    CameraSetupBuiltIn.cs
    (bool-style, standalone package),
    SpriteImportFix.cs
    (the four import settings from §2).
  • reference/api-and-enums.md
    — 逐成员介绍两个组件、 枚举及其旧布尔值对应项、推荐组合和
    pixelSnapSpacing
    。
  • reference/sharpness.md
    — 导入设置表、参考 分辨率和 Tilemap 接缝排查阶梯。
  • reference/pipeline-and-migration.md
    — 管线读取方式、 程序集名称和迁移步骤。
  • reference/motion-and-upscale.md
    — Cinemachine 规则、 放大操作的副作用和物理卡顿。
  • 代码:
    PipelineDetection.cs
    (解析管线、选择 类型并检测不匹配)、
    CameraSetupURP.cs
    (枚举风格)、
    CameraSetupBuiltIn.cs
    (布尔值风格、独立包)、
    SpriteImportFix.cs
    (§2 中的四项导入设置)。