GODOT内部如何使用线性插值

How to use linear interpolation inside GODOT

我正在尝试使用线性插值进行平滑的相机移动,但看起来我无法通过它传递 Delta.. 不确定这是否是问题所在。相反,它只是捕捉它的位置

CameraBase只是一个空间3D,实际的camera Node是他的子节点

func _unhandled_input(event):
    if event.is_action_released("ui_focus_next"):
        i += 1
        if i >= allies.size():
            i = 0
        pointer.translation = allies[i].translation + Vector3(0,5,0)
        focus_camera(allies[i])


func focus_camera(target):
    var move = $CameraBase.translation.linear_interpolate(target.translation, CAMERA_SPEED)
    $CameraBase.set_translation(move)

如果使用 Input 而不是 unhandle 会工作得很好,但我读到这不是正确的方法

让我们看看 linear_interpolate:

的文档

Vector3 linear_interpolate ( Vector3 to, float weight )

Returns the result of the linear interpolation between this vector and to by amount t. weight is on the range of 0.0 to 1.0, representing the amount of interpolation.

如你所见,第二个参数是权重。如果它是 0.0,你会得到一个没有修改的向量。如果它是 1.0,您将获得作为第一个参数传递的矢量。 0.0 和 1.0 之间的任何值都会在两者之间给出一个点。

我们可以在 "Vector Interpolation" 中确认这一点:

Here is simple pseudo-code for going from point A to B using interpolation:

func _physics_process(delta):
   t += delta * 0.4

   $Sprite.position = $A.position.linear_interpolate($B.position, t)

It will produce the following motion:

重申一下,0.0 的 weight 给你第一个位置,weight 1.0 给你第二个位置。对于运动,您应该传递一个随时间从 0.0 到 1.0 不等的值。

这就是示例使用 _physics_processdelta 的原因(顺便说一句,以秒为单位)。每个物理框架,Godot 调用 _physics_process,其中代码使用自上次 Godot 调用 [=] 以来经过的时间计算 weight(在本例中为 t 变量)的新值20=](即delta)。

如果你想用linear_interpolate来创造动感,你必须以类似的方式使用它。从 _process_physics_process 或处理程序 Timer 或类似解决方案的 timeout 信号调用它。


但是,我将建议一种完全不同的方法:使用 Tween 节点。

您可以添加一个 Tween 节点并将其用于插值。您可以在编辑器中添加节点,并像这样引用:

onready var tween:Tween = $Tween

或者您可以使用如下代码创建它:

var tween:Tween

func _ready():
    tween = Tween.new()
    add_child(tween)

无论哪种方式,一旦你有了 Tween 的变量,我们就可以像这样使用它:

    tween.interpolate_property($CameraBase, "translation",
        $CameraBase.translation, target.translation, duration)

可以在_input_unhandled_input或任何地方,没关系。也不需要 delta。而且你不需要多次调用它(如果不清楚的话,你必须用 linear_interpolate 来获得运动)。

代码告诉 Tween 节点插入 $CameraBasetranslation 属性。这些值将从 $CameraBase.translation 的当前值变为 target.translation。动作需要 duration 秒。

我们可以调整它以使用速度:

    var distance = $CameraBase.translation.distance_to(target.translation)
    var duration = distance / CAMERA_SPEED
    tween.interpolate_property($CameraBase, "translation",
        $CameraBase.translation, target.translation, duration)

这假设 CAMERA_SPEED 是单位每秒。

另外别忘了打电话给start:

    tween.start()

还有,作为奖励,interpolate_property and the other interpolation Tween methods allow you to specify the kind of interpolation (it is linear by default), by passing a TransitionType and a EaseType

顺便说一句,你可以检查is_active to find out if the Tween is running, and there are also stop and stop_all方法。