首页 > 解决方案 > 为什么有些节点使用“position”而其他节点使用“rect_position”?

问题描述

这样做的技术原因是什么?我觉得很奇怪,他们不能都只使用位置。它是一个遗产吗?

标签: godotgdscript

解决方案


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

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

这些节点是彩色编码的。所有Control的 s 都是绿色的,所有Node2D的都是蓝色的,所有Spatial的 s 都是红色的。是的,这是关于色觉缺陷的可访问性问题。这里呼吁重新设计图标:将编辑器节点图标调整为可区分而不依赖于颜色(对色盲友好)

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

如果您对如何更好地命名有想法,您可以提出建议(作为 github 上的问题)。

让我们谈谈这些节点集的定位有何不同……</p>


关于变换

Spatial节点使用Transform. 事实上,也有人提议将transform物业重命名为“仓位”。如您所知,这不是一回事,因为 aTransform不仅具有位置,还具有旋转、缩放等。

我知道你没有问transform。但是,您需要知道 aNode2D也有一个transform属性,类型为 - you gusseted - Transform2D。这就是 aNode2D的实际定位方式。同时position,rotation和是为了rotation_degrees方便scale使用。


定位控制

Spatial并且Node2Dtransform。你猜怎么了?Control才不是。相反, aControl旨在以下列方式之一定位:

  • 它被放置在一个Container(这也是Controls)中,并Container决定它的位置,考虑到“大小标志”(这就是它们的用途)。
  • 通过锚点 ( anchor_*) 和边距 ( margin_*)。抽象是anchors是factor,margin是offset的。例如,控件的最左侧部分将位于anchor_left * parent_width + margin_left.
  • 通过rect_positionrect_sizerect_position父级左上角的位置在哪里。

一个警告:rect_min_size是坚持。是的,上面的解释也有rect_rotation一个rect_scale问题,但它的工作原理与人们想象的一样。

我说是有意的,因为你可以混合这些。例如,您可以通过锚点和边距来定位控件,或者将其放置在 aContainer中,然后为rect_positionfor 效果设置动画。


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

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


在前缀上

好的,它们是不同的,但它们确实 - 大致上 - 相同的东西。为什么他们不能有相同的名字?

除了提醒他们它们不是一回事之外。在 Godot 中为属性添加前缀是有原因的。这是为了便于在检查器面板中对它们进行分组。

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

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

这一切都应该让新用户更容易弄清楚Control定位是如何工作的。但是,老实说,它的效果并不好。另请参阅提案:重新设计如何向用户呈现用户界面(控件)缩放


Node2D 内部的控件

您可以 - 而且您可能需要 - 将Controls 放在Node2D. 例如,如果您想要 aLabel或 a ProgressBar(它们是Control)跟随 a Node2D

戈多将处理这个职位。但是你会发现缩放和居中的问题,因为Node2D没有Controls 可以使用的大小(有些 - 例如Sprite- 有一个视觉大小作为他们的优点Texture,它没有作为属性公开,Control也没有使用它)。

它在那里可能想用一些混合的代码来破解它rect_positionposition.

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


控件内的 Node2D

您也可以将 aNode2D放在a 内Control,Godot 将再次处理该位置。您可能要设置rect_clip_contentControl.

但是,将 aNode2D放在 aContainer内不能正常工作。Container不能处理Node2D孩子。

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

  • Sprite将 a (a Node2D)更改为TextureRect(a Control)。
  • TouchScreenButton将 a (a Node2D)更改为( Buttona Control) 并在 Project Settings -> Input Devices -> Pointing 中启用触摸仿真。
  • 无论你想在那里展示什么,都有Viewport一个Camera2D侧面。为了便于设计,我建议将其制作为单独的场景。不要忘记给. 然后,要么: Node2DViewport
    • 将其Viewport放在ViewportContainer(a Control) 内。您可能希望将 的 设置stretchViewportContainertrue
    • 或将 aTextureRect与 a 一起使用ViewportTexture

在此过程中,我还建议将主场景的根设为 a Node(不是任何派生类型),然后使用CanvasLayers 将 UI 与游戏世界分开。这将防止Camera2D影响用户界面。


推荐阅读