【发布时间】:2021-09-28 07:46:11
【问题描述】:
这是什么技术原因?我觉得很奇怪,他们不能都只使用位置。这是遗留的东西吗?
【问题讨论】:
这是什么技术原因?我觉得很奇怪,他们不能都只使用位置。这是遗留的东西吗?
【问题讨论】:
共有三组相关的节点。那些扩展:
Control,在这里你可以找到rect_position。Node2D,在这里你可以找到position。Spatial,在这里你只能找到transform。这些节点是彩色编码的。所有Controls 都是绿色的,所有Node2D 都是蓝色的,所有Spatials 都是红色的。是的,这是关于色觉缺陷的可访问性问题。此处呼吁重新设计图标:Tweak editor node icons to be distinguishable without relying on color (colorblind-friendly)。
是的,有一些命名混乱。对于初学者来说,2D 节点的名称中会显示“2D”,但 3D 节点不会(例如 Camera 与 Camera2D)。对于 Godot 4.0,这一点尤其发生了变化。
如果您对如何更好地命名有任何想法,您可以提出建议 (as an issue on github)。
让我们谈谈这些节点集的定位有何不同……
关于变换
Spatial 节点使用Transform。事实上,有人提议将transform 属性重命名为“位置”。如您所知,这不是一回事,因为Transform 不仅有位置,还有旋转、缩放等。
我知道你没有问过transform。但是,您需要知道Node2D 也有一个transform 属性,类型为-您插角-Transform2D。这就是Node2D 的实际定位方式。同时position、rotation、rotation_degrees和scale是为了方便使用。
定位控件
Spatial 和 Node2D 有 transform。你猜怎么了? Control 没有。相反,Control 旨在以下列方式之一定位:
Container(也是Controls)中,Container 决定它的位置,考虑到“大小标志”(这就是它们的用途)。李>
anchor_*) 和边距 (margin_*)。抽象是anchors是factor,margin是offset的。例如,控件的最左侧部分将位于anchor_left * parent_width + margin_left。rect_position 和 rect_size。其中rect_position 是父级左上角的位置。一个警告:rect_min_size 是坚持。 是的,还有 rect_rotation 和 rect_scale 对上述解释提出了质疑,但它的工作原理与人们想象的一样。
我说 有意 因为你可以混合使用这些。例如,您可以通过锚点和边距来定位控件,或者将其放置在Container 中,然后为rect_position 设置动画效果。
如您所见,position 和 rect_position 是两个不同的东西。 并不是某些节点被一个名字或另一个名字卡住了。
我还应该提到,这些属性有“全局”版本,因为它们的位置相对于它们的父级。
关于前缀
好吧,它们是不同的,但它们确实 - 大致上 - 相同的东西。为什么他们不能有相同的名字?
除了提醒他们它们不是一回事之外。在 Godot 中为属性添加前缀是有原因的。这是为了便于在检查器面板中对它们进行分组。
例如,“Anchor”组将包含名称以anchor 开头的所有属性,并且该前缀不会显示在属性名称上。
同样,您找到的组之一是“矩形”。是的,rect_position 在里面。除了相关的属性。这也有助于从代码编辑器中发现这些属性,因为它们会一起显示在自动完成中。
这一切都应该让新用户更容易弄清楚Control 定位的工作原理。但是,老实说,它的效果并不好。另见提案:Redesign how user interface (Controls) scaling is presented to the user。
Node2D 中的控件
您可以 - 而且您可能需要 - 将 Controls 放在 Node2D 中。例如,如果您想要在Node2D 之后使用Label 或ProgressBar(即Control)。
Godot 会处理这个位置。但是你会发现缩放和居中的问题,因为Node2D 没有Controls 可以使用的大小(一些 - 例如Sprite - 有一个视觉大小作为他们的Texture,不作为属性公开,Control 不使用它)。
可能想用一些混合rect_position 和position 的代码来破解它。
在Node2D 中居中Control 本身并不难(有Containers、锚点和边距,以及良好的旧手定位)。问题是当它改变大小时保持居中。特别是当您向Label 添加更多文本时,尽管有各种困难,它仍坚持向右增长。但不要担心,您需要处理resized 信号并调用set_anchors_and_margins_preset,这是您在编辑器中的“布局”选项中所做的。
控件内的 Node2D
您也可以将Node2D 放在Control 中,Godot 将再次处理该位置。 您可能希望在Control 上设置rect_clip_content。
但是,将Node2D 放在Container 中无法正常工作。 Container 无法处理 Node2D 子级。
如果您尝试这样做,您可能需要执行以下操作之一:
Sprite(Node2D)更改为TextureRect(Control)。TouchScreenButton (a Node2D) 更改为 Button (a Control) 并在项目设置 -> 输入设备 -> 指向中启用触摸模拟。Viewport 和一个Camera2D,旁边是你想在那里显示的任何Node2D。 为了便于设计,我建议将其制作为单独的场景。不要忘记给Viewport 提供大小。然后,要么:
Viewport 放在ViewportContainer(Control)内。 您可能希望将ViewportContainer 的stretch 设置为true。TextureRect 和ViewportTexture。在此过程中,我还建议将主场景的根设为 Node(不是任何派生类型),然后使用 CanvasLayers 将 UI 与游戏世界分开。这将防止Camera2D 影响用户界面。
【讨论】: