Input 如何在GODOT中使用线性插值
我正在尝试使用线性插值来平滑相机移动,但看起来我无法通过Delta。。不确定这是否是问题所在。相反,它只是捕捉它的位置 CameraBase只是一个空间3D,而实际的摄影机节点是其子节点Input 如何在GODOT中使用线性插值,input,timedelta,godot,linear-interpolation,Input,Timedelta,Godot,Linear Interpolation,我正在尝试使用线性插值来平滑相机移动,但看起来我无法通过Delta。。不确定这是否是问题所在。相反,它只是捕捉它的位置 CameraBase只是一个空间3D,而实际的摄影机节点是其子节点 func _unhandled_input(event): if event.is_action_released("ui_focus_next"): i += 1 if i >= allies.size(): i = 0
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)
如果使用输入而不是unhandle,它会工作得很好,但是我读到这不是正确的方法,让我们看看以下文档:
Vector3线性插值(Vector3到,浮动权重)
返回此向量与to之间的线性插值结果(按数量t)。权重的范围为0.0到1.0,表示插值量
如您所见,第二个参数是权重。如果为0.0,则得到一个未经修改的向量。如果为1.0,则得到作为第一个参数传递的向量。任何介于0.0和1.0之间的值都将给出介于两者之间的一个点
我们可以在以下文件中确认这一点:
下面是使用插值从A点到B点的简单伪代码:
func _physics_process(delta):
t += delta * 0.4
$Sprite.position = $A.position.linear_interpolate($B.position, t)
它将提出下列动议:
重申一下,0.0的权重
为第一个位置,而权重
1.0为第二个位置。对于运动,您要传递的值随时间从0.0到1.0变化
这就是为什么该示例使用\u physics\u process
和delta
(顺便说一下,以秒为单位)。每个物理帧,Godot调用\u physics\u process
,其中代码使用自上次Godot调用\u physics\u process
(即delta
)以来经过的时间来计算权重的新值(本例中为t
)
如果要使用linear\u interpolate
创建运动,则必须以类似的方式使用它。从\u进程
,\u物理过程
,或从处理程序调用计时器
或类似解决方案的超时
信号
但是,我将建议一种完全不同的方法:使用节点
您可以添加一个Tween
节点,并将其用于插值。您可以在编辑器中添加节点,并采用如下引用:
onready var tween:Tween = $Tween
var tween:Tween
func _ready():
tween = Tween.new()
add_child(tween)
tween.interpolate_property($CameraBase, "translation",
$CameraBase.translation, target.translation, duration)
或者,您可以通过以下代码创建它:
onready var tween:Tween = $Tween
var tween:Tween
func _ready():
tween = Tween.new()
add_child(tween)
tween.interpolate_property($CameraBase, "translation",
$CameraBase.translation, target.translation, duration)
无论哪种方式,一旦你有了一个Tween变量,我们可以这样使用它:
onready var tween:Tween = $Tween
var tween:Tween
func _ready():
tween = Tween.new()
add_child(tween)
tween.interpolate_property($CameraBase, "translation",
$CameraBase.translation, target.translation, duration)
可以是\u输入
或\u未处理的输入
或任何地方,这都无关紧要。它也不需要delta
。而且你不需要多次调用它(如果不清楚的话,这就是用linear\u interpolate
获得运动所必须做的)
代码告诉Tween
节点插入$CameraBase
的translation
属性。这些值将从$CameraBase.translation
的当前值变为target.translation
。运动将持续秒
我们可以调整它以使用速度:
var distance = $CameraBase.translation.distance_to(target.translation)
var duration = distance / CAMERA_SPEED
tween.interpolate_property($CameraBase, "translation",
$CameraBase.translation, target.translation, duration)
这假定摄像机的速度为每秒单位
另外,作为奖励,和其他插值Tween
方法允许您通过传递a和a来指定插值的类型(默认情况下是线性的)
顺便说一句,你可以检查一下Tween是否正在运行,并且有很多方法。也许相机的速度太快了,你有没有尝试过不同的数字和未处理的输入是有点奇怪,尝试使用正常的物理过程。这真的很方便,Tween的工作性能很好,答案中唯一缺少的是将``tween.start()``放在tween代码的末尾