I want the minimum width of my layout element to automatically be the same as the preferred width:

I don’t want to have to manually specify the preferred width with a LayoutElement.
Is there a component that already has this functionality? Can I extend LayoutElement somehow without requiring me to manually specify a preferred width?
Turns out, it’s quite easy. You just need to figure out where you want to get your preferred width from (which you can do by just looping through all components inheriting ILayoutGroup or LayoutGroup and then checking which is the last one in the list with the highest priority, or you can do what I did and just store a reference) and then return that as the min width. Then for the remaining values just return -1 to allow other layout elements to fill in the gaps.
Following is the code I used. Technically I believe it should do LayoutRebuilder.MarkLayoutForRebuild(rectTransform) whenever the setMinimumWidthToPreferredWidth, setMinimumHeightToPreferredHeight or priority is changed, but I couldn’t be bothered with the customer inspector stuff you’d need to have things work with properties.
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(RectTransform))]
public class PreferredSizeToMinSize : MonoBehaviour, ILayoutElement
{
[SerializeField]
private LayoutGroup referenceLayoutGroup;
[SerializeField]
private bool setMinimumWidthToPreferredWidth = false;
[SerializeField]
private bool setMinimumHeightToPreferredHeight = false;
[SerializeField]
private int priority = 3;
//private RectTransform _rectTransform;
//private RectTransform rectTransform
//{
// get
// {
// if(_rectTransform == null)
// {
// _rectTransform = GetComponent<RectTransform>();
// }
// return _rectTransform;
// }
//}
public float minWidth
{
get
{
if(setMinimumWidthToPreferredWidth)
{
return referenceLayoutGroup.preferredWidth;
} else {
return -1;
}
}
}
public float preferredWidth { get { return -1; } } // -1 allows other layout elements with lower priority to specify this value
public float flexibleWidth { get { return -1; } }
public float minHeight
{
get
{
if(setMinimumHeightToPreferredHeight)
{
return referenceLayoutGroup.preferredHeight;
} else {
return -1;
}
}
}
public float preferredHeight { get { return -1; } }
public float flexibleHeight { get { return -1; } }
public int layoutPriority { get { return priority; } }
public void CalculateLayoutInputHorizontal() { }
public void CalculateLayoutInputVertical() { }
}