This is a naive implementation of a Z-sorting in order to fake 3D depth using sprites in a 2D scene. I would appreciate feedback on this, especially for performance as this has to be called each frame to handle moving objects.A ZIndexHandler is added to every object that may need to be sorted. When an object is loaded in the scene, OnEnable is automatically called by Unity3D. When the object is removed or hidden, OnDisable is called.Each object registers and unregisters itself from the ZIndexManager depending on whether it needs to get sorted on not.public class ZIndexHandler : MonoBehaviour{    //A transform is used to place the position offset of the object    //So that PositionOnScreen is not the middle of the sprite    [SerializeField]    private Transform positionOnScreenTransform;    public Transform PositionOnScreenTransform    {        set { positionOnScreenTransform = value; }        get { return positionOnScreenTransform; }    }    public Vector3 PositionOnScreen    {        get { return positionOnScreenTransform.position; }    }    //If true, this object won't get sorted.    [SerializeField]    private bool ignoreZBuffer;    public bool IgnoreZBuffer    {        get { return ignoreZBuffer; }        set        {            ignoreZBuffer = value;            if(!ignoreZBuffer)                updateHandlerActivy(true);        }    }    //Pointer to the ZIndexManager singleton    private ZIndexManager indexManagerInstance;    //The sprites in this objects are all stored here once and for all    protected List<SpriteRenderer> sprites;    protected virtual void Awake()    {        sprites = new List<SpriteRenderer>();        //Recursively search for sprite in the object's hierarchy        findAndStoreSpritesRecursive(transform);    }    void OnEnable()    {        indexManagerInstance = ZIndexManager.Instance;        updateHandlerActivy(!ignoreZBuffer);    }    void OnDisable()    {        updateHandlerActivy(false);    }    //Register or unregister this object to the Z-sorting process    private void updateHandlerActivy(bool needSort)    {        if (indexManagerInstance)        {            if(needSort)                indexManagerInstance.registerObject(this);            else                indexManagerInstance.removeObject(this);        }    }    private void findAndStoreSpritesRecursive(Transform curTransform)    {        SpriteRenderer sr = curTransform.GetComponent<SpriteRenderer>();        if (sr != null)            sprites.Add(sr);        foreach (Transform t in transform)            findAndStoreSpritesRecursive(t);    }    public void setZIndex(int index)    {        foreach (SpriteRenderer s in sprites)            s.sortingOrder = index;    }    public override bool Equals(object other)    {        return GetInstanceID() == ((ZIndexHandler)other).GetInstanceID();    }    public override int GetHashCode()    {        return base.GetHashCode();    }}The ZIndexManager class is a singleton that handles the sorting.public class ZIndexManager : MonoBehaviour{    List<ZIndexHandler> screenObjects = new List<ZIndexHandler>();    //The Z index starts at 10 to leave some space for the background    public static int StartIndex = 10;    //Singleton implementation using FindObjectOfType    private static ZIndexManager instance;    public static ZIndexManager Instance    {        get        {            if (instance == null)                instance = FindObjectOfType<ZIndexManager>();            return instance;        }    }    public void registerObject(ZIndexHandler obj)    {        screenObjects.Add(obj);    }    public void removeObject(ZIndexHandler obj)    {        if(screenObjects.Contains(obj))            screenObjects.Remove(obj);    }    public void sortZBufferOnList(ref List<ZIndexHandler> list)    {        //Put everything in the correct order based on the Y position of the object        list.Sort(delegate (ZIndexHandler zi1, ZIndexHandler zi2)        {            if(zi1 && ! zi2)                return -1;            else if(!zi1)                return 1;            Vector3 p1 = zi1.PositionOnScreen;            Vector3 p2 = zi2.PositionOnScreen;            if (p1.y == p2.y) return 0;            return -1 * p1.y.CompareTo(p2.y);        });        //Iterate over each object to update their Z index        for (int i = 0; i < list.Count; ++i)            list[i].setZIndex(StartIndex + i);    }    void Update()    {        sortZBufferOnList(ref screenObjects);    }}
Z sorting implementation for a 2D isometric game
c#;sorting;coordinate system;unity3d