Search Unity

Displaying text elements vertically in an extendable layout

Discussion in 'UGUI & TextMesh Pro' started by mehalon, Feb 16, 2018.

  1. mehalon

    mehalon

    Joined:
    Jun 13, 2017
    Posts:
    9
    Hi all,

    I'm trying to create an interaction fiction game in which I want to display generated text elements below each other with some buttons for choices at the bottom and a menu bar at the top.
    I have been playing around with content size fitters (of the text and button elements), vertical layout groups (of the canvas in the background) and manual settings of pivot points, height, width etc., but I can't get to a satisfactory solution.
    Ideally the UI should work independent of the screen resolution, so I would like to stretch the text elements according to the available space horizontally and then vertically depending of the amount of text. Then, with some spacing, the next text element should be displayed.
    Similarly for the buttons. And the UI should be extendable, so that if there is too much text, the user should be able to scroll/swipe down and then select the choice. I guess that involves a ScrollView.
    Currently, the text elements still seem to be overlapping. Maybe I overdid it with trying everything at once and the different script lines and components are overwriting each other.

    How do you think a clean way to set up the UI as described above could look like?

    Thank you very much for your help :).

    screenshot.JPG
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I would say that sounds like a task for the scrollview, as you mentioned. You might want a panel as the parent, too, to setup the title/menu bar at the top and buttons at the bottom, if they are supposed to be part of the "window" or element..

    On the content portion of the scrollview, you'll probably use a vertical layout group and a content size fitter. For the content size fitter, horziontal unrestricted & vertical "preferred". The vertical layout you may have to try a few settings. I can usually get it to work with a little trial and error, but I don't want to say one thing here and then it doesn't work ;)

    As for scaling/resolutions, there is a guide here: https://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.html

    Hope that helps some. :)
     
    mehalon likes this.
  3. mehalon

    mehalon

    Joined:
    Jun 13, 2017
    Posts:
    9
    Thanks for your reply.
    Maybe I should explain how the UI currently works: I have a script constantly creating and destroying text fields and buttons. So during a scene some text fields and buttons are generated, then a choice is selected, all text and buttons are destroyed, new ones created and so on.

    Currently I instantiate text assets and buttons like this:

    UnityEngine.UI.Button buttonInstance = Instantiate(storyButton) as Button;
    buttonInstance.transform.SetParent(contentCanvas.transform, false);

    This works because I have "public Canvas contentCanvas;" during initialization. However that does not seem to work with panels or scrollviews (public Panel ... does not seem to exist).

    How would it work if I want to instantiate something and set a panel or a scrollview as the parent (and not a canvas)?
     
    Last edited: Feb 16, 2018
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    You don't really need to do public Panel or public ScrollView or even public Canvas honestly. Just do a public GameObject variable and drag whatever. Or you could even do public Transform if you're only going to use it for parenting. All the UI stuff in the scene is a GameObject and has a rectTransform(which inherits from Transform, so can go into a Transform variable)

    Also note you can declare a parent with the instantiate call, so you don't have to use setParent right after.

    I would also say you should look into object pooling if you are constantly destroying and instantiating buttons.
     
  5. mehalon

    mehalon

    Joined:
    Jun 13, 2017
    Posts:
    9
    Ok, it's already looking a bit better. I have attached a screenshot regarding my next questions:

    screenshot.JPG

    I would like to have the text areas stretched horizontally (filling the space available minus padding), however the "child force expand" of the vertical layout group of the parent canvas does not seem to change anything.

    Also, this would probably mean to stretch the buttons horizontally, which I do not want, I would rather like them to fill 50% of the screen and be centered horizontally.

    I tried to stretch the text fields in their rect transform, but it does not work. Currently, both buttons and text fields have a defined width (700), but this is probably not good given that it should adjust to different screen resolutions.

    Another problem is that neither buttons nor text fields adjust their size vertically depending on how much text is in there, although I have set the parent canvas content size fitter to vertical fit "preferred size".
    And when I added a content size fitter to the buttons and text fields, Unity complained that this is not advisable and should be handled by the layout group.

    Thanks again :)
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Your screenshot didn't work out ( I see that happen a lot here).
    For adding one ( when it doesn't work), provide a link that has the photo (dropbox or some other place you can share).

    I am too tired to even try to answer every part of your question, but one component that can be useful is "Layout element"; it would be used on child elements.

    For the buttons, perhaps don't put them in the layout group (guess that depends on your setup).
     
  7. mehalon

    mehalon

    Joined:
    Jun 13, 2017
    Posts:
    9
    That's ok, don't know in what time zone you live in. Sleep well. I'm sure somebody else will be able to help further.
     
  8. zjuwpn

    zjuwpn

    Joined:
    Sep 15, 2020
    Posts:
    1
    It took me several months to solve this, hope this can help others with the same issue.

    For the parent object (in other words, the Content object in the Scroll View), set the anchor preset to top-stretch (important) and set the left/right to 0 or other values. in the vertical layout group component, select Control Child Size-Width and Control Child Size-Height and leave others unchecked. Add a content size fitter component here with Horizontal Fit - Unconstrained and Vertical Fit - Preferred Size.

    For Text children objects, in the Text component, select Wrap and Truncate for Horizontal and Vertical Overflow. Here you don't need to add content size fitter for vertical size since the parent object has set Control Child Size-Height. You can also try adding a content size fitter in the child and disable Control Child Size-Height in the parent, the effects are the same, but with a warning in the child object.

    Same for other types of children objects like Image or Button.

    The key is that where there is a parent with a Layout Group component, we can not set anchor preset for its children. But we can still set the parent's anchor preset and then a top-stretch anchor preset ensure the width is stretched.

    pic1.png

    Furthermore, if you want every child in the parent's vertical size even if the text is short, add a Layout Element component in the child prefab and set Flexible Width to 1.

    pic2.png
     
    danialaddin66 and adityaspt like this.
  9. TrueBlue25

    TrueBlue25

    Joined:
    Aug 27, 2021
    Posts:
    7
    Dude you are literally a lifesaver! It still took some fiddling to get the buttons to expand how they should, but I got it working. Thank you so much for solving this terribly annoying issue!
     
  10. Koustav2010

    Koustav2010

    Joined:
    Nov 17, 2018
    Posts:
    2
    For me
    just put a content fitter->prefered size on the text and in your code put

    LayoutRebuilder.ForceRebuildLayoutImmediate(NPCQuestDetail.transform.Find("Body/ScrollArea/Content").GetComponent<RectTransform>());