unity GridLayoutGroup真正的居中

GridLayoutGroup默认的居中效果:

  

不是真正的居中 加上代码:
namespace UnityEngine.UI
{/// <summary>/// GridLayoutGroup拓展,使支持自定义内容/// </summary>internal class GridLayoutGroupEx : GridLayoutGroup{/// <summary>/// 启用居中/// </summary>bool m_enableMiddle = true;/// <summary>/// 超过行数采用默认的/// </summary>int m_surpassLine = 2;public bool EnableMiddle{set { m_enableMiddle = value; }get { return m_enableMiddle; }}public int SurpassLine{set { m_surpassLine = value; }get { return m_surpassLine; }}/// <summary>/// Called by the layout system/// Also see ILayoutElement/// </summary>public override void SetLayoutHorizontal(){SetCellsAlongAxis(0);}/// <summary>/// Called by the layout system/// Also see ILayoutElement/// </summary>public override void SetLayoutVertical(){SetCellsAlongAxis(1);}private void SetCellsAlongAxis(int axis){// Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis// and only vertical values when invoked for the vertical axis.// However, in this case we set both the horizontal and vertical position when invoked for the vertical axis.// Since we only set the horizontal position and not the size, it shouldn't affect children's layout,// and thus shouldn't break the rule that all horizontal layout must be calculated before all vertical layout.if (axis == 0){// Only set the sizes when invoked for horizontal axis, not the positions.for (int i = 0; i < rectChildren.Count; i++){RectTransform rect = rectChildren[i];m_Tracker.Add(this, rect,DrivenTransformProperties.Anchors |DrivenTransformProperties.AnchoredPosition |DrivenTransformProperties.SizeDelta);rect.anchorMin = Vector2.up;rect.anchorMax = Vector2.up;rect.sizeDelta = cellSize;}return;}float width = rectTransform.rect.size.x;float height = rectTransform.rect.size.y;int cellCountX = 1;int cellCountY = 1;if (m_Constraint == Constraint.FixedColumnCount){cellCountX = m_ConstraintCount;if (rectChildren.Count > cellCountX)cellCountY = rectChildren.Count / cellCountX + (rectChildren.Count % cellCountX > 0 ? 1 : 0);}else if (m_Constraint == Constraint.FixedRowCount){cellCountY = m_ConstraintCount;if (rectChildren.Count > cellCountY)cellCountX = rectChildren.Count / cellCountY + (rectChildren.Count % cellCountY > 0 ? 1 : 0);}else{if (cellSize.x + spacing.x <= 0)cellCountX = int.MaxValue;elsecellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));if (cellSize.y + spacing.y <= 0)cellCountY = int.MaxValue;elsecellCountY = Mathf.Max(1, Mathf.FloorToInt((height - padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y)));}int cornerX = (int)startCorner % 2;int cornerY = (int)startCorner / 2;int cellsPerMainAxis, actualCellCountX, actualCellCountY;if (startAxis == Axis.Horizontal){cellsPerMainAxis = cellCountX;actualCellCountX = Mathf.Clamp(cellCountX, 1, rectChildren.Count);actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}else{cellsPerMainAxis = cellCountY;actualCellCountY = Mathf.Clamp(cellCountY, 1, rectChildren.Count);actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}Vector2 requiredSpace = new Vector2(actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x,actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y);Vector2 startOffset = new Vector2(GetStartOffset(0, requiredSpace.x),GetStartOffset(1, requiredSpace.y));int customActualCellCountX, customActualCellCountY;if (startAxis == Axis.Horizontal){customActualCellCountX = rectChildren.Count % cellCountX;customActualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}else{customActualCellCountY = rectChildren.Count % cellCountY;customActualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));}Vector2 customRequiredSpace = new Vector2(customActualCellCountX * cellSize.x + (customActualCellCountX - 1) * spacing.x,customActualCellCountY * cellSize.y + (customActualCellCountY - 1) * spacing.y);Vector2 customStartOffset = new Vector2(GetStartOffset(0, customRequiredSpace.x),GetStartOffset(1, customRequiredSpace.y));//Debug.Log("actualCellCountX: " + actualCellCountX);//Debug.Log("actualCellCountY: " + actualCellCountY);//Debug.Log("requiredSpace.x: " + requiredSpace.x);//Debug.Log("requiredSpace.y: " + requiredSpace.y);//Debug.Log("startOffset.x: " + startOffset.x);//Debug.Log("startOffset.y: " + startOffset.y);//Debug.Log("-------------------------------");//Debug.Log("customActualCellCountX: " + customActualCellCountX);//Debug.Log("customActualCellCountY: " + customActualCellCountY);//Debug.Log("customRequiredSpace.x: " + customRequiredSpace.x);//Debug.Log("customRequiredSpace.y: " + customRequiredSpace.y);//Debug.Log("customStartOffset.x: " + customStartOffset.x);//Debug.Log("customStartOffset.y: " + customStartOffset.y);int startCount = rectChildren.Count % cellsPerMainAxis;int totalLine = startAxis == Axis.Horizontal ? customActualCellCountY : customActualCellCountX;for (int i = 0; i < rectChildren.Count; i++){int positionX;int positionY;if (m_enableMiddle && startCount > 0 && totalLine <= m_surpassLine){if (i < startCount){if (startAxis == Axis.Horizontal){positionX = i;positionY = 0;if (cornerX == 1)positionX = startCount - 1 - positionX;if (cornerY == 1)positionY = actualCellCountY - 1 - positionY;}else{positionX = 0;positionY = i;if (cornerX == 1)positionX = actualCellCountX - 1 - positionX;if (cornerY == 1)positionY = startCount - 1 - positionY;}SetChildAlongAxis(rectChildren[i], 0, customStartOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, customStartOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);}else{int index = i - startCount;if (startAxis == Axis.Horizontal){positionX = index % cellsPerMainAxis;positionY = index / cellsPerMainAxis + 1;}else{positionX = index / cellsPerMainAxis + 1;positionY = index % cellsPerMainAxis;}if (cornerX == 1)positionX = actualCellCountX - 1 - positionX;if (cornerY == 1)positionY = actualCellCountY - 1 - positionY;SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);}}else{if (startAxis == Axis.Horizontal){positionX = i % cellsPerMainAxis;positionY = i / cellsPerMainAxis;}else{positionX = i / cellsPerMainAxis;positionY = i % cellsPerMainAxis;}if (cornerX == 1)positionX = actualCellCountX - 1 - positionX;if (cornerY == 1)positionY = actualCellCountY - 1 - positionY;SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);}//Debuger.Log("positionX: " + positionX + "positionY: " + positionY + ",cellsPerMainAxis: " + cellsPerMainAxis);}}}
}

效果:

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/53564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人生苦短我用Python pandas文件格式转换

人生苦短我用Python pandas文件格式转换 前言示例1 excel与csv互转常用格式的方法Flat fileExcelJSONXML 示例2 常用格式转换简要需求依赖export方法main方法 附其它格式的方法HTMLPicklingClipboardLatexHDFStore: PyTables (HDF5)FeatherParquetORCSASSPSSSQLGoogle BigQuery…

香橙派转换模型以及在开发板上部署

新手小白记录一下自己使用香橙派模型转换以及在开发板上运行的过程&#xff0c;防止后面忘记。 使用的开发板&#xff1a;Orange Pi 5 Plus&#xff08;rk3588&#xff09; 官方的一些资料在&#xff08;主要参考用户手册&#xff09;&#xff1a;Orange Pi - Orangepihttp:/…

Pytest夹具autouse参数使用。True表示会自动在测试中使用,而无需显式指定

1. 全局conftest文件日志记录功能 # 当前路径(使用 abspath 方法可通过dos窗口执行) current_path os.path.dirname(os.path.abspath(__file__)) # 上上级目录 ffather_path os.path.abspath(os.path.join(current_path,"../"))LOG_FILE_PATH f{ffather_path}/lo…

【视频讲解】Python贝叶斯卷积神经网络分类胸部X光图像数据集实例

全文链接&#xff1a;https://tecdat.cn/?p37604 分析师&#xff1a;Yuanchun Niu 在人工智能的诸多领域中&#xff0c;分类技术扮演着核心角色&#xff0c;其应用广泛而深远。无论是在金融风险评估、医疗诊断、安全监控还是日常的交互式服务中&#xff0c;有效的分类算法都是…

科研绘图系列:R语言富集散点图(enrichment scatter plot)

介绍 富集通路散点图(Enrichment Pathway Scatter Plot)是一种数据可视化工具,用于展示基因集富集分析(Gene Set Enrichment Analysis, GSEA)的结果。 横坐标是对应基因名称,纵坐标是通路名称,图中的点表示该基因在某个通路下的qvalue,可以简单理解为不同环境下的贡献…

【全网最全】2024年数学建模国赛A题30页完整建模文档+17页成品论文+保奖matla代码+可视化图表等(后续会更新)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片那是获取资料的入口&#xff01; 【全网最全】2024年数学建模国赛A题30页完整建模文档17页成品论文保奖matla代码可视化图表等&#xff08;后续会更新&#xff09;「首先来看看目前已有的资料&#xff0…

【ACM独立出版|EI快检索-高录用|IEEE Fellow支持】2024年数字经济与计算机科学国际学术会议(DECS2024)

【ACM独立出版&#xff5c;EI快检索-高录用&#xff5c;IEEE Fellow支持】 2024年数字经济与计算机科学国际学术会议&#xff08;DECS2024&#xff09; *ACM独立出版&#xff0c;快检索&#xff0c;高录用 *见刊后1个月左右完成EI&Scopus检索 *国内211大学、世界QS名校…

系统架构师-ERP+集成

ERP 集成平台end&#xff1a;就懒得画新的页

MyBatis-MappedStatement什么时候生成?QueryWrapper如何做到动态生成了SQL?

通过XML配置的MappedStatement 这部分MappedStatement主要是由MybatisXMLMapperBuilder进行解析&#xff0c;核心逻辑如下&#xff1a; 通过注解配置的MappedStatement 核心逻辑就在这个里面了&#xff1a; 继承BaseMapper的MappedStatement 我们看看这个类&#xff0c;里…

python strip()函数使用

默认情况下去除字符串首尾的空格和换行符号&#xff1b; 但是也可以去掉任意的字符串&#xff0c;可以把首尾的字符串去除到再也找不到为止&#xff0c;但是需要注意可能会由于空格和换行符的存在使得待去除的字符串没有被去除&#xff1a; a "[[1,2,3,4,5], [2,3,4,5]]…

Java项目——苍穹外卖(一)

Entity、DTO、VO Entity&#xff08;实体&#xff09; Entity 是表示数据库表的对象&#xff0c;通常对应数据库中的一行数据。它通常包含与数据库表对应的字段&#xff0c;并可能包含一些业务逻辑。 DTO&#xff08;数据传输对象&#xff09; 作用&#xff1a;DTO 是用于在…

【小沐学OpenGL】Ubuntu环境下glfw的安装和使用

文章目录 1、简介1.1 OpenGL简介1.2 glfw简介 2、安装glfw2.1 直接命令二进制安装2.2 源码安装 3、测试glfw3.1 测试1&#xff0c;glfwglew3.2 测试2&#xff0c;glfwglad3.3 测试3 结语 1、简介 1.1 OpenGL简介 OpenGL作为图形界的工业标准&#xff0c;其仅仅定义了一组2D和…

美团面试题:生成字符串的不同方式

美团面试题:生成字符串的不同方式 引言问题分析动态规划思路伪代码C代码实现代码解析复杂度分析优化建议结论引言 小红拿到了一个空字符串 s s s,她希望通过两种操作生成一个给定的字符串 t t t。我们需要计算生成字符串

python(进阶2)实现自动化注册和登录

1. 分析需求 后端完成接口以后&#xff0c;工作中可能会涉及到自测通断&#xff0c;a接口和b接口之间可能有关联关系&#xff0c;例如:a接口注册&#xff0c;b接口登录&#xff0c;就需要a接口返回的参数传递到b接口 2. 环境准备 需要这些类包 import requests import rand…

Vivado编译报错黑盒子问题

1 问题描述 “Black Box Instances: Cell **** of type ** has undefined contents and is considered a back box. The contents of this cell must be defined for opt_design to complete successfully.” 检查工程代码提示的模块&#xff0c;该模块为纯手写的Veril…

替代 Django 默认 User 模型并使用 `django-mysql` 添加数据库备注20240904

替代 Django 默认 User 模型并使用 django-mysql 添加数据库备注 前言 在 Django 项目开发中&#xff0c;默认的 User 模型虽然能够满足许多基础需求&#xff0c;但在实际项目中我们常常需要对用户模型进行定制化。通过覆盖默认的 User 模型&#xff0c;我们可以根据具体的业…

注册安全分析报告:熊猫频道

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【论文阅读】CiteTracker: Correlating Image and Text for Visual Tracking

paper&#xff1a;[2308.11322] CiteTracker: Correlating Image and Text for Visual Tracking (arxiv.org) code&#xff1a;NorahGreen/CiteTracker: [ICCV23] CiteTracker: Correlating Image and Text for Visual Tracking (github.com) 简介 现有的视觉跟踪方法通常以…

iOS——frame和bounds的区别

把frame理解为占用区域&#xff0c;把bounds理解为边界。View在旋转过程中&#xff0c;其实自己的坐标系统并没有发生改变&#xff0c;bounds中的origin只能通过setBounds方法修改。 frame 定义了视图在其父视图坐标系统中的位置和大小。其坐标系是相对于俯视图的坐标系。 bou…

如何保证 UDP 的可靠性传输?

一、TCP 和 UDP 的区别 1、TCP基于连接&#xff0c;UDP基于无连接。 2、对系统资源的要求&#xff1a;TCP 较多&#xff0c;UDP 少。 3、UDP 程序结构较简单。 4、TCP基于流模式&#xff0c;UDP基于数据报模式 。 5、TCP 保证数据正确性&#xff0c;UDP 不保证数据准确性&…