Hi All
Im having a bit of a nightmare with child Objects and their render order, I have a slider script which creates 4 child objects
empty
full
mask
pin
The script creates the gameobjects in the correct order in the Hierarchy, however as soon as I access methods such as transform.Localposition the draw order changes, breaking the editor hierarchy completely, something which isn’t mentioned in any of the tutorials. Im presuming it because setting the transform position x and y defaults the Z to 0 and that I have to create a separate sortingLayer for ALL of my Objects which have child Objects and the sorting order then has to be set for each child object, which is a bit cumbersome and messy. And I dont know how to automatically create a unique sortingLayer in code for each GameObject that has children, or how to then nest those sorting Layers in other sorting Layers for example
UISortingLayer
—Slider1SortingLayer
-----Empty
-----Full
-----Mask
-----Pin
—Slider2SortingLayer
—Slider3SortingLayer
—Button1SortingLayer
—Button2SortingLayer
What Im really confused about is that when any new game object in the editor is added, its set to z = 0 and sortingLayer Default and sortingOrder = 0 so how is the Editor drawing the correct order ??? but as soon as you give the transform position a z value of 0 in code (the value hasn’t even been changed from the value in the editor) it breaks the order ??? Is this a bug And whats the work around ? Ive googled extensively and people seem to be having this issue as far back as 2015 but no definitive answers…
Thanks
UI components don’t care about z when doing what is drawn on top of other stuff.
They are drawn from top to bottom, which means your Empty is drawn first, your Full is drawn on top of it, then the Mask, etc.
Unless I’m completely misunderstanding the issue you are running into.
Hi Brathnann Yes thats what it should be doing but it isnt Ive been messing around with canvas but Im not getting on with it so Im baking my own SpriteRender based UI so my order in the hierarchy is currently something like this (Im experimenting)
Canvas
—Image
—Image
—Button
Slider
—Empty
—Full
—Mask
—Pin
Now I insatiate my child objects of slider like this
void OnValidate()
{
if (transform.childCount == 0)
{
empty = new GameObject("gameobject");
empty.AddComponent<Transform>();
empty.AddComponent<SpriteRenderer>();
empty.name = "empty";
empty.transform.parent = this.transform;
full = new GameObject("gameobject");
full.AddComponent<Transform>();
full.AddComponent<SpriteRenderer>();
full.name = "full";
full.transform.parent = this.transform;
mask = new GameObject("gameobject");
mask.AddComponent<Transform>();
mask.AddComponent<SpriteMask>();
mask.name = "mask";
mask.transform.parent = this.transform;
pin = new GameObject("gameobject");
pin.AddComponent<Transform>();
pin.AddComponent<SpriteRenderer>();
pin.name = "pin";
pin.transform.parent = this.transform;
full.GetComponent<SpriteRenderer>().maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
empty.GetComponent<SpriteRenderer>().maskInteraction = SpriteMaskInteraction.VisibleOutsideMask;
}
else
{
empty = this.transform.Find("empty").gameObject;
full = this.transform.Find("full").gameObject;
mask = this.transform.Find("mask").gameObject;
pin = this.transform.Find("pin").gameObject;
}
if(emptyImage != null) empty.GetComponent<SpriteRenderer>().sprite = emptyImage;
if(fullImage != null) full.GetComponent<SpriteRenderer>().sprite = fullImage;
if(maskImage != null) mask.GetComponent<SpriteMask>().sprite = maskImage;
if(pinImage != null) pin.GetComponent<SpriteRenderer>().sprite = pinImage;
}
All works fine the order in the Editor is as expected in my Hierarchy above, but when I call other properties and methods such as the transform.localPosition (at least I think thats whats triggering it) I get this draw order something like this
Cavas
—Image
Empty
Full
—Image
—Button
Slider
—Mask
—Pin
Ive since discovered SortingGroups applied to the parent Slider Object
using UnityEngine.Rendering;
[RequireComponent(typeof(GameObject))]
[RequireComponent(typeof(SortingGroup))]
[RequireComponent(typeof(Transform))]
Solves this problem and I think another masking issue of making sure the mask only Apply to the child objects, Empty and Full of Slider ONLY, and not other sliders or other Objects with masks, I was having too ! Fingers crossed although Im not sure if that is expected behaviour or how it works, I haven’t tested it thoroughly yet. But its still perplexing why the renderOrder without SortingGroups messes up the render order when transforms are used