Search code examples
unity-game-enginegameobject

2D Unity: expand UI element based on text to the bottom


I've got a game object (InfoBox) with a..

  • Vertical Layout Group (Padding 20 on all sides, Control Child Size Height active)
  • an image
  • a Content Size Fitter (Vertical Fit set to Preferred Size, Horizontal Unconstrained)

Inside this InfoBox is a Text-Element and every time I update the text, I want the InfoBox to expand or collapse, but to the bottom only. Right now my InfoBox always expands or collapses to both top and bottom, but I don't want that to happen. How can I achieve that? I added some screenshots to better visualise this.

These are my settings for the InfoBox:

InfoBox Settings

And these are my settings for the text:

Text Settings

And this is what happens when I use for example less text, the box collapses from bottom and top, but I want it to stay fixed at the top (on the same line as the green box next to it) and only collapse on the bottom:

How it should not be

Any help is really appreciate!


Solution

  • You main issues looks like you are using a ContentSizeFitter also on the parent object. So it depends how this parent object is aligned with its according parent.

    This sentence sounds strange I know but what you did is basically shifting up the alignment responsibility to the parent.

    => Make your UI element aligned to the top and grow downwards.

    All you need to do for this is either set

    • Anchors Min y -> 1
    • Anchors Max y -> 1
    • Pivot y -> 1

    or simply go to the RectTransform Inspector, open the alignment tool and hold Shift + Alt and click on the top alignment:

    enter image description here


    For the second instead of using the ContentSizeFitter I prefer to have my own script that only does what it should and nothing more.

    You can get the preferredHeight which is exactly the value you are looking for.

    The following script simply always applies the preferred height to the text rect. Using [ExecuteAlways] this also works in edit mode. Simply attach it on the same GameObject as the UI.Text component

    [ExecuteAlways]
    [RequireComponent(typeof(Text))]
    [RequireComponent(typeof(RectTransform))]
    public class TextHeightFitter : MonoBehaviour
    {
        [SerializeField] private RectTransform _rectTransform;
        [SerializeField] private Text _text;
    
        private void Update()
        {
            if (!_text) _text = GetComponent<Text>();
            if (!_rectTransform) _rectTransform = GetComponent<RectTransform>();
    
            var desiredHeight = _text.preferredHeight;
            var size = _rectTransform.sizeDelta;
            size.y = desiredHeight;
            _rectTransform.sizeDelta = size;
        }
    }
    

    enter image description here