Search Unity

Why doesn't Layout Element have Max values?

Discussion in 'UGUI & TextMesh Pro' started by deram_scholzara, Oct 16, 2014.

  1. deram_scholzara

    deram_scholzara

    Joined:
    Aug 26, 2005
    Posts:
    1,043
    Why doesn't Layout Element have Max Width and Max Height? Without this, as far as I can tell, it is impossible to do a shrink-to-fit text box which wraps text (and expands the height) when a maximum width is met.
     
    Ultroman likes this.
  2. Mikeysee

    Mikeysee

    Joined:
    Oct 14, 2013
    Posts:
    155
  3. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    The preferred width and height function this way as long as the flexible width and height are zero.
     
    Erveon and BryanTaiNexusMedia like this.
  4. deram_scholzara

    deram_scholzara

    Joined:
    Aug 26, 2005
    Posts:
    1,043
    Then why isn't this box shrinking to fit the text? It is always expanded to the maximum width of the layout group's bounds, even if there isn't enough text to require that much width.
    Screen Shot 2014-10-16 at 3.54.52 PM.png
    Screen Shot 2014-10-16 at 3.55.10 PM.png

    Edit:
    The only way I've found to fix the issue is to also put my dialogue box (with its own layout group) inside another object with a horizontal layout group, then set it's flexible width to 0 and add two layout elements on each side with flexible widths of 100 (using 1 doesn't "squeeze" it hard enough). Having an explicit maximum width for layout elements would eliminate the need for these extra flexible elements, as it would prevent the text box's width from expanding beyond that value, while also still allowing it to automatically shrink to fit the text.

    Edit 2:
    Essentially, I guess the real problem is that there's no way to explicitly limit the "Preferred Width" of a text box - as far as I can tell (you can set it, but not limit it). A text box will just expand its preferred width indefinitely unless it is limited to a parent layout group's width, in which case the text will not shrink to a smaller preferred width than the width of the layout group (thus preventing a shrink-to-fit behavior).
     
    Last edited: Oct 17, 2014
    travlake and Mikeysee like this.
  5. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    It's the parent you want to resize to fit the child? You didn't say so before, but no problem!

    Just add a HortizontalLayoutGroup and a ContentSizeFitter to the parent. (The layout group should have force expand child width and height disabled.) For more info, see here: http://docs.unity3d.com/460/Documentation/Manual/HOWTO-UIFitContentSize.html
     
    djkpA and -chris like this.
  6. deram_scholzara

    deram_scholzara

    Joined:
    Aug 26, 2005
    Posts:
    1,043
    Maybe I missed something, but that doesn't seem to work either.

    If I have force-expand width disabled, while the ContentSizeFitter is Preferred Width, it does shrink to fit, but it also expands beyond my desired maximum width of 500. Shown in these screenshots:
    Preferred Width - Inspector.png
    Preferred Width - Scene View.png


    If I change the ContentSizeFitter to Unconstrained, and set the rect's width to 500, the text will shrink to fit, but the border will not. Shown here:
    Unconstrained 500 Width - Inspector.png
    Unconstrained 500 Width - Scene View 1.png
    Unconstrained 500 Width - Scene View 2.png
     
  7. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Ok, I misunderstood what you wanted.

    I think what you want is then:

    ButtonContainer object with
    • HorizontalLayoutGroup with ChildForceExpand off
    • ContentSizeFitter with horizontal unconstrained and vertical set to preferred
    • Set the width of it to the max width you want
    • Nothing visual on it
    Button (as child of ButtonContainer) with
    • HorizontalLayoutGroup with ChildForceExpand off
    • Background image for button
    Text (as child of button) with
    • Text for button
    The idea here is that the ButtonContainer HorizontalLayoutGroup will size the Button width according to its preferred width, but not make it larger than the whole group width (unless the Button min width is larger, but by default is 0).
     
    robertono, slice3d and ZammyIsOnFire like this.
  8. deram_scholzara

    deram_scholzara

    Joined:
    Aug 26, 2005
    Posts:
    1,043
    Ah, excellent - thank you. - I was actually just about to post that I had basically done just that. Screenshots attached, in case you or others are curious how I set it up. Edit: Layout Handler inherits the parent's width (500), which is just for the sake of convenience (no digging into the prefab's hierarchy).
    Screen Shot 2014-10-20 at 4.23.59 PM.png

    Screen Shot 2014-10-20 at 4.23.11 PM.png

    Screen Shot 2014-10-20 at 4.23.28 PM.png

    Screen Shot 2014-10-20 at 4.23.42 PM.png
     
    robertono, Evole and fluiddot like this.
  9. xenotime

    xenotime

    Joined:
    Apr 27, 2010
    Posts:
    12
    Hello everybody.

    This solution works perfectly with a single element but not in the following more complicated case.

    So I have a dynamic scrollable list with some elements.
    Each element behaves like ButtonContainer and so it must shrink to the text width but does not exceed a maximum width (so that the text wraps).

    Here the hierarchy :

    ¤ ScrollView object (ScrollRect, Mask, Image)
    • ScrollRect
    • Mask
    • Image
    ¤ Content object (as child of ScrollView)
    • HorizontalLayoutGroup with ChildForceExpand off
    • ContentSizeFitter with horizontal set to preferred and vertical unconstrained
    ¤ Several ButtonContainer (like yours) as child of Content.

    But in this case it does not work anymore. Because of constraints introduced by the HorizontalLayoutGroup on the Content object, I can't set the max width of a ButtonContainer. I tried unsuccessfully to add a LayoutElement (preferredheight sets to my max width and flexiblewidth sets to 0) on ButtonContainer (this one will be aways the max width...)

    If anyone has a solution, I will be grateful.
     
  10. levykin

    levykin

    Joined:
    Nov 7, 2013
    Posts:
    2
    If it helps, I found that LayoutGroup itself acts like LayoutElement (you can see it if you open class hierarchy - LayoutGroup implements ILayoutElement). So, if you want to add LayoutElement and be sure it works as expected, create extra child object and move LayoutGroup to this child. This looks like nor bug nor undesired behaviuor.
     
  11. WTFG

    WTFG

    Joined:
    Dec 15, 2012
    Posts:
    3
    That really work perfectly!
     
  12. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    This conversation is unbelievable.
    Wouldn't it be much better to have Max width and height on the Layout Element?
    We're limited to not using Child Expand, in the case we can make it work. After hours, I still didn't.
     
  13. Nimred

    Nimred

    Joined:
    Nov 1, 2014
    Posts:
    46
    I agree, I had the same problem today but the above solutions did not work for me - too many layouts in the mix. UI in unity is nice but it easily breaks down when you combine too many layouts and content fitters together... Max width on the layout element would probably solve many problems and avoid extra complexity.
     
  14. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    I tried this technique in an a blank scene and it worked out ok. Max width in would be nice to have in Layout Element component though, without this technique it's a bit confusing.

     
    Last edited: Feb 23, 2016
    Ultroman and Ghosthowl like this.
  15. Kerihobo

    Kerihobo

    Joined:
    Jun 26, 2013
    Posts:
    65
    Aaaaargh! Please, Unity, please add MaxWidth/Height to the layoutElement! I get this:

    upload_2016-4-6_13-39-32.png

    It does not seem to care that I have a PreferredHeight set for anything:

    upload_2016-4-6_13-40-24.png

    I'm gonna have nightmares if I can even sleep at all!
     
  16. IzzySoft

    IzzySoft

    Joined:
    Feb 11, 2013
    Posts:
    376
    I'm sure someone will come up with an easier way to add Min/Max.

    kissUI has something similar.

    ex:
     
    rakkarage likes this.
  17. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    You have Child Force Expand enabled. Please try to uncheck it on all LayoutGroups and see if not that helps.
     
  18. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    If either width, height, or both of "Child Force Expand" is not enabled, then the whole UI mashes together into 1 very thin line, even when preferred width/height are set, and the fixed width/height are set to 0 sometimes. I had to create a custom script just to handle this.
     
  19. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    I have not seen this myself and can't reproduce it here. What do you have at the top level? Layout elements will expand to their preferred width unless parent groups force them to be smaller. This might happen if you have a ContentSizeFitter that's set to size things to minimum width (which might well be 0) rather than preferred width. But otherwise I don't know why it would happen and would need more details (like a project folder or detailed video) to be able to tell what's going on.
     
  20. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    This is already fixed by recreating everything again. I thought it might be worth to say that this can happen, just that I don't know much about it.

    In the image, I had to drag-select the text and move my mouse downwards in order to highlight all of the text that aren't shown.

     
  21. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    @runevision so I found one drawback with this technique, long wrapping text will make the container go to it's full width even if the text wraps and becomes smaller.

    For example, the string "Because 8 accoutrements" would do the following (all imaginary values):

    top max width 100
    bottom max width 99

    Code (CSharp):
    1. +-----------------------+
    2. |Because 8 accoutrements|
    3. +-----------------------+
    4.  
    5.  
    6. +-----------------------+
    7. |Because 8              |
    8. |accoutrements          |
    9. +-----------------------+
    10.  
    The text draws to it's maximum width then wraps, but leaves the container stretched out. Instead of:
    Code (csharp):
    1.  
    2. +-------------+
    3. |Because 8    |
    4. |accoutrements|
    5. +-------------+
    6.  
    I would imagine there's a case for both outcomes, but currently no way to control it.
     
  22. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Yeah this is indeed a limitation of the layout algorithms used. It has a fixed number of passes. In the first pass the layout system asks the controls what their minimum, preferred and flexible widths are, and it then allocates space for all the controls based on what they each reported and how much room there is for for each when it has to be divided between them. In the second pass each control is just told how big it is.

    The functionality you describe makes things more complex. Only once a control is told how much room it has, can it know if it can shrink further based on that. Then this shrinking changes how much room is available for the other controls. But they might shrink as well and in turn make more room for the first control again. We went for something simpler and faster that doesn't support these kinds of iterative adjustments.
     
    Ultroman likes this.
  23. Xorxor

    Xorxor

    Joined:
    Oct 15, 2014
    Posts:
    24
    Has anyone found a solution to this yet? Adding these elements to a vertical layout group forces their content size fitter's to fail and they get stuck at their min size
     
  24. Deni35

    Deni35

    Joined:
    Jul 10, 2012
    Posts:
    43
    Hi!
    https://monosnap.com/file/3bOQZ4ZGmXctUgPH8hTmwi44QYeq5B

    I use slider with Flexible Width. But this slider ignore Preferred With of parent.
    I think in this case would be great to have Max Width option.
    if I enable ContentSizeFitter, it will work as I want. But there is warning message on component.

    Update
    Wow! I can set Flexible Width on Slider to 0 and it will shrink.
     
    Last edited: Nov 20, 2016
    Ultroman likes this.
  25. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
    It still does't work for me when I set Flexible Width on Slider to 0. I had to attach a content size fitter component to the slider as you first did and got it to work. Am I doing something wrong? I would also like to see a maximum size option on the Layout Group component.
     
  26. i0plus_developer

    i0plus_developer

    Joined:
    Oct 20, 2018
    Posts:
    25