UGUI-ContentSizeFitter之最简单实现maxSize限制
步骤
方法思路如下:
- 复制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 &¤tValue.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
也会一直显示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();}}
}
最后效果如下:
UGUI-ContentSizeFitter之最简单实现maxSize限制相关推荐
- UGUI ContentSizeFitter 嵌套 适配
Unity不支持ContentSizeFitter 的嵌套,如果使用了嵌套则会出现警告,并且有些时候没有效果. 但是实际应用时候肯定会碰到嵌套的情况,这怎么办呢? 其实我们只需要在最外层加一个Cont ...
- 【Unity3D-UGUI应用篇】(三)使用UGUI实现层级菜单
推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...
- UGUI自定义组件之Image根据Text大小自动调整
文章目录[点击展开](?)[+] 需求分析 在之前的文章中,介绍到可以使用UGUI自带的ContentSizeFitter组件,进行Button根据Text的长度自适应, UGUI ContentSi ...
- 从CPU和GPU出发的UGUI优化
UGUI优化 就在前几天去B站面试实习岗位,发现学习的方向出现了一些小问题 对UGUI的优化理解出现了不小问题,面试之后,查询了不少的文章,并吸取他们的知识,对UGUI有了一定的理解,希望可以避免再出 ...
- 微观平台_不再受到微观管理
微观平台 Organisations spend vast amounts of time and resources on hiring smart, talented and self-motiv ...
- 面向对象设计原则_面向对象的设计原则
面向对象设计原则 Programming is fun until you have to incorporate a new requirement that changes the whole d ...
- Python_多线程编程
简介 线程是操作系统能搞够进行运算调度的最小单位.它把被包含在进程之中,所有的线程运行在同一个进程中,共享相同的运行环境,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可 ...
- 运行linux在de1soc,在DE1-SOC上运行Linux
1,设定串口终端 安装驱动 :使用mini-USB线将计算机与DE1-SoC的UART转USB接口.drivers\USB2UART_driver文件夹内放置有驱动程序 设定串口终端规格 : 设定串口 ...
- 深度学习去燥学习编码_您不应该学习编码的5个理由
深度学习去燥学习编码 It seems like more and more people are catching the learn to code bug these days. If YouT ...
最新文章
- numpy和scipy安装
- 【网络协议】专题总结以及网络协议高频面试题汇总(8篇)
- 作为一名产品经理,我是如何快速做项目计划的?
- 【SIGGRAPH 2015】【巫师3 狂猎 The Witcher 3: Wild Hunt 】顶级的开放世界游戏的实现技术。...
- C++中的位域(bit-filed):一种节省空间的成员
- 第28件事 挖掘用户真实需求的6大撒手锏
- 叮叮叮 重点之中的python必备英语单词(2)来啦!请记得查收
- mysql三高教程(二):2.7 如何约束数据
- 高级参数绑定(数组和List绑定)
- mysql in 有序_mysql中的in排序 mysql按in中顺序来排序
- 假如在1996年,微软、IBM、苹果你会投资谁?
- 软考网络工程师考试大纲(2018年最新版)
- 用两个栈实现队列(Java)
- 赛尔号服务器维护时间2月13,赛尔号2月13日更新福利活动汇总 重生之翼王者归来大暗黑天刻印放送...
- 给定平面上的n个点,求最多有多少个点共线
- JavaScript 实现网页截屏五种方法
- 【python爬虫】easyocr识别gif图片文字
- uniapp原生sdk插件极光短信·极光短信插件可快速对接收发短信·官方伙伴优雅草发布
- C语言常用的math函数
- 安卓新闻发布系统源码,后台java springboot框架
热门文章
- thinkpad e450 win7黑苹果macos 10.10.5(网/显/声卡驱动)安装成功
- micropython 常量_MicroPython添加Module(二)
- WIFI设备接入阿里云物联网平台
- 重装fedora17之后的一些配置
- UOJ#311. 【UNR #2】积劳成疾
- Windows 下解决 VsCode 使用 SSH 连接报 Bad owner or permissions on C:\\Users\\Administrator/.ssh/config 错误
- 计组 | 寻址范围的概念与数据寄存器的位数
- PLC数据采集有何难点?有什么解决方法?
- dhcp应该开启还是关闭(dhcp应该开启还是关闭)
- 通过 I2C 驱动 LCD1602 液晶屏(51单片机)