Godot/Gdscript 旋转 + 从本地翻译到世界 space

Godot/Gdscript rotate + translate from local to world space

我有一个 RigidBody 节点 (3D),我想得到,在全局坐标 中,“目标”的位置,给定:

看起来很简单....先平移,再旋转,或者如果不行,先旋转,再旋转。

A 到 B -> 如果我只应用翻译,它可以工作,没问题:

target = global_transform.translated(5 * Vector3.FORWARD).origin

但是如果我想从 B 到 C,它会失败:它看起来像围绕世界原点旋转

在过去的几个小时里我尝试了很多东西并阅读了很多关于 Transform 的文章,现在我放弃了。那么...你会怎么做?

又过了1个小时,我终于找到了东西,但是有点难看:

target = to_global(to_local(transform.translated(3 * Vector3.FORWARD).origin).rotated(Vector3.UP, rot))

如果你有更好的,请添加你的答案!

我们将在 XZ 平面上通过极坐标(即“旋转”角度和距离,我称之为“d”)定义相对于您的 RigidBody(3D) 的位置。

为了清楚起见,我们将在RigidBody(3D)的局部space定义它,然后将它移动到全局坐标。

我们可以使用转换。如果您需要保持旋转,您会这样做。虽然它需要更多的工作。或者,您可以 仅使用向量 。哪个更容易。

以下是执行此操作的不同方法。


使用变换

局部变换

我们这样定义旋转和平移变换:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)

顺便说一句,使用这些方法时顺序无关紧要。结果是这样的:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot) * Transform.IDENTITY.translated(d * Vector3.FORWARD)

在给定距离处绕原点旋转。但是,如果您这样做:

var t = Transform.IDENTITY.translated(d * Vector3.FORWARD) * Transform.IDENTITY.rotated(Vector3.UP, rot)

你得到一个向前移动,然后在适当位置旋转的变换。


全局变换

对于全局变换,我们可以使用它应该是相对于 RidigBody(3D) 的事实,并且我们有它的全局变换:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var global_t = global_transform * t

请注意,这将应用旋转、缩放等。如果你只想要全局翻译,你可以这样做:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var global_t = Transform.IDENTITY.translated(global_transform.origin) * t

不,t.translated(global_transform.origin) 不是一回事。当您使用 translated 时,它位于您调用它的变换的本地坐标中。


本地位置

如你所知,我们可以使用变换的origin

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var v = t.origin

全球排名

你可以使用 to_global:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var v = t.origin
var global_v = to_global(v)

或者我们可以从全局变换中获取 origin

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var global_t = global_transform * t
var global_v = global_t.origin

如果只想要全局翻译,可以添加global_transform.origin:

var t = Transform.IDENTITY.rotated(Vector3.UP, rot).translated(d * Vector3.FORWARD)
var v = t.origin
var global_v = global_transform.origin + v

仅使用向量

本地位置

如果您只关心位置,我们可以完全不进行变换:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP, rot)

全球排名

当然,您可以使用 to_global:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP, rot)
var global_v = to_global(v)

同样,如果您只想要全局翻译,您可以添加 global_transform.origin:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP, rot)
var global_v = global_transform.origing + v