如何在 godot 编辑器中编辑矢量类?

问题描述

我正在使用 godot 编辑器从网站创建简单的游戏。问题出在那个网站上,他们告诉他们使用名为“move_toward”的函数,但该函数在我使用的编辑器的 vector 类中不可用。我在 github 中找到了一个解决方案,其中提到我应该将“move_toward”函数添加到 vector3.cpp 文件中,但我无法在项目的任何地方找到该文件。如何从 godot 编辑器中查找和编辑该 vector3 文件

解决方法

Godot 引擎的 Web 版本有很多限制,如果您可以在您的设备上下载 Godot Limitations 会更好。
我已经搜索过您是否可以编辑 Godot 的网络文件,但我找不到任何相关信息。在 Godot 的可执行版本中,已经有一个内置函数“move_toward”以及更多您无法在 Web 编辑器中访问的功能。

,

您无法从编辑器中编辑 vector3.cpp...因为您没有它!

如果你真的想编辑vector3.cpp,你可以从github仓库下载Godot源码,并进行自定义构建。见Compiling

当然,您会想要 3.x 分支之一。除了,好吧,如果你下载并编译 3.3 分支,它已经有 move_toward。您不妨下载一个官方版本。

但是,要回答如何查找和编辑 vector3.cpp:它位于“godot/core/math/”文件夹中,在 vector3.h 旁边。可以在vector3.cpp中添加一个函数,不要忘记在头文件中声明。


函数 move_toward 是在 Godot 3.2 中添加的(撰写本文时的当前版本是 Godot 3.3.2)。如果您需要此功能,更简单的解决方案是下载 Godot 的更新版本。

我不知道 Godot Web 编辑器是否与此相关。但是,它也在 3.3.2 版本上,并且 move_toward 在那里可用(我刚刚检查过),所以应该没问题。


话虽如此,如果 - 无论出于何种原因 - 您必须使用旧版本的 Godot,我们也可以模拟 move_toward

此代码:

var result:Vector3 = v.move_toward(to,delta)

相当于:

var result:Vector3 = to
if v != to and v.distance_to(to) < delta:
    result = v + delta * v.direction_to(to)

也就是说,向量 v 在从 deltav 的方向上偏移距离 to

我们检查 v.distance_to(to) < delta 以确保我们不会超过第二个向量。我们检查 v != to 因为当向量相等时不需要计算。 实际上,还有一点点,我们会处理的。

上面的代码等价于:

var result:Vector3 = to
var vd = to - v
if v != to and vd.length() < delta:
    result = v + delta * vd.normalized()

在那里我计算了 vto 之间的差异,并用它来获得距离 (vd.length()) 和方向 (vd.normalized())。

相当于:

var result:Vector3 = to
var vd = to - v
var len = vd.length()
if v != to and len < delta:
    result = v + delta * (vd/len)

因为归一化向量就是向量除以它的长度。

正如你所看到的,如果两个向量相等(一个向量到另一个向量的距离为零),那将是除以零。

我们可以改为检查零:

var result:Vector3 = to
var vd = to - v
var len = vd.length()
if len > 0 and len < delta:
    result = v + delta * (vd/len)

如果我们使用三元运算符条件,它看起来像这样:

var vd = to - v
var len = vd.length()
var result = v + delta * (vd/len) if len > 0 and len < delta else to

您可以将其与 the source code for move_toward 进行比较:

Vector3 Vector3::move_toward(const Vector3 &p_to,const real_t p_delta) const {
    Vector3 v = *this;
    Vector3 vd = p_to - v;
    real_t len = vd.length();
    return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
}

条件被翻转。并且他们检查 len 是否与 epsilon(一些非常小的数字)相比较,而不是与零相比较。然而,希望你能看到它完成了同样的事情。

当然,我们也可以将我们的版本包装在一个函数中。也许把它当作一个辅助类:

class_name Vector3Helper extends Object

static func move_toward(v:Vector3,to:Vector3,delta:float) -> Vector3:
    var vd = to - v
    var len = vd.length()
    if len > 0 and len < delta:
        return v + delta * (vd/len)

    return to

然后而不是编写此代码:

var result:Vector3 = v.move_toward(to,delta)

您可以编写此代码:

var result:Vector3 = Vector3Helper.move_toward(v,to,delta)