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. Dismiss Notice

Canvas sort order and batching

Discussion in 'UGUI & TextMesh Pro' started by Sandler, Sep 9, 2016.

  1. Sandler

    Sandler

    Joined:
    Nov 6, 2015
    Posts:
    240
    Hi im using a Canvas, with lots of nested Objects.
    I have a bitmap font, which uses its own texture / material.

    Hierarchy:
    Canvas > Image > Text
    Canvas > Image > Text
    Canvas > Image > Text
    ...

    I´d like to change the Text Sorting Layer to enable batching. So Images are all on Layer Background, Text all on Layer Foreground.
    With the Canvas > Canvas you can set the sorting layer... but this also breaks batching.

    Is there any way to keep the hierarchy and enable batching in this scenario? (As a button nearly always has a text, this should be more easily possible)

    Or do i need to do this:
    Canvas > Image, Image, Image
    Canvas > Label, Label, Label

    Which is kinda annoyin.

    Thanks!
     
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    I did a bunch of testing with various types of Canvas and Sorting Layers. It appears the Canvas object and all its children totally ignore the Layer variable assigned to them. They seem to exclusively use the Sort Order Variable. I had 2 Canvas, one with a Button and One with Some text. As long as they were both Sort Order 0 the Text always drew on top of the Button regardles of Hierarchy even. As soon as I set the Canvas with button to Sort Oder 1, it covered up the Text.

    I tried putting both Canvas in a Master canvas. I put both Canvas in a GameObject, Put them in their own separate game objects. But nothing made them care about the Layer I put them in. In fact I added a few sprites that were not children of a Canvas.. and put them in various Sorting layers and they all behaved as you'd expect. The canvas objects always drew on top of them. So I think Canvas and its children are always in the UI layer which gets drawn last no matter what.

    I believe your stuck with the solution:
     
  3. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Well I was silly in my testing and Didn't realize that Screen Space - Camera and World Settings on the Canvas created a new variable called Sorting Layer. So Canvas still ignore the Layer Setting you use up top, and only care about the Sorting Layer set in that variable in the Canvas Script. It also appears to control all the children's Layer. So if the Canvas is Set to Default, even if I set a child UI Text to ForeGround it will still draw the Text in the Default layer.

    So again I still think your stuck with the annoying solution
     
  4. conondev

    conondev

    Joined:
    Jun 9, 2016
    Posts:
    24
    So what is your solution for this please?
    We have 2 atlases in this case, and in the most optimized setting, we should have only 2 draw calls.
     
  5. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    I'm not sure what you meant by my solution. I was just verifying for the OP that Canvas's children totally ignore the sorting Layer. Their sorting layer is entirely dependent upon the sorting layer defined in the Canvas script. So if you wanted all the Image children of Canvases to be in one Layer, and all the Text children of the Canvases in another layer you couldn't do this using the normal Sorting Layer options. You would have to place all the Images in One Canvas, and all the Text in another Canvas, which as the OP suggested is annoying.

    And unfortunately, unlike all the rest of the UI scripts, the canvas script itself is not on the bitbucket site to make it easily modifiable.
     
    conondev likes this.
  6. Sandler

    Sandler

    Joined:
    Nov 6, 2015
    Posts:
    240
    My workaroung is the following.
    I use this Order for Design:

    Canvas > Image > Text
    Canvas > Image > Text
    Canvas > Image > Text
    Canvas > AllTexts

    After i switch to Playmode all Text elements are put into the AllTexts Container.
    Best solution i could think of.
     
  7. conondev

    conondev

    Joined:
    Jun 9, 2016
    Posts:
    24
    I also think about this solution. But this is fine for static elements/groups. And the best optimized solution is we should have an editor script to do that for every prefab before you game is building (to save cost reordering UI elements on real device).

    But with group of UI elements and if we have logic to handle their RectTransform (position, size, scale, ...) in running time this will be broken.
    Beside that, UI batching logic is not only rely on child order, but their position/size also (overlap area to each other). And this seems to make us could not have a predictable batching result.
     
  8. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    yes, basically you need to press Unity to allow children's Sorting Layer to override the Canvas Scripts assigned sort order. Which, unfortunately, I don't believe exists. The canvas and all its children are locked into one layer. Each canvas can have its own layer, but you need more functionality.
     
  9. tomerpeledNG

    tomerpeledNG

    Joined:
    Jul 14, 2017
    Posts:
    81
    I'm also encountering the same problem...
    My scene get drawn, not in the order that I would expect, which of course breaks the batching...
    I only have on canvas and I would like that it's children would be drawn according the the right order, however it seems that Unity sort the items to be drawn by some unknown and unpredictable algorithm :(

    Could you guys figure how can we control the drawing ordering?
     
  10. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Hello! Does anyone have a solution to this? Our UI is drawing a sprite, text, sprite, text, etc... and really increasing our draw calls.

    It seems like the only thing to do is move all text to their own canvas or parent, but this seems like we are over-complicating things when we need to instantiate list items for a scroll list.
     
  11. thienhaflash

    thienhaflash

    Joined:
    Jun 16, 2012
    Posts:
    513
    It's so annoying that we can not customize the drawing order when needed. There is no good solution for UI with a bunch of text & images mixed together (which is really really common).

    Whoever under the hierarchy-sorting decision has never actually used UGUI or at least has never trying to optimize it for low-end devices. Back to the NGUI time, we strive for 1-2 draw calls. With UGUI, we strive for 10s.

    I don't see how hard it is to implement a custom sort function that respects custom sort order (where we can put all the text to the same higher layer than other elements) so that all the texts can be batched, and all other images can be batched, too.

    After so many years, anyone on the UGUI team care?