I have a panel, and I want its preferred width to match the size of its child objects, which are Text components, but the background Image is overriding the preferred width with a large value (1000x1000). How is the Image preferred size determined? Is there a way I can override it or give preference to the Vertical Layout Group?
I spent hours trying to make this work in a project recently… no idea why this is so insanely intuitive and weird to get something so simple working. But anyway I eventually ended up with this:
To start with I have a Canvas which has a Vertical Layout Group component added to it with the options “Control child size (both Width and Height)” enabled, and everything else disabled.
Within that Canvas there is a Panel with an Image component added to it set to whatever image you want, but also a Vertical Layout Group component with all options disabled.
Then within the Panel there is my text object (which is TextMeshPro but presumably this works the same with default UI text) and on that I have a Content Size Fitter component with both options set to Preferred Size.
If you only want it to resize to width rather than height, you’ll have to mess about with things and none of it will behave how you think it will -_-
EDIT: Actually ignore that. Just to add to the ongoing ridiculousness, it turns out that only works fine in the scene view and game view, but not when I actually run the time. Amazing.
OK this is by far the most confusing and frustrating part of Unity I’ve come across. The fact that the resizing and position behaviour in scene view and game view frequently does not match what happens when you run the game is very annoying. Also at one point the behaviour changed when I disabled one of the vertical layout group options so I enabled the option straight away again and the behaviour would not go back to how it was!
ANYWAY… this is what I’ve got that works now. Who knows when it might decide to just behave differently for no reason though.
- Canvas (root object) has Vertical Layout Group component on it with every option disabled
- Panel (child of Canvas) has the Image component on it and also a Vertical Layout Group with all options disabled, as well as a Content Size Fitter with both options set to Min Size
- Text (child of Panel) has a Content Size Fitter on it with both options set to Preferred Size.
So yeah that results in my image resizing to both the width and height of the text.
Created the following script to prefer layout groups over image dimensions. Maybe this can help you.
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(HorizontalOrVerticalLayoutGroup))]
[RequireComponent(typeof(RectTransform))]
public class PreferLayoutGroup : UIBehaviour, ILayoutElement
{
public float minWidth
{
get
{
return GetLayoutGroup().minWidth;
}
}
public float preferredWidth
{
get
{
return GetLayoutGroup().preferredWidth;
}
}
public float flexibleWidth
{
get
{
return GetLayoutGroup().flexibleWidth;
}
}
public float minHeight
{
get
{
return GetLayoutGroup().minHeight;
}
}
public float preferredHeight
{
get
{
return GetLayoutGroup().preferredHeight;
}
}
public float flexibleHeight
{
get
{
return GetLayoutGroup().preferredHeight;
}
}
public int layoutPriority
{
get
{
return 100;
}
}
ILayoutElement layoutGroup;
public void CalculateLayoutInputHorizontal()
{
}
public void CalculateLayoutInputVertical()
{
}
protected override void OnEnable()
{
base.OnEnable();
LayoutRebuilder.MarkLayoutForRebuild(GetComponent<RectTransform>());
}
protected override void OnDisable()
{
LayoutRebuilder.MarkLayoutForRebuild(GetComponent<RectTransform>());
base.OnDisable();
}
ILayoutElement GetLayoutGroup()
{
if (layoutGroup == null)
{
layoutGroup = GetComponent<HorizontalOrVerticalLayoutGroup>();
}
return layoutGroup;
}
}
Hey man, thanks for the answer, and the script… can’t believe that this is the only post I found regarding this problem :S
thank u very much !!! you saved me
It’s funny finding this two years after the fact, really needed this info, thanks!
Your Script solved all my issues. Thanks!!!
First I want to thank you for the code, it helped me!
Second, I want to inform a bug in it. The function flexibleHeight should return GetLayoutGroup().flexibleHeight and not GetLayoutGroup().preferredHeight.
I ran into this too and I believe this has to do with the borders on the sprite metadata. in the screenshots I posted, my sprite’s top/bottom borders are each 26, and the preferred height is 52. I suppose this is optimized for nine boxed sprites.
This worked excellently! Great work and thank you.
Came here with the same problem, stuck for over an hour and pulling my hair out why the Preferred Size on the Content Size Fitter was forcing a size larger than the child text elements. Using your script immediately fixed it. You’re a gem, sir. Thank you.
Why Unity behaves the way it does in many UI cases… I am just baffled. It needs to be fixed badly.
Ran into the exact same thing. Sliced are also problematic in how they compete for preferred width/height.
Ran into the same problem in Unity 6000.2, the workaround works really well, thank you. However, I had to correct the script as there was a small issue on my side:
public float flexibleHeight
{
get
{
return GetLayoutGroup().preferredHeight;
}
}
I changed the returned value to the flexibleHeight like so:
public float flexibleHeight
{
get
{
return GetLayoutGroup().flexibleHeight;
}
}

