Search Unity

Padding by ratio/anchor instead of fixed units in nested Horiz/Vert Layouts

Discussion in 'UGUI & TextMesh Pro' started by montag64, Sep 2, 2016.

  1. montag64

    montag64

    Joined:
    Mar 15, 2014
    Posts:
    23
    I just started using anchors and stretching elements to scale my UI dynamically so that width and height of the device can vary and its working very well so far. I'm trying to build a messaging view; typically what you would see on an iPhone, Android, etc, but I'm trying to make the padding dynamic so that when stretched there is always a maximum ratio at which the message can expand (let's say, always 80% of the screen) regardless of how wide the canvas is. In the layouts I can set my Right or Left padding statically in units but that doesn't stretch when the canvas width changes. I'm using nested layouts to get the effect that I need, to adapt the bubble to the text width, and that works. This is all taking place inside a ScrollView. The opponent in the conversation should be left justified, and the player should be right justified, which is where the problem is created, otherwise I would just be able to change the anchors.

    In the picture I've attached, the red area should always scale accordingly as the canvas stretches, as should the max width of the message. Some messages should not stretch to the full maximum based on text length (like 'yes', or 'OK that's great').

    Here's my hierarchy. I'm using abbreviations (VLG = vert layout group, h = horiz)

    Code (Hierarchy):
    1.  
    2. Canvas - Canvas Scaler (Scale with Screen Size)
    3.     Scroll View - Scroll Rect
    4.         Viewport - Mask
    5.             Content - VLG, Content Size Fitter (Vert set to preferred, Horiz unconstrained)
    6.                 Player1Message - VLG (Child Width Force Expand, upper left aligned)
    7.                     BubbleBackground - HLG (Child Width Force Expand, middle center aligned, some padding), Image
    8.                     Arrow - Image
    9.                         Text
    10.                 Player2Message - VLG (Child Width Force Expand, upper right aligned)
    11.                 ...
    12.                 Message(n)
    13.             ScrollBar
    14.  
    I assume I need to do something with FlexibleWidth set to .8 on the message and .2 on the spacing, but it gets ignored it seems. I tried putting a parent above Message with a horizontal layout group and an empty child object with a layout and a placeholder image but it just gets squeezed down. If I duplicate messages and put them on the same parent and apply flexible widths of .8 and .2, they both take up 50% of the space. I think the text is driving the max message width when I need it to drive only the height and width up until the ratio limit I've defined.

    I also thought about copying the UI Layout Group script and extending it to replace padding units with a ratio based on the canvas width, but that seems kind of tacky. Is there a way to do this with just the UI elements? How do you guys recommend I structure this?
     

    Attached Files:

  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    I tried lots of various ways to do this. I find the Layout of the new UI is fairly limitied, especially if your coming from something like Android Studio. Those Layout controls were very nice. I think your going to have to do it in one of the two ways:
    Write a Custom Layout Fitter, that can handle a min forced width based on a percentage like flexible width

    or..

    I was able to achieve this affect by this:
    Main Panel (HLG - Forced width and Height checked) Its dimensions were 200x200
    -- Panel (Layout Element. Min Width Set to 40
    --- Text Element

    With no texts the panel would expand across most of the 200 units, then as I typed text it shrunk till it hit the min width of 40 units. You programmatically set these min Widths as you created your ChatBox. At that point you'd know your scren height/width and get the dimensions of the total Chat box, to set a Min Width of 20% of that.

    Sadly there is no forced min width based on percentage. Which is annoying.
     
  3. montag64

    montag64

    Joined:
    Mar 15, 2014
    Posts:
    23
    On recommendation from a colleague and kind of along the lines with what you said, I ended up just coding a script that extends the UIBehaviour class. I'll post it once I clean it up. It works well; I'm not saying it's the best solution, but it works.
     
  4. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
    FORTUNATELY IT IS VERY SIMPLE:

    make a panel with a horiz layout group.

    put two panels in it.

    on each panel put a layout element (named left/right in the image below)

    simply set flexible width as desired.

    for example 45 and 55 for a 45/55 split

    Screen Shot 2020-06-25 at 3.49.07 PM.png

    that's all there is to it. put anything you want inside the two left/right panels.

    cheers
     
    MilenaRocha likes this.
  5. FrankBuss

    FrankBuss

    Joined:
    Dec 22, 2014
    Posts:
    55
    I wouldn't call this simple.
     
    HazyPaw and Cbunz like this.