Search Unity

Adding an element at a different position

Discussion in 'Prefabs' started by dadude123, Jun 20, 2018.

  1. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Quick explanation:

    1. MyBaseWindow: Is a prefab with a VerticalLayoutGroup that contains: BackgroundImage, Title, Content, StatusBar
    2. MySpecificWindow: should inherit everything from MyBaseWindow and then add one more thing: Lets say a "ToolBar" that must go exactly between Title and Content.

    3. While creating MySpecificWindow and adding your ToolBar, to MyBaseWindow you will notice that you cannot add it at a specific place, only at the very end.
      Which will cause the ToolBar to be below the StatusBar.

    Possible Workaround

    • Add an empty GameObject to MyBaseWindow
    • Just for the sake of clarity you could name it "InsertPoint_BelowTitle"
    • Save the prefab
    • In MySpecificWindow you insert the ToolBar into the InserPoint_BelowTitle object.
    • Define whatever insert-points you need.

    This is somewhat ugly, but it works.
    Initially it seems this problem would appear everywhere, but as it turns out it's actually pretty rare, and the workaround is not all that bad (for now).



    ======
    Old Post:

    After seeing that the nested prefab system is out now I had to of course test it.
    And the primary use case for our game will be the UI. For everything else we have custom
    scripts that compose things at runtime.
    For the UI that's an exception because of course it is a massive advantage to have a "WYSIWYG"-style editor, instead of having make modifications, run the game, stop, ...

    Anyway, so I immediately ran into a limitation: It seems you can add something to a prefab, but you can't add it at a specific position in the hierarchy? How would I do the following then?

    Adding a new panel in the normal scene mode:


    Adding a panel in prefab mode:


    In this example MyWindow is a variant of Window.
    The "Window" (title text for it is "Base Window Prefab" in the scene view) defines the titlebar, content, and statusbar.

    MyWindow is supposed to have an additional "tool-bar" exactly between "Titlebar" and "Content", so the VerticalLayoutGroup on Window (and thus on MyWindow as well) will do the layout correctly.

    I don't want to make "insert-points" where derived prefabs can add their own stuff, because it is not predictable what should get added and where, or sometimes there would even be "collisions". Like what if one type of window has a sidebar (vertically), and the other has a toolbar (horizontally)... so defining empty GameObjects just as markers or containers to insert new elements is not viable.

    Am I doing it wrong?
    It seems like I can only add a new object at the last index and not somewhere inbetween.
    Is that completely impossible? Is it planned as a feature to allow inserting at any index?
     
    Last edited: Jul 15, 2018
  2. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Hi. Correct, added objects cannot be placed in between sibling GameObjects that are part of the Prefab. For technical reasons we were not able to support that. It might be possible to add support for but would not be trivial, which is why it ended up being cut.

    If this is a sufficiently big pain point for many people, we might bump it up in the list of priorities of what to look into next (and make us down-prioritize other things).
     
  3. Virtuactions

    Virtuactions

    Joined:
    Jun 5, 2017
    Posts:
    13
    From my point of view it surely need to be bumped up. In UI world it is essential, since all drawings and calculatings are based on order in hierarchy.
     
    Truun, Deeeds, interpol_kun and 3 others like this.
  4. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Oh, well placing objects anywhere in the hierarchy is really important.
    We're planning to use nested prefabs for our UI. And since the auto layout containers go by hierarchy order that seems pretty essential.

    May I ask what the current list of priorities is?
    Just so I can be aware of any other small "traps"/limitations that might still be around, and plan accordingly :p
     
    BAIZOR likes this.
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    Are you able to go into detail on that? Is it simply because everything is serialized to unity-yaml in-order?

    I know that you can remove components from prefabs instance and not lose the prefab connection, but reordering components loses it. In the scene file, removed components show up as m_RemovedComponents. I assume that having similar concepts for reordering of components and sibling indices isn't very straightforward?
     
    Deeeds, BAIZOR, MrCool92 and 2 others like this.
  6. Coroknight

    Coroknight

    Joined:
    Jul 10, 2012
    Posts:
    26
    Please prioritize fixing this and other inconsistencies related to the foundation of the new prefabs system.

    Myself and many other people would rather you establish a rock solid foundation without these corner-cases than adding a bunch of new features.
     
    Truun, Deeeds, interpol_kun and 3 others like this.
  7. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    726
    +1

    Seems necessary for UI elements.
     
    Stardog likes this.
  8. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    I vote to prioritize this, crucial for UI
     
  9. ian-gabriel

    ian-gabriel

    Joined:
    Feb 24, 2013
    Posts:
    12
    It seems like the whole UI layout system depends on this. I wouldn't call that a corner case, but a core feature that should be prioritized.

    Anyway, thanks for all the work you do, new features are exciting :)
     
    cirocontinisio likes this.
  10. ShivekGG

    ShivekGG

    Joined:
    Nov 13, 2016
    Posts:
    4
    another +1 for UI guys
     
    cirocontinisio and SM_AF like this.
  11. MrCool92

    MrCool92

    Joined:
    Jul 13, 2015
    Posts:
    26
    breaks the point of nested prefabs... definitely +1
     
  12. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    This is 100% required. As mentioned, since UI depends on the hierarchy for placement it makes it impossible to use them effectively for it. Please put this on the top of the priority pile.
     
    dadude123 likes this.
  13. scvnathan

    scvnathan

    Joined:
    Apr 29, 2016
    Posts:
    75
    Aw man, UI is such an ideal use-case for nested prefabs and the only scenario in my 2+ years of using Unity that I really felt a need for them. Is this where I vote my +1?
     
    dadude123 and BAIZOR like this.
  14. ErnestSurys

    ErnestSurys

    Joined:
    Jan 18, 2018
    Posts:
    94
    Same experience here, UI workflow needs this feature.
     
  15. JakobSchouJensen

    JakobSchouJensen

    Unity Technologies

    Joined:
    Jan 24, 2017
    Posts:
    5
    One challenge with allowing insertions is that it is unclear what should happen if the base changes. Assume, in the original example that a “SeparatorLine" element is added in the base prefab Window between TitleBar and Content. Where should the MyWindow ToolBar then go? Above or under the SeparatorLine? The person adding the SeparatorLine might not be aware of MyWindow and therefore unknowingly introduce an error.

    On the other hand the “insert-point” strategy would be more robust. The person creating MyWindow with the ToolBar would have to edit Window and insert a “ToolbarHolder” empty gameobject between the TitleBar and the Content. When at a later point somebody else want to add the SeparatorLine that person will know that there may be a ToolBar and can decide whether the separator goes above or below the toolbar.
     
  16. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    I would expect "SeperatorLine" to always go after the "ToolBar". The order in the variant should take priority imo, because that's what you're seeing in the build. The variant knows that "ToolBar" is always at index 1 in the sibling list and must maintain that index, no matter how many things are re-ordered or added. If "SeperatorLine" is needed above "Toolbar" you would need to adjust the variant.

    I think it's better to have something like this, a general rule that is always enforced. People can work around it, but better to have it than not, imo.

    Either way, there's a current solution using the holder method, so at least nested UI prefabs can still work.
     
    dadude123 and NikolaBinxCT like this.
  17. JakobSchouJensen

    JakobSchouJensen

    Unity Technologies

    Joined:
    Jan 24, 2017
    Posts:
    5
    Keeping the index fixed for Toolbar would mean that the Toolbar would appear above Title in MyWindow if something is added above Title in Window. It would not (in general) maintain the order in the variant.
     
  18. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    When the base prefab gets modified, get all the variants that inherit from it.

    Now update all the things in their xorrsct context. Basically this just means that you don't exactly modify the base prefab primarily, but all the "endpoints" in the hierarchy.

    That way you know how (in the base) how many items are actually between your title/content/statusbars in all your derived prefabs.


    That means that your base prefab will have to be defined like this internally:
    Base Window:
    - title bar @ index 0
    - content @ index 5
    - status bar @ index 6

    This example assumes that there are some more prefab variants and one of them has 4 game objects inserted between title and content.

    So every change in any prefab, has to recalculate all indices of all prefabs/variants belonging to the same hierarchy.

    Might sound a little expensive, but its not. Only transforms are processed, and not the components as well. And its only really rarely that the order of objects gets changed. Also at runtime everything is baked out anyway!
    Besides, you guys probably have an internal graph of prefabs and their variants anyway (I didn't look at the API yet but I will soon)




    That's just one idea, I'm sure you guy have even more and better ideas.
    But in any case the insert point thing might sound good because it is easy, but it is simply a terrible solution that does not even solve anything when it comes to UI because hierarchy and (z-)ordering are the fundamental principles of an UI.

    So lets forget that really fast :p
     
    Last edited: Jun 21, 2018
  19. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Correct, and I would be ok with this. It's not great for sure, but neither is having lot of holder game objects for things that might not even exist. If you could be confident in knowing what was above in the variant, then yes I would vote to always keep the inserted object after the previous child. i.e always after "Title"

    With the holder scenario, maybe there's a way to reduce some of the friction by automatically creating a holder in the base prefab whenever a person attempts to insert a child in a variant that would cause inconsistency. Something like a popup:

    "This action will modify the Base 'Window' prefab" - "Continue", "Cancel"

    If a person continues, the base Window creates a holder at the correct position and disables it.
    The variant updates, shows the holder activated with the inserted item being a child of it.
    And you should be able to undo this action too ;)

    Anyway, I'm sure you guys have had 1000 discussions about it. Curious to know what some of the workarounds may have been?
     
  20. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Surprisingly it doesn't even matter at all:
    Lets say I add this new "SeparatorLine" to BaseWindow.
    And then I realize that in MyWindow the ToolBar I added is now at the wrong spot.
    Then I'd simply drag-drop the ToolBar up/down to its intended position and all is well again.
    Is it even the prefab systems job to resolve those ambiguities? I say not at all!

    I mean, create ambiguous situations, get ambiguous results... as long as it can be clarified in a simple way its a non-issue.

    You already have a similar """problem""" when you right-click a GameObject in the hierarchy and add a new one: Is the new object supposed to go into the object as a child? As first child? As last? Or do you want to "insert at this position" essentially displacing the right-clicked object down? Or insert after at the same depth as the clicked object?

    Same answer there: It doesn't matter at all! Just drag it where it should be!

    What does matter is that prefabs work without wonky workarounds with the UI system, where it is needed the most by far.
    Because if I start redoing the UI for a game with the new prefab workflow + some strange workarounds (insert markers), then why would I not just stick with whatever temporary solution I got right now in the first place??
     
  21. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    I'd say it's a caveat, to the point of "Nested Prefabs... BUT..."
     
  22. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    Just to toot my own horn, I complained about the hierarchy position being important in the new UI system as a dumb idea in 2014. They could add some kind of render order integer to the UI components that would override the hierarchy position, but then you'd have to fiddle with numbers a lot, or can you use the Canvas component for this already?
     
    Last edited: Jun 22, 2018
  23. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    I'm not sure what you mean by that...
    Maybe I misunderstand your point, but are you saying that all UI should be in a linear layout!?
    Not sure, if that's not what you meant then please ignore the next paragraph.

    I don't think that is possible at all. You can't remove the need for a hierarchy from a concept that is completely defined by the hierarchy. This is not just about just z-ordering.

    How would you do input event-bubbling in a linear layout?
    What about resizing? How would you even begin to support anchors or pivots!?
    What about children that need to do layout based on the available space?
    Actually the concept of containers themselves would suddenly make no sense anymore.
    And what really is a window, or a button, if not a container for more stuff?

    Removing the absolute back-bone of graphical-user-interfaces: the concept of hierarchy, just to avoid having to add a feature to the serializer (that should be there anyway).
    That's like saying "Fire kills viruses, lets inject everyone having a cold with fire". lol.

    If the answer is "just have a reference to the parent in each component", then we're back at hierarchical organization again...

    Or maybe you meant just decoupling renderers from the layout logic? But then how would that solve anything regarding the problem in this thread?

    Personally I think the concept as it is is perfectly fine. Like, I can't even imagine an UI system that is not hierarchical. Think about XML (so HTML/DOM) is a hierarchy, WinForms, WPF, ...
    The he "silbling index" is always a very important concept in all of those technologies that cannot be removed at all.
    Want to write a list in HTML? The order in which the elements appear determines the order in which they are displayed in the list... it's pretty obvious.


    And the "insert points"-idea won't work either for anything but the most simple use-cases. (In fact, I'm truly sorry for even coming up with this stupid idea, and giving it any stage-light at all in my first post!!)

    The way I see it, just investing the time to properly fixing this is simply not avoidable.
    After all it would definitely pay off to get it "done right" (TM) as that enables a lot more things you can


    I think on the one hand it is great that this was already released as a preview now, so issues (huge gaping ones as this) can be resolved before some apocalypse scenario like "uhh, fixing it would break literally all previous prefabs now. we're too late its impossible now" can manifest itself :p

    On the other hand I do really have to wonder how it's even possible that not every single companies/studios that you Unity-devs worked with told you why this feature is absolutely essential.
    Like, I honestly don't know a more important use-case for the new PrefabWorkflow than UI.
    It's like the only thing that really requires (as in workaround are either very ugly, or very time consuming to implement, like a full on custom UI editor...) prefab nesting and variants.

    Anyway, Unity-devs! You guys did a great job so far!
    So please, please don't take offense or be discouraged by my words!
    We're all developers here (mostly? I guess?) and I certainly know how painful it can be to hear from people that they are not happy with the result; and how difficult it is to please everyone.
    Especially when it comes to a feature where people already have massive expectations (actually, we all know how ridiculously high the public expectations can grow when something is long-awaited :) )

    So tell us what you devs think about this problem, your ideas, ... lets keep the discussion going.
    I'm confident that together we can even find new potential approaches to this problem, should we see that no previously mentioned solution is acceptable.
     
    Last edited: Jun 22, 2018
    Devil_Inside and CDF like this.
  24. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    I didn't mean no hierarchy, just the positioning of children shouldn't be so important. They made it like Photoshop layers.

    With the current UI the click-drag ordering is essentially some type of visual coding of the layout. Ideally it would have more HTML/CSS where the position of the HTML doesn't matter as much. They could have built a visual UI editor on top of that, instead of making it the main way to do layout.

    You can change it with CSS, and modern CSS techniques like flexbox/grid have full reordering support by default. I think they are making an HTML/CSS style UI anyway, so it won't matter.
     
  25. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    365
    This def needs to be prioritized, i probably wont use the system until i can drag and drop the children hierarchy order... thats a huge oversight...
     
    dadude123 likes this.
  26. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Yes, the "retained mode" UI in the experimental namespace.
    That is editor only.

    Ah, ok nice! I can sorta see what you're on about, and it does indeed make sense. (or at least I can see that you're not trying to advocate for some radical change of concepts) :)

    However I still don't fully get it, would you care to elaborate?
    In HTML the position of the html matters very much actually. If you place one <li> before another one, then the order the items in the list changes! But that's not what you meant, is it?

    Do you mean they should not have used GameObjects/Transforms at all? And instead have some sort of "markup language", similar to HTML, or maybe even directly HTML + their own flavor of CSS (just like they're doing now for the new "retained mode" editor UI I think)? Is that it?

    If so, then yes, that'd probably solve *some* of the issues, but sibling indices are still important for other things as well.
    Maybe you have a mecha-bot that has a set of weapons on each arm that get fired in order.
    Or a group-formation for your peons in an RTS game, where the order in the group determines who's at the front or something, ...

    Well, actually, all those things can probably be worked around with by scripting as they are really contextual and specific to the game. So yes, maybe you're right and that would solve a lot of things (at least at a first glance :p)

    But the facts right now are: sibling index is massively important for ordering of elements in a layout-group.

    However, there might be a new way to solve this issue!! :D
    Imagine this: Modify the "Layout Element" component (for the unaware: the thing where you can set min-size, preferred size, ...) so it also contains an "OverrideOrder" field.
    Then modify all the *LayoutGroup components (Horizontal/Vertical/Grid/...) so they look for that new property (those groups have to check for the presence of a "LayoutElement"-Component already anyway, so no performance issue here).

    If that was made to work correctly at edit-time, it could be an actual solution.
    A solution that is ugly, not elegant, prone to errors (because people expect that the implicit order of the hierarchy keeps working! I can already see myself trying to reorder stuff outside a prefab and wondering why it's not working...), and a bad precedent of not fixing a massive feature-gap (which we know will cause more problems in the future) just because there's an easy way out.

    But at least it would be a solution.

    Actually, maybe lets make that OverrideOrder a float, so only that hypothetical toolbar has to get an LayoutElement and can set itself to "Oder: 1.1f", :p

    I think if the devs don't fix this until the final version, I'll just have to write my own layout groups and layout-elements as a replacement to all the built-in unity stuff. (Which will definitely break a TON of things that rely on an exact
    UnityEngine.UI.VerticalLayoutGroup
    to be there for example). And of course it would have that really bitter after-taste of a half-assed feature, and having to put some work in to get functionality that is supposed to work out of the box. (I know compared to all of the prefab-workflow it is not that big, but for people working with the UI it IS big :( )

    And lets not forget the impact this will have on stuff on the asset store.
    Really cool modular UI packs, now that its supposedly finally possible to make them using nested prefabs? Well, that will certainly take a hit since you can't really compose windows now. (Unless everyone and their mom comes up with their own hacked/extended layout groups)
     
  27. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    If I'm not mistaken...

    The suggestion is that when deciding the position and render-order of UI elements the hierarchy order is not the most important factor. Instead, there is a "position order" and/or a "render order" integer, and items are sorted by this before the hierarchy position is taken into account.

    This way you could place an item at the end of the list of children in a Transform, but the layout group is still able to sort it into any visual position within that list.

    For example, siblings such as this:
    • GameObject1 (order = 100)
    • GameObject2 (order = 200)
    • GameObject3 (order = 101)
    ... could be rendered like this:
    • GameObject1 (order = 100)
    • GameObject3 (order = 101)
    • GameObject2 (order = 200)

    I can see why Unity didn't go with that in the first place. On the plus side it would be equivalent to how... pretty much anything else is positioned and rendered. Order amongst siblings generally has no effect on this. On the minus side, at the time of implementation that would have meant a whole extra set of numbers and probably additional sorting and other computation to achieve a thing that could already be done, without providing any other benefits at the time (because workflows like this one didn't exist).

    I'm interested to know why this couldn't be put in place now, though. By default the position/render order will come straight from the hierarchy, the numbering can be automated, and most of the time nobody has to worry about it. If you hit a case where the ordering does matter then they're there to hand tweak, and you're involved in a case that needs direct developer attention anyway regardless of the approach taken.
     
    Stardog likes this.
  28. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Probably because there are tons of projects relying on the existing system.
    So that sort of thing would have to be optional. And if not that, then maybe because there's no time scheduled for someone to get some UGUI improvements going.

    Anyway, I understand that this would be a way to de-couple z-order from layout-order.
    Which is nice and all (and I agree the UGUI framework should have a way to do this, like every other UI system), however the actual problem here is about layout, and the interaction with all the implementations of the
    LayoutGroup
    components.

    While I can see that some extra sorting-number could enable some effects without having to mess with the hierarchy, I don't see how that approach would be appealing for layout-order.

    The way it is right now is how it should be. I expect its sibling index to determine its "layout order" in a layout-group.

    Why?
    Because it makes sense, that's why it is like that literally everywhere: WinForms, WPF/XAML, HTML, Qt, ...


    @runevision
    @JakobSchouJensen
    I completely understand that there might be even more important things.
    But it'd be really helpful if you could tell us if a fix for that is planned, or not.
    We need to plan our projects as well, and we need some information to be able to make an informed decision.
    Should we keep using (and improving) our own workarounds, or can we expect this to be fixed in 2018.3 (or maybe a few months later).
     
  29. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    No, it's a way to decouple layour order from hierarchy / sibling order.

    Yeah, this is exactly what I'm talking about. Rather than the order in the hierarchy, LayoutGroup would instead (or first) look at this "order" number to determine where to position things.

    I believe that what I suggested is already completely optional. If you do nothing then no results will be different.

    Another approach would be fundamentally similar, but instead of calculating the order numbers based on hierarchy position you have them all default to 0. For any ties, fall back to the existing hierarchy/sibling order. By default all values will tie and fall back to the existing system. If you want some other behaviour you can then set order numbers using whatever strategy you want.
     
  30. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    I agree it makes sense, and there are indeed plenty of other systems that use that approach. No argument there. However, consider that it's within the Unity hierarchy, and within that context it's actually unusual behaviour.

    Personally I'm not worried either way, as long as all cases are accounted for.
     
  31. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    There is no trivial fix for this limitation and so we can't fix it for the initial release. Right now we're quite busy with the initial release and haven't decided on prioritization of issues beyond that yet. We can't at this point give a time frame of when it might or might not get addressed, so don't count on it for your own planning.

    For now we recommend the workaround of inserting insertion point children where added elements can be added under as children, which also doesn't have the issue of ambiguous order which might otherwise arise.
     
    dadude123 likes this.
  32. tibbitts

    tibbitts

    Joined:
    Jul 1, 2014
    Posts:
    2
    You can't require that hierarchy order be a central way to sort UI and then remove the ability to change that order. This is breaking a whole section of the editor. Either hierarchy needs to be totally rethought or prefab nesting needs to allow reordering. Without that this feature is near useless and many are going to have to just keep using prefab evolution.

    In other words, if you are asking if this is a big problem, yeah, this is a huge problem.
     
    Deeeds likes this.
  33. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    I ran into this yesterday. First time I ever worked on UI in Unity, rather than little experiments.

    I had 3 things.

    A score, a frame/background for the score, and a number to be added to the score.

    And somehow, with only these three things, utilising only two of them, I ran into this, when sorting the background and the total.

    I was speechless. And still am. Stunning degree of peculiarity. Not even Apple Pages, in a browser, is this limiting.

    UGUI or whatever it's called is weird. Odd, actually. Like a hybrid of ideas, none of them quite finished, all of them not quite familiar with each other.

    Blending that with the rigidity, brittleness and obstinance of Improved Prefabs™ is a world of pain and anguish I wouldn't wish on anyone.
     
  34. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    What is the status of this issue now?
     
  35. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Most likely it won't be fixed.

    I use the "insert points" workaround all the time and it is working well.
    It might not be the most efficient, but it does the job.
     
    Dan2013 likes this.