Search Unity

Horizontal Layout Groups and preserving aspect

Discussion in 'UGUI & TextMesh Pro' started by Melang, Aug 27, 2014.

  1. Melang

    Melang

    Joined:
    Mar 30, 2014
    Posts:
    166
    I want to put several rectangular shaped buttons in a Horizontal Layout group so they can be auto-resized when the group is resized, but I also want to preserve their aspect ratio. "Preserve Aspect" works alright for the images, but the clickable area's aspect is not preserved.

    Is there some way to do it aside from using a script that calculates the clickable area? Using such script wouldn't work for me, since I also have UI elements parented to the button that depend on its size.
     

    Attached Files:

    Last edited: Aug 27, 2014
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    I'm not sure what you mean by this? Filtering on that level should be the correct solution unless I really misunderstand your problem.
     
  3. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    Can't you just have a wrapper object that scales, then the image just scales vertically and positions centre inside? And call the click on the image, not the wrapper of course.
     
  4. Melang

    Melang

    Joined:
    Mar 30, 2014
    Posts:
    166
    I'll try to explain what I need better. I have a button and a child object parented to it. On the 1st attached screenshot is how my button (a card frame) should look at all times, it can scale but the aspect of the frame and its child object (the dagger icon) should be preserved.

    On the 2d screenshot is how a Horizontal Group with two cards looks currently. The clickable area is too large and the child image position is off. The clickable area can indeed be fixed by a script by senritsu, but what about the child image position? For the icon I use the anchors that are at the icon's corners currently and it works perfectly when scaling the parent with Shift key held down.
     

    Attached Files:

  5. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    We don't have a good built-in solution for this.

    Making a script that implements ILayoutElement and return a minHeight / preferredHeight size dependent on the width would be quite simple. The other way around - width dependent on height - is more tricky, since widths cannot depend on heights in the layout system, since it will create a circular dependency.
     
  6. rain03

    rain03

    Joined:
    Apr 18, 2014
    Posts:
    5
    Any solution for this? I also ran into this issue...
     
  7. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
  8. rain03

    rain03

    Joined:
    Apr 18, 2014
    Posts:
    5
    The aspect ratio fitter component shows a warning if placed on an object which is inside a layout group.
     

    Attached Files:

  9. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Ah, might have read back in history of the thread too quickly.

    If it's inside a LayoutGroup, there's two options I can see:
    • Making a script that implements ILayoutElement and return a minHeight / preferredHeight size dependent on the width, and then putting that script on each element.
    • Putting the AspectRatioFitter on the layout group itself to control the aspect ratio of the group as a whole - this however assumes a number of element in the group that doesn't vary.
     
  10. initram

    initram

    Joined:
    Nov 17, 2013
    Posts:
    1
    I would like to create a hand of cards area, that span the with of the screen and scales with the height of the screen.
    In this area (panel) I would like to display my cards so that the height of the cards scale with the height of the hand area panel (while keeping their aspect ratio).
    The hand area would have a horizontal layout group to layout the cards, that only stretches the height.

    Is this not possible? or how would you go about doing that, since I am not allowed to change the width based on the height?

    Or would I need to write my own layout script instead of using horizontal layout group?
     
  11. Kastenfrosch2

    Kastenfrosch2

    Joined:
    Mar 19, 2017
    Posts:
    10
    Hey!
    I was trying to implement your method. (My goal is to have a HorizontalLayoutGroup with childs (count varies during runtime) of maximized height and width-determined-by-fix-aspect-ratio)
    I overwrote both minWidth and preferredWidth with

    Code (CSharp):
    1. public override float minWidth
    2. {
    3.     get
    4.     {
    5.         float height = ???;
    6.         return height*aspectRatio;
    7.     }
    8. }
    but I dont know what to use for "height".
    If i use (rectTransform.offsetMax.y - rectTransform.offsetMin.y), or preferredHeight, the value always seems to be "the height before the currently processed update".

    Can you help me with that?

    PS: Is there a way in this forum to format code within a sentence (e.g. variable names)
     
    Last edited: Apr 3, 2017
  12. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    The width can't depend on the height as the height is calculated after the width.

    More details on this page: https://docs.unity3d.com/Manual/UIAutoLayout.html
     
  13. Kastenfrosch2

    Kastenfrosch2

    Joined:
    Mar 19, 2017
    Posts:
    10
    Thanks for your answer.
    Too bad, that there isn't a proper solution :(.

    Can I anyhow work around it by letting the whole layout evaluate botoom-up without aspect ratio restrictions - then taking the resulting height for my width-constraints and re-evaluate it in the same update-tick?

    If not: I am currently using parentRectTransform.rect.height; and though it might be undefinied behaviour, it currently fits my needs :).
     
  14. mattyalan

    mattyalan

    Joined:
    Oct 16, 2017
    Posts:
    1
    Last edited: Oct 19, 2017
  15. Elvthe

    Elvthe

    Joined:
    Dec 23, 2017
    Posts:
    1
    I have a similar issue. I am trying to achieve scalable, scrollable horizontal group with square buttons that use full parent height. My current solution looks like this:
    • Canvas - Scale With Screen Size
    • Scrol Rect - Horizontal, Clamped, Viewport -> Mask
    • Mask - covers Scroll Rect
    • Horizontal Layout Group - Child Controls Size (Height), Child Force Expand (Height), Content Size Fitter (Horizontal: Min Size, Vertical Unconstrained)
    • Button - Layout Element (Flexible Height 1) and Aspect Ratio Fitter (Height Controls Width)
    This solution works as desired. It scales to different aspect ratios but Aspect Ratio Fitter shows error "A child of a layout group should not have an Aspect Ratio Fitter component". Should I be worried about this and find another solution (I would appreciate help) or leave it as be?

    Here is how it looks like:
    button.png
    And scaled to 4:3:
    scaled_to_4_3.png
     
    DJgray3D likes this.
  16. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    393
  17. DarkestDay

    DarkestDay

    Joined:
    Feb 2, 2014
    Posts:
    2
    I think having Aspect Ratio Fitter in a Layout group is a viable solution. The warning is there to make you aware of the fact that you could possibly make two components control same dimension, which will lead to unexpected behavior as the two of them will try to adjust the dimension concurrently. So you need to make sure you understand what you are doing to make it work.
    For example, if you need the horizontal layout group where the heights and alignment are controlled by the layout group, but the children of the layout group should keep the aspect ratio:
    1. On the parent object with horizontal layout group check height in Child Controls Size and Child Force Expand, but make sure to uncheck the width in both.
    2. On the child objects add aspect ratio fitter and set it to whatever ratio you like (it can be individual for each child) and set Aspect Ratio to 'Height Controls Width'
    You get a warning when you do this, but you have Horizontal Layout group controlling only height, and aspect ratio fitter controlling only width, so there's actually to conflict here.

    This works for me in 2018.2.2f1
     
  18. LocalsOnlyCoop

    LocalsOnlyCoop

    Joined:
    Mar 8, 2019
    Posts:
    9
    I like how this is still an issue five years later.

    I have a similar problem where I have a horizontal layout group. The first element in the group needs to maintain its aspect ratio and be square. The second element should take up the remaining space. Instead, the horizontal layout group splits the area in half, and the first element, while the correct size and aspect ratio, does not seem to supply its updated width to the HorizontalLayoutGroup and the area is still split in half instead of by size.
     
  19. grinmonk

    grinmonk

    Joined:
    Nov 7, 2019
    Posts:
    5
    Unfortunately Aspect Ratio Fitter doesn't work properly inside Layout Group. Maybe, it mustn't, but it would be great if it did. unity_screen.gif
     
  20. Redrag

    Redrag

    Joined:
    Apr 27, 2014
    Posts:
    181
    DarkestDay you have saved my day! It worked exactly as you said - I have spent half a day on this problem trying different combinations. Thank you. (I am using 2019.2.17f1)
     
    amgreen333 likes this.