使用容器
锚点 是处理图形用户界面中基本多分辨率处理的不同纵横比的有效方法,
对于更复杂的用户界面, 它们可能会变得难以使用.
这通常是游戏的情况下, 如角色扮演类, 在线聊天, 大富翁类或模拟类游戏. 另一个需要更高级布局功能的常见情况是游戏内工具(或者仅仅是工具).
这些情况需要一个更强大的类似操作系统的用户界面, 具有先进的布局和格式. 为此, 容器 更有用.
容器布局
容器提供了巨大的布局能力(例如,Godot编辑器的用户界面就是完全使用它们完成的):
当使用 容器 派生节点时, 所有 控件 子节点放弃了自己的定位能力. 这意味着 Container容器 将控制它们的位置, 任何手动更改这些节点的尝试, 都将在它们的父节点下一次调整大小时被忽略或失效.
同样, 当一个 Container 派生的节点被调整大小时, 它的所有子节点将根据它重新定位, 其行为基于所用的容器类型:
例如 HBoxContainer 调整子按钮的大小.
容器的真正优势在于它们可以嵌套(作为节点), 允许创建非常复杂的布局, 调整毫不费力.
大小标志
当向容器添加节点时, 容器对待每个子元素的方式, 主要取决于它们的 size flags尺寸标记 . 通过检查 容器 的子控件, 可以找到这些标记.
尺寸标记独立于垂直和水平尺寸, 并不是所有容器都使用它们(但大多数容器都使用):
Fill填充 : 确保控件 fills填充 容器内指定的区域. 无论控件是否 expands扩展 (见下面), 当此选项被选中时(默认情况), 只 填充 指定区域.
Expand扩展 : 试图在父容器中尽可能多地使用空间(在每个轴中). 不展开的控件会被展开的控件推开. 在扩展的控件之间, 它们相互占用的空间大小由 Ratio 决定(见下文).
Shrink Center收缩中心 当扩展时(如果不填充), 尽量保持在扩展区域的中心(默认情况下, 它仍然位于左侧或顶部).
Ratio比例 扩展控件之间, 相互占用可用空间的简单比例. 一个比例为 “2” 的控件, 将占用比例为 “1” 控件的两倍可用空间.
建议使用这些标记和不同的容器进行试验, 以便更好地了解它们是如何工作的.
容器类型
Godot提供了几种开箱即用的容器类型, 因为它们有不同的用途:
格子容器(Box Containers)
将子控件垂直或者水平排列(使用 HBoxContainer 和 VBoxContainer )。而在相对方向上(比如水平容器的垂直方向),子节点会被扩展。
这些容器会用到设置了 Expand(扩展) 选项的子节点的 Ratio(比例) 属性。
网格容器
将子控件按照网格排列(使用 GridContainer ,必须指定列数),会同时用到垂直和水平扩展选项。
边距容器
将子节点扩展到该控件的边界(使用 MarginContainer ),会根据主题的设置来添加不同大小的边距。
同样, 请记住, 边距是一个 Theme 值, 所以它们需要从每个控件的常量重写部分进行编辑:
选项卡容器
允许你将多个子控件堆叠在一起(使用 TabContainer ),只会显示 当前 控件。
点击容器顶部的选项卡可以更改 当前 控件:
标题默认是根据节点名称生成的(尽管可以通过 TabContainer 的 API 重写)。
可以在 TabContainer 的主题覆盖项中修改类似选项卡位置和 StyleBox 等设置。
拆分容器
只接受单个或者两个子控件,会将它们相邻放置,中间是分隔线(使用 HSplitContainer 和 VSplitContainer ),会使用到水平和垂直选项以及 Ratio 属性。
可以通过拖动分隔线来调整两个子节点所占区域的大小:
PanelContainer
绘制 StyleBox 的简单容器,会将子节点扩大到整个区域(使用 PanelContainer ,会考虑 * StyleBox* 的边距)。它同时考虑水平和垂直尺寸选项。
这个容器作为顶层非常有用, 或者只是为布局各个部分添加自定义背景.
ScrollContainer
接受一个单独的子节点. 如果这个节点比容器大, 将添加滚动条以允许移动节点(通过 滚动条容器). 考虑垂直和水平尺寸标识, 该行为可以在属性中的每个轴上打开或关闭.
鼠标滚轮和触摸拖动(当触摸可用时)也是平移子控件的有效方法.
在上面的例子中, 使用此容器最常见的方法之一, 是将 VBoxContainer垂直盒子容器 作为子容器一起使用.
ViewportContainer
这是一个特殊的控件,只接受单个 Viewport 节点作为子节点,并且会把它作为图片显示(使用 ViewportContainer)。
创建自定义容器
可以使用脚本轻松地创建自定义容器。下面是一个简单容器的例子,它会根据自身的矩形尺寸调整子节点:
GDScript
extends Container
func _notification(what):
if what == NOTIFICATION_SORT_CHILDREN:
# Must re-sort the children
for c in get_children():
# Fit to own size
fit_child_in_rect( c, Rect2( Vector2(), rect_size ) )
func set_some_setting():
# Some setting changed, ask for children re-sort
queue_sort()