unity-2d-rendering — draw order is four keys in a fixed priority, and z is the last of them
Moving a sprite in z is almost never the fix. Two overlapping renderers are compared on
sorting layer, then Order in Layer, then render queue, then distance along the sort axis. The
first key that differs decides and the rest are never read. World z is only what "distance"
happens to mean under the default sort mode — and under a custom axis it means nothing.
The first you add turns everything it does not light black. With no light in
the scene, lit sprites draw at full colour; with one, every pixel outside its shape and every
sorting layer it does not target receives darkness. Both halves of this skill are the same question: which asset is the renderer
actually reading?
Start here — symptom → where to look
First match wins. Stop at the first cause the audit or the frame confirms.
| Symptom | Go to |
|---|
| A sprite draws behind one it should be in front of | §1 |
| Changing z or Order in Layer makes no difference | §1 — an earlier key already decided |
| Two sprites flicker or swap as the camera moves | §1 — a tie on all four keys |
| A character's hat, weapon or carried item sorts apart from its body | §2 |
| Something appears between the parts of a character | §2 |
| Seen from above, the runner walks behind a shelf or wall it stands in front of | §3 |
| Isometric or hex pieces draw inside out against the board | §3 |
| The sort axis is set under Project Settings and nothing changed | §0, then §3 |
| The runner cannot walk behind a tall tile, or is always behind the whole Tilemap | §4 |
| Particles or a world canvas draw under the sprites | §4 |
| The Light 2D does nothing | §5 |
| Everything went black after adding one light | §5 — no Global light |
| One sorting layer stays dark, or stays bright, under a light | §5 — target sorting layers |
| No shadow, or a wall that shades itself black | §6 |
| The normal map does nothing | §6 |
| A sprite mask hides nothing, or hides sprites it should leave alone | §7 |
| Tinting or flashing one sprite multiplied the draw calls | §7 |
| A parallax background: layers shudder, slide after a respawn, or run out in a long level | §8 |
| A generated scene to scroll endlessly, or props repeating beside their own mirror image | §8 — reference/parallax-layers.md
|
0. Before diagnosing
Work on a live Editor (
→
reference/editor-control.md
) and run two reports first:
— the pipeline in force, its renderers, and the sort mode and axis
actually read (built-in: the camera and Project Settings; URP without a 2D Renderer: the camera's
axis and no lights; URP with one: only the renderer asset's) — and
—
every renderer's four keys, group, sort point, lit material and the pairs that tie. Answer from
the Frame Debugger where it disagrees with the audit; change only the key that decided, and
restore anything changed while probing. In full:
reference/before-diagnosing.md
.
1. The four keys
| # | Key | Set on | Decides |
|---|
| 1 | Sorting layer | Renderer; order from the list in Tags and Layers | Higher in the list draws first |
| 2 | Order in Layer | Renderer, −32768 to 32767 | Higher draws later, on top |
| 3 | Render queue | Material | Higher draws later. Both default sprite shaders are 3000 |
| 4 | Distance along the sort axis | The renderer's sort point and the sort mode | Further draws first |
- Compare in order. Find the two renderers in the audit and read , ,
, . The first difference is the whole explanation.
- A tie on all four has no defined order and can swap from frame to frame. The audit's
array lists every overlapping pair. Fix a tie with a key, never with a hope that
hierarchy order holds.
- is not an order. Compare
SortingLayer.GetLayerValueFromID(id)
. A
misspelt lands on Default without an error.
- z is key 4 only, and only under , or . Under
with z is ignored completely.
- Key 3 behaves differently outside the 2D Renderer. The 2D Renderer sorts every queue in
one back-to-front list per batch of layers. The Built-in pipeline and URP's Universal
Renderer draw opaque-queue materials in an earlier pass with depth writing: an opaque
there ignores keys 1 and 2 against sprites and hides them by z.
Each key in full, the three places a sort axis can live, and the fix per deciding key:
.
2. SortingGroup — a character is one thing
A
on a root makes everything below it sort as one unit against the outside,
using the group's own layer and order and the root's position. Inside, the children order
themselves with their own keys.
- A multi-sprite or skeletal character gets one group on its root. Parts are ordered inside
with Order in Layer: body 0, satchel 1, cap 2.
- Nothing outside can be drawn between two members. To put a pickup between body and cap, make
it a child inside the group.
- A child's Order in Layer cannot lift it over an outside object; raise the group's.
- on a nested group takes it out of its parent.
What a group costs and what it isolates:
.
3. Sorting from above
Depth in a top-down, isometric or hex view is key 4 with a custom axis. Four settings, and it
fails if any one is missing:
- Sort mode , axis — on the asset §0 named.
- Pivot at the feet on every sprite that takes part — for setting pivots.
SpriteRenderer.spriteSortPoint = SpriteSortPoint.Pivot
. The default is , which
swaps a tall shelf and the runner half a shelf late.
- One sorting layer and one Order in Layer for everything that Y-sorts. Keys 1 and 2 beat
the axis.
Isometric Z as Y starts from
. A board with rows is often better served by an
Order in Layer per row than by the axis. Layer table, split tall objects, the isometric and hex
cases, and the row formula:
.
4. Tilemaps, particles and UI
- . sorts the map as chunks: the runner is in front of all
of it or behind all of it. sorts each tile at its own position against other
renderers on the same layer and order — required for tall tiles the runner walks behind,
and it gives up chunk batching. Keep floors on , put tall tiles on a second Tilemap.
TilemapRenderer.sortOrder
is the corner the renderer starts from among its own tiles.
- A particle system is one unit with its own Sorting Layer and Order in Layer.
- A Screen Space – Overlay canvas draws after the scene and takes no part. Camera and World
Space canvases sort with sprites by and .
5. The light does nothing
Three conditions, all required. First failure wins.
- The 2D Renderer is in force — in the §0 report.
- The sprite's material is lit — in the audit. and the
Built-in never react.
- The light targets the sprite's sorting layer. A light targets the layers that existed
when it was created; a layer added later is missing from lights in prefabs and unopened
scenes.
And the inversion:
no at all means full colour; one means everything it
does not reach is black. Make the first light in a scene a Global light on every layer.
Light types and defaults, blend styles, the cost per light, and why lights that skip a layer
in the middle of the stack multiply the light textures:
.
6. Shadows and normal maps
Each needs a setting on the light and a piece on the sprite.
- Shadow: the light has shadows enabled and is not Global; the object has a
; both target the layer the shadow falls on. leaves the caster
itself lit; darkens it. A Tilemap casts through its composite collider.
- Normal map: the sprite carries a secondary texture named —
→
reference/data-provider.md
— and the light's Normal Maps quality is or
. The default is , and the property is read-only from script.
- Mask map: on the sprite plus a blend style that reads a mask channel.
reference/shadows-and-normals.md
.
7. Masks, materials and batches
- A reaches only renderers whose is not — the default is
. Narrow it with a custom range in sorting-layer and order units, or by placing it
inside a .
- Tint with : it is vertex colour and keeps the batch. A
or takes the renderer out of it.
- Two sprites batch only when consecutive in sorted order with the same material and texture.
Y-sorted scenes interleave textures constantly; one atlas for the Y-sorted layer restores it.
reference/masks-and-materials.md
.
8. Parallax
One factor per layer —
moves with the world,
is locked to the camera — applied
after the camera's final position for the frame. A layer placed before the camera trails
by a frame and shudders on every acceleration.
resources/ParallaxLayer.cs
runs after the
Cinemachine Brain, wraps endlessly for a runner, snaps to the pixel grid, and has
for
cuts and respawns. Camera timing itself is
→
reference/update-order-and-jitter.md
.
A scene split into depth layers (
→
) becomes one rig
with
:
mirrors continuous strips and shuffles props one per
tile with seeded gaps, so no prop stands beside its own copy; tile i always holds the same art.
;
reference/parallax-layers.md
.
The tools
| File | Does |
|---|
resources/Editor/SortingAudit.cs
| Read-only. Every renderer's four keys, group, sort point, lit or unlit, and tied pairs, as JSON. |
resources/Editor/Renderer2DSetup.cs
| the pipeline, renderers and sort axis. Creates a 2D Renderer or sets its axis after reporting the plan and waiting for confirmation |
resources/ParallaxLayer.cs
| One parallax layer: factor, wrap, pixel snap, |
resources/ParallaxTiles.cs
, | Endless tiles on a layer: Mirror, Repeat, Shuffle with gaps; deterministic per tile |
resources/Editor/ParallaxRigBuilder.cs
| + PNGs (or a PSD, ) → rig prefab. |
Menu root: Tools → Unity Dev → 2D Rendering.
Scope — what this skill does NOT do
Pixel-art filtering, the pixel-perfect camera and seams between tiles are
. Post-processing Volumes, bloom on lit sprites and renderer features
are
; moving a Built-in project onto URP is
. Sprite
pivots, slicing and secondary textures are
; packing is
.
Tile palettes, their own sort setting and rule tiles are
; which Tilemap goes on
which sorting layer is
→
. Skeletal sprite meshes
and bones are
. Colliders, including the Tilemap collider a shadow caster
reads, are
. Camera follow, confiners and shake are
. Draw
calls and frame time as numbers are
.