Unity UI - 如何制作“复合”布局组以在同一位置组合多个图像?

Posted

技术标签:

【中文标题】Unity UI - 如何制作“复合”布局组以在同一位置组合多个图像?【英文标题】:Unity UI - How to make a "Composite" Layout Group to combine multiple images in the same location? 【发布时间】:2021-06-19 22:02:53 【问题描述】:

我正在制作一个简单的自动布局 UI,它由一个带有背景图像和三行文本的面板组成。

首先,我在***“面板”游戏对象中有一个垂直布局组组件,设置为控制子高度。它还有一个内容大小调整器,其中“首选”设置为垂直适合。 Panel 对象有一个背景图像,并且有几个子对象代表视图中的行:

Panel [Vertical Layout Group] [Image] [Content Size Fitter]
  - Text 1
  - Text 2
  - Text 3

这一切都按原样运行。

我的问题出现是因为我希望面板背景由 两个 图像组成 - 一个是填充的背景图像,另一个是适合背景并添加的大部分透明的“框架”图像细节只到边缘和角落。两张图片都被切片了。

不幸的是,Unity 不允许在单个 GameObject 上使用多个图像组件,因此这使我无法简单地将两个图像添加到面板中。如果这行得通,那就足够了。

相反,如果我将图像添加到 Panel 的新子级,则它将作为子级包含在 VLG 中,并且框架显示为新的第一行,即垂直布局的一部分。不是我想要的:

Panel [VLG] [Image:Background] [Content Size Fitter]
  - Frame [Image:Frame]
  - Text 1
  - Text 2
  - Text 3

我尝试将两个图像作为面板的两个子项移动,然后将第三个子项添加为“布局”,将原始子项作为其子项,使用 VLG(将其从面板中删除):

Panel [Content Size Fitter]
  - Background [Image: Background]
  - Frame [Image:Frame]
  - Layout [VLG]
    - Text 1
    - Text 2
    - Text 3

不幸的是,这似乎也不起作用,因为如果面板不包含某种布局组,则两个图像的尺寸不会由面板驱动。但显然,当我真的希望将所有三个叠加在一起时,将 VLG 添加到 Panel 会从 Frame 和 Layout 中分离出背景。

有没有办法创建一个“复合”布局组,使子级相互叠加,而不是水平或垂直组合?我查看了 UnityEngine.UI.LayoutGroup 抽象基类的源代码,想知道是否可以创建类似于 VLG 的东西,但只是通过模拟 UnityEngine.UI.VerticalLayoutGroup 将所有子类放在同一位置,但为每个子位置返回相同的 Y 值。这行得通吗?

我知道我可以手动将这两个图像组合成一个图像并只使用一个图像 - 但是我想更好地了解在一般情况下我如何能够做到这一点。此外,当图像之间的切片尺寸不同时,您可以通过运行时合成获得更有趣的结果。

【问题讨论】:

道歉:我也在 GameDevelopment SE 上发布了这个,因为直到我发布后不久我才知道它的存在。但是这里有很多与 Unity 相关的问题,并且有人回答了这些问题,所以我会留下来以防有人可以提供帮助。 【参考方案1】:

试试这个

Panel  [Image:Background] [Content Size Fitter]
  - Frame [VLG] [Image:Frame]
    - Text 1
    - Text 2
    - Text 3

【讨论】:

感谢您的建议。这确实有些作用,但由于某种原因,切片框架图像的尺寸(即使它是切片的也是 900x900)模糊了内容尺寸(文本 1、2、3),从而导致面板无法正确调整大小。我想我需要找到一种方法让 Frame 的 VLG 忽略附加到自身的图像。 Dialogue 也会发生同样的事情 - 即使背景图像是切片的,它也会将其首选大小强加到 Content Size Fitter。我会尝试一些布局元素,看看是否可以避免这种情况。 是的,不幸的是 - 对话上的切片图像的尺寸(0x0,因为它是用零边距切片的)阻止任何可能从像 Frame 这样的孩子出现的最小或首选尺寸的传播,所以背景图像保持 0x0。此外,由于我还不明白的原因,Frame 的尺寸不是由 Panel 的 Content Size Fitter 驱动的。我在面板上尝试了一个 VLG(上面评论中的“对话”,抱歉)来驱动孩子的(框架)宽度和高度,但由于上面的原因,它最终为 0x0。 好的,我现在正在做一些事情 - 似乎有时只是切换检查器中的控件会产生不同的结果。我将 Content Size Fitter 从 Preferred Size 切换回 Unconstrained 然后再切换回来,它已经开始正常工作... @davidA 内容大小调整器不会影响其子项的帧大小。它与子尺寸相反会影响内容尺寸 fitter 尺寸。把它想象成一个糖果包装纸,它适合它的儿童尺寸。尝试改变孩子的大小,包装器将适合自己。 您的回答让我成功了——再次感谢您。关键是按照您的建议进行操作,但还要向 Panel 对象添加一个 VLG,其中包含子控件大小宽度和高度。似乎没有额外的 VLG,面板上的背景图像最终的首选宽度和高度为零,使其消失。堆栈中的其他所有内容都在工作。【参考方案2】:

感谢@Art Zolina III,关键是将第二个图像放在 Content Size Fitter 的唯一孩子上,并在同一个孩子上使用垂直布局组 (VLG) 将最终的孩子传播回***对象(面板)。

Panel [Image:Background, sliced] 
      [Content Size Fitter: Horiz Preferred, Vert Preferred]
      [Vertical Layout Group: Control Child Width, Height]
  - Frame [Image:Framing, sliced] 
          [VLG: Control Child Width, Height; Child Force Expand Width]
    - Text 1 [TextMeshPro Text]
    - Text 2 [TextMeshPro Text]
    - Text 3 [TextMeshPro Text]

请注意,切片图像的首选高度是顶部和底部边框高度的总和,这意味着它不能轻易缩小到低于该高度。这让我大吃一惊,因为我的图像有一个 900 像素的组合垂直边框空间,这让我误以为我的布局没有缩小“以适应”。一旦我使用了具有较小顶部和底部边距的切片图像,面板布局似乎可以正常工作。

此外,Sprite 的切片边界似乎受到每单位像素乘数的影响,这意味着您可以使边界小于视觉上应有的值,但增加乘数以使所有边距仍然完整呈现(但分辨率更高)。

【讨论】:

以上是关于Unity UI - 如何制作“复合”布局组以在同一位置组合多个图像?的主要内容,如果未能解决你的问题,请参考以下文章

unity中如何将Ui Image占满界面

unity小地图制作___按比例尺图标布局

unity设置UI界面16:9铺满屏幕

如何修复 Unity 中的“无法从复合材料中读取 Vector2 类型的值”错误?

我在制作一串字符数组以在 Unity 引擎中打印到屏幕时遇到问题

Unity2019学习:常用功能--Unity UI自动布局相关组件