Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

UI elements sort order

Discussion in 'Getting Started' started by viveleroi, Jan 11, 2017.

  1. viveleroi

    viveleroi

    Joined:
    Jan 2, 2017
    Posts:
    91
    I'm creating some Image elements from C#, they're dynamic backgrounds for a text element. The image objects are being added to the same parent GameObject the text lives under.

    No matter what I do, I can't get the text to render on top of the Images. Since the text doesn't have a sortOrder I've tried setting the z positions on all elements, but it doesn't make a difference.

    There are no errors or warnings in the console.
     
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Render order for UI elements is based on the hierarchy order. So move items up or down the hierarchy to change when things get rendered.

    Its different from the rest of Unity, just to be fun.
     
  3. viveleroi

    viveleroi

    Joined:
    Jan 2, 2017
    Posts:
    91
    I must be doing something wrong then. When I made this post, I was adding the Image elements to the parent of the Text element. Just in case unity doesn't like the fact that the Image and Text became siblings, I made a new GameObject to nest the text under. That doesn't work either.

    -> TextBubbleBackground <- Image elements added via code here.
    -> GameObject
    -> TextBubbleText

    No matter what the Image(s) always cover my Text.

    EDIT: Playing around with transform SetAsFirstSibling / SetAsLastSibling methods. Even thought the objects are no longer siblings, they work as long as I set the index for every sibling.
     
    Last edited: Jan 11, 2017
  4. CuirassEntertainment

    CuirassEntertainment

    Joined:
    Aug 29, 2017
    Posts:
    1
    If I am using a grid order layout and want my objects in a specific order, simply changing their order in the hierarchy will not work, they will be physically moved. Is there another option?
     
    io-games, steril, xaldin-76 and 3 others like this.
  5. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    I think Canvas component with Override Sorting option checked would help with this.
     
    porig, Jaiweed, Wonkanese and 12 others like this.
  6. mikewilliams76901

    mikewilliams76901

    Joined:
    Jan 29, 2014
    Posts:
    3
    VLukianenko's suggestion worked for me. Many thanks!
     
    ThePanJake and VLukianenko like this.
  7. ThisIsDangerous

    ThisIsDangerous

    Joined:
    Dec 3, 2018
    Posts:
    39
    Please mind the downsides and consequences. Every another canvas breaks batching thus increasing draw calls amount. One call for things below the new canvas, one for the new canvas with children and one for something on top of it. This may really kill performance if it is done say in a backpack item prefab. Even a small backpack with 8x8 items may result in 3*64=192 draw calls made (instead of just one!) just to render your backback.
     
    customphase and apostelzhuk like this.
  8. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    Unity Team at Unite recommended breaking things into smaller canvases for better performance, since every little change in one big canvas makes the whole canvas redraw.

    References:
    - Unite
    https://doozyentertainment.zendesk.com/hc/en-us/articles/360002576153-UI-batching-in-Unity - some blogpost, which says same but in text.
    "So if you use one big canvas for your entire UI then you are doing it wrong."

    While you don't need to make every little item a separate canvas, since that'll introduce problem that LanVision described, but you better divide your big canvas into separate smaller canvases that have own update logic, independent from other elements.

    That is, however, a 2 year old info. Please let me know if this have changed.
     
    ThisIsDangerous likes this.
  9. ThisIsDangerous

    ThisIsDangerous

    Joined:
    Dec 3, 2018
    Posts:
    39
    No, that hasn't changed. However, following recommendations blindly isn't going to do any good if one doesn't understand the underlying reasons.

    Dividing canvases can greatly increase performance if there are changing layout elements. If a layout element has changed, these changes will "propagate" to parenting layouts in the same canvas. This usually means that the whole canvas is going to be recalculated. So it is generally a good idea to enclose such changing elements into a separate smaller canvases because such layout changings won't go beyond the canvas enclosing it.

    So, canvas dividing is good when there are too many UI calculations which can be constrained into smaller canvases.

    But think a minute about a general backpack full of items. They are usually just put in their places once and aren't really going to change after that. There are no layout changes and no propagations going to happen at all in this case. So there really is no need to produce any more canvases besides just one. But the added draw calls overhead may and will decrease performance here (more calls means more impact).

    All in all, fellow developers, please think of what you are doing, even if it is 'recommended' by Unity team. Because every such recommendation is intended to solve some problem which probably doesn't actually exist in your project. And bear in mind the price you may have to pay for implementing them.

    EDIT: By "changing" I of course mean changes in size, positions etc, not changing one image to another one.
     
  10. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    Since that's what I've said in the sentences after the video link, I fully support your statement.
     
    Egad_McDad and pavel_fadrhonc like this.
  11. DavDevGames

    DavDevGames

    Joined:
    Jul 11, 2017
    Posts:
    9
    Hello. So I've used the Override Sorting solution in my project and it worked fine until I deactivate and reactivate the ui. Any way around it?
     
    Visuallization likes this.
  12. DevGa_me

    DevGa_me

    Joined:
    Jun 16, 2019
    Posts:
    3
    What if we have two canvases. I have a canvas by default in the scene. When scene runs, a new canvas appears from the previous scene ( because of Dont destroy on load on the canvas of the previous canvas). Now after the scene started running, the new canvas always appears in the end of hierarchy. Due to this reason all the elements of the previous canvas are rendered beneath the new ui. This is the order of the hierarchy:

    Gameobjects -> Default canvas -> New Canvas from the previous scene.

    I want a particular gameObject from the Default canvas rendered above the new canvas...
     
    Rutger likes this.
  13. Arairn

    Arairn

    Joined:
    Aug 21, 2020
    Posts:
    2
    If anybody runs into this problem, here you are: i just found that on Canvas component there is a Sort order field, that does the trick, at least it did for me.
     
    Pff18, rcFMS and LockedFire like this.
  14. LockedFire

    LockedFire

    Joined:
    Oct 16, 2018
    Posts:
    1
    I was just about to say that . . if you seperate it in a different canvas, just use "Sort Order" (put the index of the canvas as high for the one you needed in the back)
     
  15. danielmanzie87

    danielmanzie87

    Joined:
    Dec 4, 2020
    Posts:
    5
    It's weird, but the sorting order goes bottom-up in your canvas. So, the lowest game objects in your canvas show up first.
     
    shoutr_work_tt and twitchfactor like this.
  16. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It may help conceptually to think of it as rendering order. Items are rendered from top to bottom, meaning the first item on the list is behind the last item.
     
  17. twitchfactor

    twitchfactor

    Joined:
    Mar 8, 2009
    Posts:
    356
    This is probably the most useful piece of information in this entire thread! Seriously, knowing THIS one little bit of information solves the problem that all the back and forth BS on new canvases doesn't.

    All I had to do was put a number in front of the name, to force a sorting order in the hierarchy, but it still didn't seem to work right, until I read it was "bottom up". I changed my numbering order and BAM! Everything is sorted as intended, without resorting to extra canvas trickery.
     
    shoutr_work_tt and _eternal like this.
  18. juvelezm

    juvelezm

    Joined:
    May 23, 2018
    Posts:
    9
    You have to take in count 2 sceneries here: Static UIs and Dynamic UIs created/added on runtime, the first one is solved sorting by Hierarchy in the Canvas it self, but the second one is solved using SetSiblingIndex(int index)

    Is usually common that some already created UI elements in Hierarchy need to be on Top of the new runtime created UI elements, is in these cases when SetSiblingIndex become pretty useful:

    https://docs.unity3d.com/ScriptReference/Transform.SetSiblingIndex.html
     
    MarcelinoAndrade likes this.