How do I do sprite sorting correctly for a top-down 2D RPG?

I am making a top-down 2D RPG (Chrono Trigger, Final Fantasy, etc) and I am using the universal render pipeline with a custom transparency sort axis of (0, 1, 0). In my game, both characters and objects can be taller than 1 tile. I want characters to be able to walk in front of or behind tall objects depending on their y-position.

A player should be considered in front of an object if their pivot point y-position is less than the pivot point y-position of an object. For example, if the character pivot point is located at (0, 0) and an object pivot point is located at (0, 1), the character should appear in front of the object.

6472268--726557--Untitled-2.png

The above image shows the desired behavior and I have (mostly) achieved this result using the following:

  • Sprites are on the same sorting layer
  • Sprites have the same order in layer
  • Sprites all have a Sprite Sort Point of Pivot
  • I have set the pivots to match the example above

However, I run into a problem if I have two or more sprites at the same location. In my example above, I have two images—a wall and a window—and they both have identical dimensions and pivot points. I want to place one in front of the other.

If I change the order in layer of the window, it will appear on top of the wall but also the player—not desirable.

Or, if I leave them with the same order, the result is unpredictable—sometimes the window might be behind the wall, and other times it might look correct.

How should I approach solving this problem? Ideally I’d like to be able to have multiple images with the same layer, order in layer, and position, but control how conflicts are resolved (i.e., how the images with the same transform position should be ordered when rendered).

Any help is much appreciated!

Try adding a Sorting Group component to the wall and window. As far as I understand it that should keep them together.

@Zephus answer is the best way to do it

alternatively you can change the position of the window to be y - 0.000001 so it is in front of the wall but by a micro amount

@Zephus I am currently using tilemaps to do all this, including objects. If I use your solution, it sounds like I will need to remove the objects from the tilemaps and make them prefabs composed of:

  • A root object with a sorting group component
  • Sub-objects hierarchically arranged in the order I want them to render

Does that sound right? I’m not opposed to that. Although it feels a little less elegant in terms of map design, I can probably offset some of that with a special brush.

For anyone else reading, this approach will cause the entire object with the sorting group component to be sorted according to its transform y-position, ignoring the positions of all its sub objects, so consider this when deciding whether to use Zephus’s approach.

Thanks to both of you who helped me <3 I’ll report back with any findings.

I don’t think this is possible with just tilemaps. Those work in layers, but you need a dynamic solution. If you would try to do this in Photoshop, you’d also have to change layers depending on the sprite’s position. The cleanest way would probably be to use the 2D Tilemap Extras package (which is still in preview, but works), create your prefabs and use the Prefab Brush to draw them into your tilemap.