godot - 为什么有些节点使用“position”而其他节点使用“rect_position”?
问题描述
这样做的技术原因是什么?我觉得很奇怪,他们不能都只使用位置。它是一个遗产吗?
解决方案
存在三组相关的节点。那些扩展:
Control
, 在这里你可以找到rect_position
。Node2D
, 在这里你可以找到position
。Spatial
, 在这里你只能找到transform
.
这些节点是彩色编码的。所有Control
的 s 都是绿色的,所有Node2D
的都是蓝色的,所有Spatial
的 s 都是红色的。是的,这是关于色觉缺陷的可访问性问题。这里呼吁重新设计图标:将编辑器节点图标调整为可区分而不依赖于颜色(对色盲友好)。
是的,有一些命名混乱。对于初学者,2D 节点在名称中说“2D”,但 3D 节点没有(例如Camera
vs Camera2D
)。对于 Godot 4.0,这一点尤其发生了变化。
如果您对如何更好地命名有想法,您可以提出建议(作为 github 上的问题)。
让我们谈谈这些节点集的定位有何不同……</p>
关于变换
Spatial
节点使用Transform
. 事实上,也有人提议将transform
物业重命名为“仓位”。如您所知,这不是一回事,因为 aTransform
不仅具有位置,还具有旋转、缩放等。
我知道你没有问transform
。但是,您需要知道 aNode2D
也有一个transform
属性,类型为 - you gusseted - Transform2D
。这就是 aNode2D
的实际定位方式。同时position
,rotation
和是为了rotation_degrees
方便scale
使用。
定位控制
Spatial
并且Node2D
有transform
。你猜怎么了?Control
才不是。相反, aControl
旨在以下列方式之一定位:
- 它被放置在一个
Container
(这也是Control
s)中,并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
问题,但它的工作原理与人们想象的一样。
我说是有意的,因为你可以混合这些。例如,您可以通过锚点和边距来定位控件,或者将其放置在 aContainer
中,然后为rect_position
for 效果设置动画。
如您所见,position
和rect_position
是两个不同的东西。并非某些节点会被一个名称或其他名称或类似名称卡住。
我还应该提到这些属性有“全局”版本,因为它们是相对于它们的父对象定位的。
在前缀上
好的,它们是不同的,但它们确实 - 大致上 - 相同的东西。为什么他们不能有相同的名字?
除了提醒他们它们不是一回事之外。在 Godot 中为属性添加前缀是有原因的。这是为了便于在检查器面板中对它们进行分组。
例如,“Anchor”组将包含名称以 开头的所有属性anchor
,并且该前缀不会显示在属性名称上。
同样,您找到的组之一是“矩形”。是的,rect_position
在里面。除了相关的属性。这也有助于从代码编辑器中发现这些属性,因为它们会一起显示在自动完成中。
这一切都应该让新用户更容易弄清楚Control
定位是如何工作的。但是,老实说,它的效果并不好。另请参阅提案:重新设计如何向用户呈现用户界面(控件)缩放。
Node2D 内部的控件
您可以 - 而且您可能需要 - 将Control
s 放在Node2D
. 例如,如果您想要 aLabel
或 a ProgressBar
(它们是Control
)跟随 a Node2D
。
戈多将处理这个职位。但是你会发现缩放和居中的问题,因为Node2D
没有Control
s 可以使用的大小(有些 - 例如Sprite
- 有一个视觉大小作为他们的优点Texture
,它没有作为属性公开,Control
也没有使用它)。
它在那里可能想用一些混合的代码来破解它rect_position
和position
.
Control
在 a中居中 aNode2D
本身并不难(有Containers
、锚点和边距,以及良好的旧手定位)。问题是当它改变大小时保持居中。特别是当您向 a 添加更多文本时Label
,尽管困难重重,它仍坚持向右增长。但不要担心,您需要处理resized
信号并调用set_anchors_and_margins_preset
,这就是您在编辑器中的“布局”选项中所做的。
控件内的 Node2D
您也可以将 aNode2D
放在a 内Control
,Godot 将再次处理该位置。您可能要设置rect_clip_content
在Control
.
但是,将 aNode2D
放在 aContainer
内不能正常工作。Container
不能处理Node2D
孩子。
如果您尝试这样做,您可能需要执行以下操作之一:
Sprite
将 a (aNode2D
)更改为TextureRect
(aControl
)。TouchScreenButton
将 a (aNode2D
)更改为(Button
aControl
) 并在 Project Settings -> Input Devices -> Pointing 中启用触摸仿真。- 无论你想在那里展示什么,都有
Viewport
一个Camera2D
侧面。为了便于设计,我建议将其制作为单独的场景。不要忘记给. 然后,要么:Node2D
Viewport
- 将其
Viewport
放在ViewportContainer
(aControl
) 内。您可能希望将 的 设置stretch
为ViewportContainer
true。 - 或将 a
TextureRect
与 a 一起使用ViewportTexture
。
- 将其
在此过程中,我还建议将主场景的根设为 a Node
(不是任何派生类型),然后使用CanvasLayer
s 将 UI 与游戏世界分开。这将防止Camera2D
影响用户界面。
推荐阅读
- r - 如何按几组汇总数据(R)
- angular - Angular 8:HttpClient - 发送长字符串
- excel - 如何将本地excel文件导入雪花数据库表?我需要每天这样做
- templates - 如何使用 K8S 测试 pod 模板中的删除GracePeriodSeconds
- reactjs - 无法清除浏览器内存,即使使用 pixi 清除所有纹理缓存。我正在使用 pixioverlay 并做出反应传单
- node.js - 如何为谷歌云功能模拟器指定内存?
- maven - 如何触发 IntelliJ 重新导入单个 Maven 依赖项?
- package - 在 conda 中安装 Octave 失败
- java - 无法在生成的 JAR 中找到主类
- go - 为什么即使左侧没有定义新变量,else if 语句中的短变量声明也不会编译失败?