步骤

方法思路如下:

  1. 复制ContentSizeFitter源码出来,改名为ContentSizeFitterEx (AddComponentMenu里面的名字也需要改。)
  2. FitMode增加枚举MaxSize
  3. 增加序列化属性m_MaxHorizontalm_MaxVertical
  4. 修改HandleSelfFittingAlongAxis增加maxSize判断
  5. 编写GetMaxSize方法
  6. 修改完毕替换场景里面的ContentSizeFitterContentSizeFitterEx

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 649private DrivenRectTransformTracker m_Tracker;
#pragma warning restore 649protected 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 sizeif (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_EDITORprotected override void OnValidate(){SetDirty();}#endif}
}

效果

优化Editor使用

当上面的操作改完之后发现我不选MaxSize也会一直显示MaxHroizontalMaxVertical属性的设置,假如我想选择了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();}}
}

最后效果如下:

UGUI-ContentSizeFitter之最简单实现maxSize限制相关推荐

  1. UGUI ContentSizeFitter 嵌套 适配

    Unity不支持ContentSizeFitter 的嵌套,如果使用了嵌套则会出现警告,并且有些时候没有效果. 但是实际应用时候肯定会碰到嵌套的情况,这怎么办呢? 其实我们只需要在最外层加一个Cont ...

  2. 【Unity3D-UGUI应用篇】(三)使用UGUI实现层级菜单

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  3. UGUI自定义组件之Image根据Text大小自动调整

    文章目录[点击展开](?)[+] 需求分析 在之前的文章中,介绍到可以使用UGUI自带的ContentSizeFitter组件,进行Button根据Text的长度自适应, UGUI ContentSi ...

  4. 从CPU和GPU出发的UGUI优化

    UGUI优化 就在前几天去B站面试实习岗位,发现学习的方向出现了一些小问题 对UGUI的优化理解出现了不小问题,面试之后,查询了不少的文章,并吸取他们的知识,对UGUI有了一定的理解,希望可以避免再出 ...

  5. 微观平台_不再受到微观管理

    微观平台 Organisations spend vast amounts of time and resources on hiring smart, talented and self-motiv ...

  6. 面向对象设计原则_面向对象的设计原则

    面向对象设计原则 Programming is fun until you have to incorporate a new requirement that changes the whole d ...

  7. Python_多线程编程

    简介 线程是操作系统能搞够进行运算调度的最小单位.它把被包含在进程之中,所有的线程运行在同一个进程中,共享相同的运行环境,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可 ...

  8. 运行linux在de1soc,在DE1-SOC上运行Linux

    1,设定串口终端 安装驱动 :使用mini-USB线将计算机与DE1-SoC的UART转USB接口.drivers\USB2UART_driver文件夹内放置有驱动程序 设定串口终端规格 : 设定串口 ...

  9. 深度学习去燥学习编码_您不应该学习编码的5个理由

    深度学习去燥学习编码 It seems like more and more people are catching the learn to code bug these days. If YouT ...

最新文章

  1. numpy和scipy安装
  2. 【网络协议】专题总结以及网络协议高频面试题汇总(8篇)
  3. 作为一名产品经理,我是如何快速做项目计划的?
  4. 【SIGGRAPH 2015】【巫师3 狂猎 The Witcher 3: Wild Hunt 】顶级的开放世界游戏的实现技术。...
  5. C++中的位域(bit-filed):一种节省空间的成员
  6. 第28件事 挖掘用户真实需求的6大撒手锏
  7. 叮叮叮 重点之中的python必备英语单词(2)来啦!请记得查收
  8. mysql三高教程(二):2.7 如何约束数据
  9. 高级参数绑定(数组和List绑定)
  10. mysql in 有序_mysql中的in排序 mysql按in中顺序来排序
  11. 假如在1996年,微软、IBM、苹果你会投资谁?
  12. 软考网络工程师考试大纲(2018年最新版)
  13. 用两个栈实现队列(Java)
  14. 赛尔号服务器维护时间2月13,赛尔号2月13日更新福利活动汇总 重生之翼王者归来大暗黑天刻印放送...
  15. 给定平面上的n个点,求最多有多少个点共线
  16. JavaScript 实现网页截屏五种方法
  17. 【python爬虫】easyocr识别gif图片文字
  18. uniapp原生sdk插件极光短信·极光短信插件可快速对接收发短信·官方伙伴优雅草发布
  19. C语言常用的math函数
  20. 安卓新闻发布系统源码,后台java springboot框架

热门文章

  1. thinkpad e450 win7黑苹果macos 10.10.5(网/显/声卡驱动)安装成功
  2. micropython 常量_MicroPython添加Module(二)
  3. WIFI设备接入阿里云物联网平台
  4. 重装fedora17之后的一些配置
  5. UOJ#311. 【UNR #2】积劳成疾
  6. Windows 下解决 VsCode 使用 SSH 连接报 Bad owner or permissions on C:\\Users\\Administrator/.ssh/config 错误
  7. 计组 | 寻址范围的概念与数据寄存器的位数
  8. PLC数据采集有何难点?有什么解决方法?
  9. dhcp应该开启还是关闭(dhcp应该开启还是关闭)
  10. 通过 I2C 驱动 LCD1602 液晶屏(51单片机)