2D 坐标系与 2D 变换
前言
本文对可用的 2D 坐标系和内置的 2D 变换进行了详细介绍。相关基础概念见 视口变换与画布变换。
Transform2D 是用于在坐标系之间进行转换的矩阵,使用前最好先了解一下 Godot 提供了哪些坐标系。如果需要更深入地了解底层的相关信息,请参考 矩阵与变换 教程。
Godot 2D 坐标系
下图展示的是 Godot 2D 中的坐标系、节点变换、变换函数、坐标系相关函数的概览。最左侧是操作系统“窗口管理器”的屏幕,最右侧是 CanvasItem。简单起见,这张图中没有加入 SubViewport、SubViewportContainer、ParallaxLayer 和 ParallaxBackground,尽管它们也能够影响变换。
这张图基于 根 Window(内嵌其他窗口)
⇒ Window(没有内嵌窗口)
⇒ CanvasLayer
⇒ CanvasItem
⇒ CanvasItem
⇒ CanvasItem
的节点树绘制。节点树还可以有更加复杂的组合,例如可以让 Window 和 SubViewport 进行更深层的嵌套,不过本示例主要的目的还是展示通用的思考方法。

单击图片放大。
- Item 坐标
这是 CanvasItem 的局部坐标系。
- 父 Item 坐标
这是父级 CanvasItem 的局部坐标系。在画布中放置 CanvasItem 时,这些画布项会继承父级 CanvasItem 的变换。CanvasItems.top_level 则是例外。
- 画布坐标
之前的教程 画布层 中就提到过,画布有两种(Viewport 画布和 CanvasLayer 画布),两者用的都是画布坐标系。画布坐标也叫世界坐标。一个 Viewport 可以包含多个画布,不同画布所使用的坐标系可以不同。
- 视口坐标
这是 Viewport 的坐标系。
- 相机坐标
仅在内部使用,用于实现 3D 相机光线投射等功能。
- 嵌入器坐标 / 屏幕坐标
场景树中的各个 Viewport(Window 或 SubViewport)不是嵌入在其他节点中,就是嵌入在操作系统的“窗口管理器”中。这种坐标系的原点位于 Window 或 SubViewport 的左上角,缩放与嵌入器或操作系统的“窗口管理器”一致。
如果嵌入器是操作系统的“窗口管理器”,那么对应的坐标也可以称为屏幕坐标。
- 绝对嵌入器坐标 / 绝对屏幕坐标
这种坐标系的原点是所嵌节点或的操作系统的“窗口管理器”的左上角。缩放与嵌入器或操作系统的“窗口管理器”一致。
如果嵌入器是操作系统的“窗口管理器”,那么对应的坐标也可以称为绝对屏幕坐标。
节点变换
此处涉及的节点都有一个或多个变换与之关联,将节点组合后就得到了在不同坐标系之间的变换。除了一些特殊情况之外,变换都是 Transform2D,下面列出了它们各自的详细信息和作用。
- CanvasLayer 变换
CanvasLayer 的变换为 transform,会影响该 CanvasLayer 中的所有 CanvasItem,不会影响所属 Viewport 中的其他 CanvasLayer 和 Window。
- CanvasLayer 视口跟随变换
The follow viewport transform is an automatically calculated transform, that is based on the Viewport's canvas transform and the CanvasLayer's follow viewport scale and can be used, if enabled, to achieve a pseudo-3D effect. It affects the same child nodes as the CanvasLayer transform.
- 视口全局画布变换
Viewport 还具有全局画布变换。这是主变换,会影响所有CanvasLayer和嵌套 Window 的变换,主要用于 Godot 的 CanvasItem 编辑器。
- 视口拉伸变换
最后,Viewport 拥有拉伸变换,用于调整视口的大小和拉伸。多分辨率 中介绍了 Window 中对该变换的用法,我们还可以通过 size 和 size_2d_override 手动设置 SubViewport 的拉伸变换。平移 translation、旋转 rotation 和偏斜 skew 为默认值,只有缩放 scale 可以是非默认值。
- 窗口位置
每个 Window 都还有一个 position,描述的是它在嵌入器中的位置。嵌入器可以是另一个 Viewport,也可以是操作系统窗口管理器。
- SubViewportContainer 收缩变换
SubViewportContainer 的 stretch 和 stretch_shrink 声明的是它所包含的 SubViewport 是否使用相对于容器大小的整数级缩放以及对应的缩放系数。