为什么有些节点使用 "position" 而其他节点使用 "rect_position"?

Why do some nodes use "position" and others use "rect_position"?

这是什么技术原因?他们不能都只使用位置,这对我来说似乎很奇怪。这是遗留的东西吗?

存在三组相关的节点。那些扩展:

  • Control,在这里你可以找到rect_position
  • Node2D,在这里你可以找到position
  • Spatial,这里只能找到transform.

这些节点用颜色编码。所有 Control 都是绿色,所有 Node2D 都是蓝色,所有 Spatial 都是红色。是的,这是关于色觉缺陷的可访问性问题。这里呼吁重新设计图标:Tweak editor node icons to be distinguishable without relying on color (colorblind-friendly).

是的,有些命名混乱。对于初学者 2D 节点,在名称中说“2D”,但 3D 节点则不要(例如 CameraCamera2D)。对于 Godot 4.0,这尤其发生了变化。

如果您有更好的命名想法,可以提出建议(as an issue on github)。

说说这几组节点的定位有何不同……


转换

Spatial 个节点使用 Transform。事实上,有人提议将 transform 属性 重命名为“position”。正如您所知,这不是一回事,因为 Transform 不仅有位置,还有旋转、缩放等。

我知道你没有问过 transform。但是,您需要知道 Node2D 也有一个 transform 属性,类型 - 您插角 - Transform2D。这就是 Node2D 的实际定位方式。同时positionrotationrotation_degreesscale是为了方便使用。


定位控件

SpatialNode2Dtransform。你猜怎么了? Control 没有。相反,Control 旨在以下列方式之一定位:

  • 它被放置在一个Container中(也就是Controls),Container决定它如何定位,考虑到“Size Flags”(即它们的用途)。
  • 通过锚点 (anchor_*) 和边距 (margin_*)。抽象就是anchors是factor,margin是offset。例如,控件的最左侧部分将位于 anchor_left * parent_width + margin_left.
  • 通过 rect_positionrect_size。其中 rect_position 是距 parent.
  • 左上角的位置

一个警告:rect_min_size是坚持。 是的,还有 rect_rotationrect_scale 对上述解释提出了质疑,但它的工作原理正如人们想象的那样。

我说 intended 因为你可以混合这些。例如,您可以通过锚点和边距定位控件,或将其放置在 Container 中,然后为效果设置动画 rect_position


如您所见,positionrect_position 是两个不同的东西。 并非某些节点卡在一个或另一个名称或类似名称的情况下。

我还应该提到这些属性有“全局”版本,因为它们的定位符合它们的 parent。


上前缀

好吧,它们是不同的,但它们确实 - 初步近似 - 同一件事。为什么他们不能同名?

除此之外,它还提醒我们它们不是同一回事。在 Godot 中给属性加上前缀是有原因的。那是为了便于在检查器面板中对它们进行分组。

例如,“Anchor”组将具有名称以 anchor 开头的所有属性,并且该前缀不会显示在 属性 的名称中。

同样,您找到的一组是“Rect”。是的,rect_position 在里面。除了相关的属性。这也有助于从代码编辑器中发现这些属性,因为它们会一起出现在自动完成中。

这一切应该会让新用户更容易理解 Control 定位是如何工作的。但是,老实说,它的效果并不好。另见提案:Redesign how user interface (Controls) scaling is presented to the user.


Node2D 内部的控件

您可以 - 并且您可能需要 - 将 Control 放在 Node2D 中。例如,如果您想要 LabelProgressBar(即 Control)跟在 Node2D.

之后

Godot 将处理该职位。但是你会发现缩放和居中的问题,因为 Node2D 没有 Control 可以使用的大小(有些 - 例如 Sprite - 具有视觉大小作为优点他们的Texture,没有暴露为属性,Control不使用它。

可能想用一些混合 rect_positionposition 的代码破解它。

Node2D 中居中 Control 本身并不难(有 Containers、锚点和边距,以及良好的旧手定位)。问题是当它改变大小时保持居中。特别是当您向 Label 添加更多文本时,它会不顾一切地坚持向右增长。但不要担心,您需要的是处理 resized 信号并调用 set_anchors_and_margins_preset,这就是您在编辑器中的“布局”选项中所做的。


[=140=控件中的 Node2D

您也可以将 Node2D 放在 Control 中,Godot 将再次处理该位置。 您可能希望在 Control 上设置 rect_clip_content

但是,将 Node2D 放在 Container 中无法正常工作。 Container 无法处理 Node2D children.

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

  • SpriteNode2D)改为TextureRectControl)。
  • TouchScreenButton (a Node2D) 更改为 Button (a Control) 并在项目设置 -> 输入设备 -> 指向中启用触摸仿真。
  • 有一个 Viewport 和一个 Camera2D 旁边任何你想在那里显示的 Node2D为了便于设计,我建议将其作为单独的场景制作。不要忘记为 Viewport 指定大小。然后,要么:
    • Viewport 放在 ViewportContainer 中(Control)。 您可能希望将 ViewportContainerstretch 设置为 true
    • 或使用 TextureRectViewportTexture

虽然我在做,但我还建议将主场景的根设为 Node(不是任何派生类型),然后使用 CanvasLayers 分隔UI 来自游戏世界。这将防止 Camera2D 影响 UI。