I'm facing an issue that is limiting my work on my game.
I have a game object that contains a sorting group component that is set to "Background Layer".
And it's working fine with my gameobjects. They all are on the sorting group (Default). I even tried to set them to Background but that didn't help.
The moment I pass 31 gameobjects (i.e. renderers), it all starts to break. As in, the very first sprite in the hierarchy will jump to the front, and if I keep adding more sprites, it brings other sprites from the top of the list to the front.
I have no idea why it keeps breaking like this.
Any help would be appreciated!
EDIT: Check answer for a fix to this issue.
Ps. I have mesh renderers (spine2d) as well as sprite renderers under that BG gameobject. And I tried to see if the problem was with the mesh renderer, but it wasn't. It still broke even with Sprite renderers alone.
Okay! So, guys, I tried with the sorting group left and right and it still didn't work with me whatsoever.
I tried even making a new scene, adding a game object with just a sorting group component, and then tried to fill it with more than 31 sprites (give or take), and it still broke (bringing images high in the hierarchy to the front and even bringing random images.
And so I just decided to make my own sorting group script. It works just like it, and even better.
It allows the usual number of renderers which is more than 1000.
So here is how I did it:
First, we make a script that will be placed on the parent game object that would usually have the sorting group component. Delete the sorting group component, and add a new script. Let's call it: RendererSorter. Just as an example.
Fill this into it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class RendererSorter: MonoBehaviour
{
//This script is an alternative to the shabby unity sorting group system. It automatically orders sprites without any hassle. Allowing more than 1000 renderers.
public RendererMarker[] RendererMarkers; //Used for the sorting of groups.
public string sortingLayerName; //For the sorting of groups.
private void Update() //This will be called each time we change something in the scene.
{
if (Application.isPlaying)
{
return;
}
RendererMarkers = GetComponentsInChildren<RendererMarker>();
for (int i = 0; i < RendererMarkers.Length; i++)
{
RendererMarkers[i].SetSortingLayer(i, sortingLayerName);
}
}
}
Then, we make another script that will be attached to the game objects that contain a renderer (Mesh or sprite). Let's call this script, RendererMarker (just as it is referenced in the first script. And add this into it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RendererMarker : MonoBehaviour
{
// Marker used to give this gameobject's renderer the appropriate sorting group layer.
MeshRenderer meshRenderer; //It could be a mesh renderer.
SpriteRenderer spriteRenderer; //Or it could be a sprite renderer.
public void SetSortingLayer(int order, string sortingLayerName)
{
meshRenderer = GetComponent<MeshRenderer>();
spriteRenderer = GetComponent<SpriteRenderer>();
//Then we sort based on the type of renderer from the void paramater.
if (meshRenderer != null)
{
meshRenderer.sortingLayerName = sortingLayerName;
meshRenderer.sortingOrder = order;
}
else if(spriteRenderer != null)
{
spriteRenderer.sortingLayerName = sortingLayerName;
spriteRenderer.sortingOrder = order;
}
}
}
And viola! Just like that. The moment the scripts are attached to the scene, everything will update automatically according to the hierarchy in your game. You can see how everything is order in the public RendererMarker array from the main script.
I hope this helps anyone!