2D top-down sorting script that doesnt rely on camera?

My current script for creating a 2.5D effect looks like this:

public class Sorter : MonoBehaviour {

    private SpriteRenderer spriteRenderer;

    void Start()
    {
        spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
    }

    void Update()
    {
        spriteRenderer.sortingOrder = (int)Camera.main.WorldToScreenPoint(spriteRenderer.bounds.min).y * -1;
    }
}

This script uses the camera to set the sortingOrder. It works perfectly but with this method I need to set it in update, and with 1000-ish object with this script (of which 980 are static) this feels really wasteful (?). But not sure how I can create a Script that only sets the position on Start() if the object is static, something like:

    private SpriteRenderer spriteRenderer;
    public bool OnlySetOnce;

    void Start()
    {
        spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
        spriteRenderer.sortingOrder = (int)Camera.main.WorldToScreenPoint(spriteRenderer.bounds.min).y * -1;
    }

    void Update()
    {
        if (!OnlySetOnce)
        {
            spriteRenderer.sortingOrder = (int)Camera.main.WorldToScreenPoint(spriteRenderer.bounds.min).y * -1;
        }
    }
}

However this obviously wont work if I use the camera to control the sortingOrder, any ideas?

You can use the Transparency Sort Mode and Transparency Sort Axis found Edit > Project Settings > Graphics, or Camera.transparencySortMode, to set the automatic sorting method.

It sounds like you’d probably want something like this:

Camera cam = Camera.main;
cam.transparencySortMode = TransparencySortMode.CustomAxis;
cam.transparencySortAxis = cam.transform.up;

Im not sure I understand.

Does this not require sorting layers?
Where would I add that code?
Would I still use orthographic camera?
Should I make any changes in “Edit > Project Settings > Graphics”?
Should I keep my old Sorting Script or replace it, as mentioned I want the drawing order to only be set once on static objects.

From the docs:

This isn’t a new addition to your system, it’s changing what Unity is already doing. So that makes it clear that SortingOrder and associated properties will take priority over this setting.

If two objects have the same sorting properties, they will be sorted using this sort mode, which is why they sort by depth by default. Now, instead, they will sort based on the camera’s up vector.

If your camera never changes orientation, you can set that once from any script in Awake. If it does rotate at all, you’ll have to update that setting with the new up vector.

Hi thanks for helping. I tried adding your code to the Awake() on my Camera. That is the only change I made (maybe I’m still misunderstanding you), and I get the same effect as I did before (i.e it sets sorting layer on Start(), but since I move and Im still using:

spriteRenderer.sortingOrder = (int)Camera.main.WorldToScreenPoint(spriteRenderer.bounds.min).y * -1;

to do sorting, it does not work. I’m sure I must be missing your meaning somehow, I would think that the above line is the one that needs changing?

If your camera never rotates, then you don’t need that line anymore. Your sprites will automatically sort based on their position on the camera’s local Y axis.

1 Like

:open_mouth: What kind of dark magic is that. Thank you Wizard. Keep using ur powers for good!

The reason I had trouble understanding was cus I thot it could not be that easy, haha.

For anyone following, here is a video doing the same thing:

https://unity3d.com/learn/tutorials/topics/2d-game-creation/sorting-groups-and-transparency-sort-axis

1 Like

Do you know why this stops working when I add another sorting layer? :S
Not even doing anything w it, just added one and poof; stopped sorting. Works again when I remove the Sorting Layer I created