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_process
和 delta
的原因(顺便说一句,以秒为单位)。每个物理框架,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
节点插入 $CameraBase
的 translation
属性。这些值将从 $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
方法。
我正在尝试使用线性插值进行平滑的相机移动,但看起来我无法通过它传递 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_process
和 delta
的原因(顺便说一句,以秒为单位)。每个物理框架,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
节点插入 $CameraBase
的 translation
属性。这些值将从 $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
方法。