步骤
方法思路如下:
- 复制ContentSizeFitter源码出来,改名为ContentSizeFitterEx(AddComponentMenu里面的名字也需要改。)
- FitMode增加枚举MaxSize
- 增加序列化属性m_MaxHorizontal和m_MaxVertical
- 修改HandleSelfFittingAlongAxis增加maxSize判断
- 编写GetMaxSize方法
- 修改完毕替换场景里面的ContentSizeFitter为ContentSizeFitterEx
ContentSizeFitterEx完整源码
复制到项目里面任意位置即可
using System.Collections.Generic;
using UnityEngine.EventSystems;
namespace UnityEngine.UI
{
    internal static class SetPropertyUtility
    {
        public static bool SetColor(ref Color currentValue, Color newValue)
        {
            if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b &&
                currentValue.a == newValue.a)
                return false;
            currentValue = newValue;
            return true;
        }
        public static bool SetStruct<T>(ref T currentValue, T newValue) where T : struct
        {
            if (EqualityComparer<T>.Default.Equals(currentValue, newValue))
                return false;
            currentValue = newValue;
            return true;
        }
        public static bool SetClass<T>(ref T currentValue, T newValue) where T : class
        {
            if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
                return false;
            currentValue = newValue;
            return true;
        }
    }
    [AddComponentMenu("Layout/Content Size Fitter Ex", 141)]
    [ExecuteAlways]
    [RequireComponent(typeof(RectTransform))]
    /// <summary>
    /// Resizes a RectTransform to fit the size of its content.
    /// </summary>
    /// <remarks>
    /// The ContentSizeFitter can be used on GameObjects that have one or more ILayoutElement components, such as Text, Image, HorizontalLayoutGroup, VerticalLayoutGroup, and GridLayoutGroup.
    /// </remarks>
    public class ContentSizeFitterEx : UIBehaviour, ILayoutSelfController
    {
        /// <summary>
        /// The size fit modes avaliable to use.
        /// </summary>
        public enum FitMode
        {
            /// <summary>
            /// Don't perform any resizing.
            /// </summary>
            Unconstrained,
            /// <summary>
            /// Resize to the minimum size of the content.
            /// </summary>
            MinSize,
            MaxSize,
            /// <summary>
            /// Resize to the preferred size of the content.
            /// </summary>
            PreferredSize
        }
        [SerializeField] protected FitMode m_HorizontalFit = FitMode.Unconstrained;
        [SerializeField] protected int m_MaxHorizontal = 900;
        [SerializeField] protected int m_MaxVertical = 100;
        /// <summary>
        /// The fit mode to use to determine the width.
        /// </summary>
        public FitMode horizontalFit
        {
            get { return m_HorizontalFit; }
            set
            {
                if (SetPropertyUtility.SetStruct(ref m_HorizontalFit, value)) SetDirty();
            }
        }
        [SerializeField] protected FitMode m_VerticalFit = FitMode.Unconstrained;
        /// <summary>
        /// The fit mode to use to determine the height.
        /// </summary>
        public FitMode verticalFit
        {
            get { return m_VerticalFit; }
            set
            {
                if (SetPropertyUtility.SetStruct(ref m_VerticalFit, value)) SetDirty();
            }
        }
        [System.NonSerialized] private RectTransform m_Rect;
        private RectTransform rectTransform
        {
            get
            {
                if (m_Rect == null)
                    m_Rect = GetComponent<RectTransform>();
                return m_Rect;
            }
        }
        // field is never assigned warning
#pragma warning disable 649
        private DrivenRectTransformTracker m_Tracker;
#pragma warning restore 649
        protected ContentSizeFitterEx()
        {
        }
        protected override void OnEnable()
        {
            base.OnEnable();
            SetDirty();
        }
        protected override void OnDisable()
        {
            m_Tracker.Clear();
            LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
            base.OnDisable();
        }
        protected override void OnRectTransformDimensionsChange()
        {
            SetDirty();
        }
        private void HandleSelfFittingAlongAxis(int axis)
        {
            FitMode fitting = (axis == 0 ? horizontalFit : verticalFit);
            if (fitting == FitMode.Unconstrained)
            {
                // Keep a reference to the tracked transform, but don't control its properties:
                m_Tracker.Add(this, rectTransform, DrivenTransformProperties.None);
                return;
            }
            m_Tracker.Add(this, rectTransform,
                (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY));
            // Set size to min or preferred size
            if (fitting == FitMode.MinSize)
            {
                rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis,
                    LayoutUtility.GetMinSize(m_Rect, axis));
            }
            else if (fitting == FitMode.MaxSize)
            {
            	//增加maxSize判断返回
                rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, GetMaxSize(m_Rect, axis));
            }
            else
            {
                rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis,
                    LayoutUtility.GetPreferredSize(m_Rect, axis));
            }
        }
		
		/// <summary>
        /// 增加maxSize获取
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        private float GetMaxSize(RectTransform rect, int axis)
        {
            var size = axis == 0 ? LayoutUtility.GetPreferredWidth(rect) : LayoutUtility.GetPreferredHeight(rect);
            if (axis == 0)
            {
                if (size > m_MaxHorizontal)
                {
                    return m_MaxHorizontal;
                }
            }
            else
            {
                if (size > m_MaxVertical)
                {
                    return m_MaxVertical;
                }
            }
            return size;
        }
        /// <summary>
        /// Calculate and apply the horizontal component of the size to the RectTransform
        /// </summary>
        public virtual void SetLayoutHorizontal()
        {
            m_Tracker.Clear();
            HandleSelfFittingAlongAxis(0);
        }
        /// <summary>
        /// Calculate and apply the vertical component of the size to the RectTransform
        /// </summary>
        public virtual void SetLayoutVertical()
        {
            HandleSelfFittingAlongAxis(1);
        }
        protected void SetDirty()
        {
            if (!IsActive())
                return;
            LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
        }
#if UNITY_EDITOR
        protected override void OnValidate()
        {
            SetDirty();
        }
#endif
    }
}
效果

优化Editor使用
当上面的操作改完之后发现我不选MaxSize也会一直显示MaxHroizontal和MaxVertical属性的设置,假如我想选择了MaxSize的时候才显示配置呢? 增加ContentSizeFitterExEditor类即可,注意该类需要放到Editor目录下,例如我是这样子放的:
 
using UnityEngine;
using UnityEngine.UI;
namespace UnityEditor.UI
{
    [CustomEditor(typeof(ContentSizeFitterEx), true)]
    [CanEditMultipleObjects]
    /// <summary>
    /// Custom Editor for the ContentSizeFitter Component.
    /// Extend this class to write a custom editor for a component derived from ContentSizeFitter.
    /// </summary>
    public class ContentSizeFitterExEditor : SelfControllerEditor
    {
        SerializedProperty m_HorizontalFit;
        SerializedProperty m_VerticalFit;
		//增加Max配置
        SerializedProperty m_MaxHorizontal;
        SerializedProperty m_MaxVertical;
        protected virtual void OnEnable()
        {
            m_HorizontalFit = serializedObject.FindProperty("m_HorizontalFit");
            m_VerticalFit = serializedObject.FindProperty("m_VerticalFit");
			//增加属性获取
            m_MaxHorizontal = serializedObject.FindProperty("m_MaxHorizontal");
            m_MaxVertical = serializedObject.FindProperty("m_MaxVertical");
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            EditorGUILayout.PropertyField(m_HorizontalFit, true);
            EditorGUILayout.PropertyField(m_VerticalFit, true);
			//判断选择了第二个MaxSize才显示max设置
            if (m_HorizontalFit.enumValueIndex == 2)
            {
                EditorGUILayout.PropertyField(m_MaxHorizontal);
            }
            //判断选择了第二个MaxSize才显示max设置
            if (m_VerticalFit.enumValueIndex == 2)
            {
                EditorGUILayout.PropertyField(m_MaxVertical);
            }
            serializedObject.ApplyModifiedProperties();
            base.OnInspectorGUI();
        }
    }
}
最后效果如下:
 



















