Unity中的LayoutGroup与LayoutElement的实战应用

在开发中遇到过一个问题,首先我们是在4k分辨率下开发的,界面要求如下
在这里插入图片描述
我们以第二行为例子,第二行有3个界面,其中中间的界面是比较长的
面板中使用Vertical和Horizontal排列,并且勾选了ControlChildSize和ChildForceExpand,保证每个物体都对齐
[图1]
在这里插入图片描述
[图2]
在这里插入图片描述
[图3]

但是在界面的第二行(以下的操作是第二行的)父物体Row2勾选了ControlChildSize和ChildForceExpand后,出现一个下面的问题,如图4:
在这里插入图片描述
[图4]
中间的间隔,被移动了。其实是最中间的面板被缩小了,而两边的面板被拉长了。
原因:在父物体勾选了ControlChildSize和ChildForceExpand后,子物体会等宽平均分布
ControlChildSize:强制父物体完全控制子物体的宽度(以宽度为例子),不允许子物体自己修改
ChildForceExpand:使剩余空间均匀分配给子物体
那么怎么解决这种情况呢?我们想要的是图1中的效果,间隙是对齐的
解决办法:

1.给每个子物体都添加LayoutElement组件
2.确定Preferred Width

  我们以4k分辨率作为设计分辨率,此时先取消ControlChildSize和ChildForceExpand,将3个子物体手动调整到正确的宽度,调整后的子物体宽度:A=920,B=1900,C=920。
  3个宽度相加920+1900+920=3740;父物体的Spacing为50,但是有2条间隙,所以50*2=100,再100+3740=3840,保证占满整个屏幕的宽度,如图5
在这里插入图片描述
[图5]

此时3个子物体的宽度,就是他们的Preferred Width
在这里插入图片描述
[图6]
在这里插入图片描述[图7]

这个时候我们再设置父物体的ControlChildSize,ChildForceExpand,就可以正常缩放了,如图8
在这里插入图片描述
[图8]

此时我相信你们肯定有疑问:他是怎么做到按照比例缩放的呢?调了这个Preferred Width到底有什么作用?Preferred Width到底应该调多少合适?别急,下面我们来解释下原理
  LayoutElement的Preferred Width,是一个最佳的宽度值,父物体在有空闲空间时,会将子物体的宽度优先设置为这个值,空间不足这个值时,如果勾选了ControlChildSize和ChildForceExpand时,则会基于这个值进行缩放。下面展示3种情况:

情况1:父物体空位刚好被子物体全部填充

解释:
已知父物体Width=3840,Spacing=50,勾选了ControlChildSize和ChildForceExpand。子物体A Preferred Width=920,子物体B Preferred Width=1900, 子物体C Preferred Width=920
此时父物体的空闲空间有3840-50 * 2=3740,这个50是Spacing,* 2是因为有2个间隙。先尝试将3个子物体的Preferred 填充进去 920+1900+920=3740,此时所有子物体的Preferred Width刚好可以填充父物体的空闲空间,所以每个子物体都可以分配到全部的Width,也就是Width=Preferred。不会做任何缩放,这是我们要的最佳效果。
计算过程:
父空闲空间:3840-50 * 2=3740
子物体占用空间:920+1900+920=3740
父空闲空间=子物体占用空间,不需要缩放

情况2:父物体空位不足

不想看解释可以直接看下面的计算过程
解释:
当分辨率变小时,此时父物体Width=2880,父物体、子物体的 其他参数都不变
此时父物体的空闲空间有2880-50 * 2=2780,子物体3个Preferred尝试填充920+1900+920=3740。2780<3740,空闲空间不够!还差3740-2780=960,这个960的意思,就是我们每个子物体都需要缩放一定大小,3个子物体共缩放960,就可以填充满父物体了
因为我们设置了Preferred Width,所以缩放并不是ControlChildSize默认的等比缩放,而是根据三者的Preferred Width加权平均决定的
子物体A Preferred Width=920,A Preferred Width占比=920/3740=0.2459, 需要缩放 0.2459 * 960=236.064
子物体B Preferred Width=1900,B Preferred Width占比=1900/3740=0.508, 需要缩放 0.508 * 960=487.68
子物体C Preferred Width=920,C Preferred Width占比=920/3740=0.2459,需要缩放 0.2459 * 960=236.064
得出3个子物体需要缩放多少,那么再用Preferred Width-需要缩放的宽度,结果就是实际的宽度了
子物体A实际宽度:920-236.064=683.936
子物体B实际宽度:1900-487.68=1412.32
子物体C实际宽度:920-236.064=683.936
所以Preferred Width的作用,就是将子物体按照一定比例分配宽度,他的用法,就是先确定一个合适的分辨率,以这个分辨率为主,设定好实际宽度,然后将Preferred Width设置为这个宽度
计算过程:
父物体空闲空间:2880-50×2=2780
子物体Preferred:920+1900+920=3740
父物体空间2780<3740,进行缩放
子物体A 缩放=920/3740=0.2459×960=236.064 --> A Width=920-236.064=683.936
子物体B 缩放=1900/3740=0.508×960=487.68 --> B Width=1900-487.68=1412.32
子物体C 缩放=920/3740=0.2459×960=236.064 --> C Width=920-236.064=683.936

情况3:父物体空间有剩余

解释:

缩小分辨率没有问题了,我们再试试放大:一个极端的例子,比如带鱼屏,如图9
在这里插入图片描述
[图9]
此时发现,间隙又对不齐了,这是因为我们只设置了Preferred Width,这个表示的是最佳宽度,如果父物体有空闲空间时,会将其子物体Width设置为Preferred Width,但是额外的空闲部分怎么办呢?在勾选了ControlChildSize和ChildForceExpand下,父物体会将所有子物体等比拉伸,就是说每个子物体拉伸的长度都是固定的,所以造成了对不齐的情况。这个时候就需要用到Flexible Width,用来决定空闲空间怎么分配,注意这个Flexible Width单位是权重,而不是像素
我们知道子物体宽度为A:920,B:1900,C:920,此时3者的比值为1,2,1,这时将3个子物体的Flexible Width设置为1,2,1,就可以实现正确的放大了,如图10
在这里插入图片描述
[图10]
这个与情况2的计算一样,就是说Flexible Width设置后,子物体以在空闲空间进行分配时,如果Flexible Width更高,则得到更多的空闲空间
用法:在正常分辨率情况下,计算好子物体之间的比值,这个比值就是Flexible Width,如果父物体空闲空间不够,则不计算Flexible Width

总结:灵活使用LayoutGroup和LayoutElement,可以实现子物体的长宽自适应,以及分辨率切换时缩放的整体协调,并且可以嵌套使用

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

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

相关文章

反应力场的生成物、反应路径分析方法

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

“自动驾驶第一股” 图森未来退市转型:改名 CreateAI、发布图生视频大模型 “Ruyi”

12 月 19 日&#xff0c;自动驾驶公司图森未来&#xff08;TuSimple&#xff09;宣布启用全新品牌 CreateAI&#xff0c;并发布多项在生成式 AI 领域的进展。 CreateAI 宣布获著名武侠 IP《金庸群侠传》正版授权&#xff0c;将开发一款大型武侠开放世界 RPG 游戏。 新的 Creat…

FreeRTOS实战——一、基于HAL库项目的FreeRTOS移植步骤

FreeRTOS实战——一、基于HAL库项目的移植步骤 文章目录 FreeRTOS实战——一、基于HAL库项目的移植步骤前言一、下载和移植FreeRTOS二、系统文件配置2.1 FreeRTOSConfig.h中添加如下3个配置&#xff1a;2.2 修改stm32f1xx_it.c 前言 废话不多说&#xff0c;在FreeRTOS基础&…

编程初学者使用 MariaDB 数据库反射生成

编程初学者使用 MariaDB 数据库反射生成 数据库反射生成&#xff0c;是动词算子式通用代码生成器提供的高级功能&#xff0c;可以利用已有的数据库&#xff0c;反射生成相应数据库的前端和后端项目。此功能自动化程度很高&#xff0c;并且支持完善的元数据和数据编辑&#xff…

yolov6算法及其改进

yolov6算法及其改进 1、YOLOV6简介2、RepVGG重参思想3、YOLOv6架构改进3.1、Backbone方面3.2、SPP改进3.3、Neck改进3.4、Head改进 4、正负样本匹配与损失函数4.1、TaskAligned样本匹配4.2、VFL Loss分类损失函数4.3、SIOU损失函数4.4、DFL损失函数 1、YOLOV6简介 YOLOv6设计主…

Redis字符串底层结构对数值型的支持常用数据结构和使用场景

字符串底层结构 SDS (Simple Dynamic Strings) 是 Redis 中用于实现字符串类型的一种数据结构。SDS 的设计目标是提供高效、灵活的字符串操作&#xff0c;同时避免传统 C 字符串的一些缺点。 struct sdshdr {int len; // 已使用的长度int free; // 未使用的长度char bu…

面试241228

面试可参考 1、cas的概念 2、AQS的概念 3、redis的数据结构 使用场景 不熟 4、redis list 扩容流程 5、dubbo 怎么进行服务注册和调用&#xff0c;6、dubbo 预热 7如何解决cos上传的安全问题kafka的高并发高吞吐的原因ES倒排索引的原理 spring的 bean的 二级缓存和三级缓存 spr…

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…

深度解析:Maven 和 Gradle 的使用比较及常见仓库推荐

Maven 和 Gradle 是 Java 项目中最常用的构建工具。它们各有优势&#xff0c;适用于不同的场景。本文将对两者进行详细的对比&#xff0c;并推荐一些常用的 Maven 和 Gradle 仓库&#xff0c;帮助开发者高效管理依赖。 一、Maven 和 Gradle 的使用比较 1.1 基本介绍 Maven 基…

STM32 与 AS608 指纹模块的调试与应用

前言 在嵌入式系统中&#xff0c;指纹识别作为一种生物识别技术&#xff0c;广泛应用于门禁系统、考勤机、智能锁等场景。本文将分享如何在 STM32F103C8T6 开发板上使用 AS608 指纹模块&#xff0c;实现指纹的录入和识别功能。 硬件准备 STM32F103C8T6 开发板AS608 指纹模块…

3GPP R18 MT-SDT

Rel-17 指定MO-SDT允许针对UL方向的数据包进行小数据包传输。对于DL,MT-SDT(即DL触发的小数据)可带来类似的好处,即 通过不转换到 RRC_CONNECTED来减少信令开销和UE功耗,并通过允许快速传输(小而少见的)数据包(例如用于定位)来减少延迟。 在R17中,NR_SmallData_INACTIVE的工…

微信小程序打印生产环境日志

微信小程序打印生产环境日志 新建一个log.js文件&#xff0c;写入以下代码&#xff1a; let log wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : nullmodule.exports {debug() {if (!log) returnlog.debug.apply(log, arguments)},info() {if (!log) returnlog.i…

Flutter路由工具类RouteUtils,可二次开发,拿来即用

一、RouteUtils路由核心类 /*** 路由封装*/ class RouteUtils {RouteUtils._();static final navigatorKey GlobalKey<NavigatorState>();// App 根节点Contextstatic BuildContext get context > navigatorKey.currentContext!;static NavigatorState get navigato…

小程序基础 —— 02 微信小程序账号注册

微信小程序账号注册 小程序开发与网页开发不一样&#xff0c;在开始微信小程序开发之前&#xff0c;需要访问微信公众平台&#xff0c;注册一个微信小程序账号。 有了小程序的账号以后&#xff0c;才可以开发和管理小程序&#xff0c;后续需要通过该账号进行开发信息的设置、…

分類タスクの評価指標をわかりやすく解説!

分類タスクの評価指標をわかりやすく解説&#xff01; 1. 正解率&#xff08;Accuracy&#xff09;2. 適合率&#xff08;Precision&#xff09;3. 再現率&#xff08;Recall&#xff09;4. F1スコア&#xff08;F1 Score&#xff09;まとめ こんにちは&#xff01;今日は、機械…

两个链表的第一个公共结点

输入两个链表&#xff0c;找出它们的第一个公共结点。 当不存在公共节点时&#xff0c;返回空节点。 数据范围 链表长度 [1,2000] 保证两个链表不完全相同&#xff0c;即两链表的头结点不相同。 算法思想描述 如上图所示&#xff0c;两种链表的出现的情况只有图中2中&…

4.基于 Couchbase 构建数据仓库的元数据管理方案

在基于 Couchbase 构建数据仓库时&#xff0c;元数据管理至关重要&#xff0c;它能够帮助跟踪数据结构、数据源、ETL作业、分区、索引等信息。以下是几个关键步骤和实现思路&#xff1a; 1. 元数据的定义范围 元数据在数仓中的主要用途包括&#xff1a; 数据库和表的组织&…

OpenAI 12天发布会:AI革命的里程碑@附35页PDF文件下载

在人工智能的浪潮中&#xff0c;OpenAI的12天发布会无疑是2024年科技界的一场盛宴。从12月5日开始&#xff0c;OpenAI连续12天每天发布一个新应用或功能&#xff0c;标志着AI技术的又一次飞跃。本文将梳理这些激动人心的发布&#xff0c;带你一探究竟。 OpenAI发布会概览 Ope…

MMaudio AI:如何通过 AI 实现精准的视频到音频合成

1. 引言&#xff1a;视频音效制作的新纪元 无论是短视频创作者还是电影后期制作团队&#xff0c;音效始终是提升作品质量的关键。然而&#xff0c;手动调整音效不仅耗时&#xff0c;还容易出错。试想&#xff0c;如果一项 AI 技术能够根据视频内容自动生成与画面完美同步的音效…

理解数列和函数的极限

什么是数列 数列就是按照1定顺序排列的数字&#xff0c; 也可以理解为包含数字元素的队列 格式: a 1 , a 2 , a 3 , . . . , a n a_1, a_2, a_3, ..., a_n a1​,a2​,a3​,...,an​, n ∈ N n \in N n∈N 或者 { a n } \{ a_n \} {an​}, n ∈ N n \in N n∈N 其中 a n…