为什么一些节点使用“position”,而另一些节点使用“rect_position”?

7

这是什么技术原因?它对我来说似乎很奇怪,为什么它们不能都只使用position呢?这是遗留问题吗?

1个回答

9

有三组相关的节点:那些扩展:

  • Control,在这里您会找到rect_position
  • Node2D,在这里您会找到position
  • Spatial,在这里您只会找到transform

这些节点有不同的颜色编码。所有的Control是绿色的,所有的Node2D是蓝色的,而所有的Spatial是红色的。是的,这对于颜色视觉缺陷是一个可访问性问题。这里提出了一个重新设计图标的呼吁:调整编辑器节点图标使其不依赖颜色以区别(适合色盲者)

是的,有一些命名上的混乱。首先,2D节点在名称中说“2D”,但3D节点不说(例如CameraCamera2D)。特别是在Godot 4.0中已经发生了变化。

如果您有关于命名如何更好的想法,可以提出提案(作为github上的问题)。

让我们来谈谈这些节点集的定位方式的不同之处...


关于变换

Spatial节点使用Transform。事实上,有些人已经建议将transform属性重命名为“position”。正如您所知道的,这并不是同一件事,因为Transform不仅包括位置,而且还包括旋转、缩放等等。

我知道您没有询问transform。然而,您需要知道的是,Node2D也有一个Transform2D类型的transform属性。这就是Node2D的实际定位方式。而positionrotationrotation_degreesscale则是为了方便使用。


控件定位

SpatialNode2D都有transform。猜猜?Control没有。相反,Control被设计成用以下任一方式定位:

  • 控件(也是“控件”)放置在容器中,容器决定它的位置,考虑“大小标志”(这就是它们的作用)。
  • 通过锚点(anchor_*)和边距(margin_*)设置。抽象地说,锚点是因子,而边距是偏移量。例如,控件的最左侧部分将位于anchor_left * parent_width + margin_left处。
  • 通过rect_positionrect_size设置。其中rect_position是相对于父级左上角的位置。

需要注意的一点是:保持了rect_min_size是的,还有rect_rotationrect_scale,它们可能会对上述解释造成影响,但它们的使用方式与人们想象的一样。

我说“打算”是因为可以混合使用这些方法。例如,您可以通过锚点和边距来定位控件,或者将其放置在容器中,但然后使用rect_position进行动画效果。


如您所见,positionrect_position是两个不同的东西。并不是某些节点被卡在一个名称或其他类似的名称上。

我还应该提到,这些属性都有“全局”版本,因为它们相对于其父级定位。


关于前缀

好吧,它们不同,但就第一近似而言,它们做着相同的事情。为什么它们不能有相同的名称?

除了提醒它们不是同一个东西之外,Godot中给属性添加前缀还有一个原因:便于在检查器面板中将它们分组。

例如,“锚点”组将包含所有属性名以anchor开头的属性,而该前缀不会显示在属性名称上。

同样,您可以在找到的组中找到“矩形”组。是的,rect_position就在其中。此外还有相关属性。这也有助于从代码编辑器中发现这些属性,因为它们会在自动完成时一起显示。

所有这些都应该使新用户更容易理解控件定位的工作原理。然而,让我们诚实地说,它的效果并不好。请参阅提案:重新设计向用户呈现用户界面(控件)缩放的方式


Node2D中的控件

您可以将Control放置在Node2D中,有时您可能需要这样做。例如,如果您希望一个LabelProgressBar(它们是Control)跟随在Node2D后面,Godot会处理其位置。但是,您会发现缩放和居中存在问题,因为Node2D没有Control可以使用的大小(一些如Sprite具有视觉大小作为其Texture的属性,但这不会公开为属性,而且Control不使用它)。 这就是您可能想要使用一些混合了rect_positionposition代码来解决问题的地方。Control居中于Node2D本身并不困难(有容器、锚点和边距以及手动定位方法)。问题是当其尺寸变化时保持其居中状态,特别是当您向Label添加更多文本时,其尺寸会不断增加。但是请不要担心,您需要处理resized信号,并在其中调用set_anchors_and_margins_preset,这就是您从编辑器的"布局"选项中所做的。

在控件内放置Node2D

您也可以将Node2D放置在Control内部,此时Godot也会处理其位置。您可能需要在Control上设置rect_clip_content

但是,在Container中放置Node2D无法正常工作。 Container无法处理Node2D子元素。

如果您正在尝试这样做,可能需要执行以下操作之一:

  • 将一个Sprite(一个Node2D)更改为TextureRect(一个Control)。
  • 将一个TouchScreenButton(一个Node2D)更改为Button(一个Control),并在项目设置->输入设备->指针中启用触摸模拟。
  • 有一个带有Camera2DViewport与您想要在其中显示的任何Node2D我建议将其作为单独场景进行设计以便于设计。不要忘记给Viewport大小。然后,要么:
    • 将该Viewport放入ViewportContainer(一个Control)中。您可能需要将ViewportContainerstretch设置为true
    • 或者使用带有ViewportTextureTextureRect

顺便说一句,建议将主场景的根节点设置为Node(不是任何派生类型),然后使用CanvasLayer来分离UI和游戏世界。这将防止Camera2D影响UI。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接