I imagined that my 3D sprite layout would mean that I won’t have too many rendering order problems. So I tried to just get rid of all the sorting groups and let camera rendering path determine what is visible for start. Unfortunately, this totally doesn’t work as I quickly discovered:

I was hoping render order wouldn’t be this much of an issue with 3D, but my pseudo-3D stuff still needs special handling.

Some things do, like doors and walls do work better, but most other dynamic things still overlap. The issue is of course my billboarding of sprites (they aren’t vertical):

Since my current logic is a bit of a mess, I am making a new asset where I will store all the sorting values:

I can then assign it in the camera system for all world objects and other code to use:

Firstly, I specify my main per-tile multiplier for the render sort value. That is, each tile further from the camera is “moved” by this much:

I am also getting rid of directly specifying offset values (which are relative to current position) in world object prefabs:

Instead, they will specify their sorting designation, which is a nice readable enum:

Then my value asset can have an entry for each designation that specifies all the sorting offsets:

I can also clean up my effect extra-spaghetti logic for offsets above/below their current position:

By having them be separate entries in the list:

So this now organizes and cleans up the sorting value mess.

There is an issue with walls and doors now that they all sort under the same value, and happen to be totally broken:

I need separate values for these too. But this means that the same world object has multiple different sprite groups for sorting, and I can only specify one. Well, technically, two, since I already spaghettied that up:

So, instead, I made a separate script that holds a list of sorting group entries and their designations:

At runtime, this grabs and sets an offset for each group.

For simple cases, it has just one entry:

And now my tiles can have their sort entries for each part (top, bottom, sides):

And this works out nicely:

This pretty much covers all the immediate cases and different world object. Now I have to tweak my values in bulk and arrange things nicely. I am sure there are corner-cases that I cannot really overcome without lots of work, but I can probably fix most of the obvious issues.

I also added a debug-time flag that specified that all world objects should re-retrieve the value every update, so I can tweak the values live:

This saves a lot of time. Not only do I not need to recompile, but I don’t even need to restart the play mode. (Of course, this is impractically slow and messy in release.)

Eventually, I got the values sorted and the render order problems (mostly) fixed:

So yeah, this took way longer than I anticipated. The good part is that I made it all nicely organized now and much quicker to adjust and expand with way less hard-coding. Now, onto other 20 things to do about the 3D camera stuff.

MicroRogue DevDiary #88 – Sprite render order
Tagged on:

Leave a Reply

Your email address will not be published. Required fields are marked *