我正试图为一个基于这视频的模拟游戏创建一个3D摄像头,它展示了如何在团结中实现这一点。在将代码转换到GDScript时,我遇到了一个问题:我无法让摄像机旋转。下面是我对视频中脚本旋转部分的GDScript解释(时间戳: 8:50-10:10):
export(float) var rotation_amount = 1
export(Quat) var new_rotation
func _ready():
new_rotation = rotation
func _process(delta):
handle_movement_input(delta)
func handle_movement_input(delta):
if(Input.is_action_pressed("cam_rotate_left")):
new_rotation *= Quat(Vector3.UP * rotation_amount).get_euler()
if(Input.is_action_pressed("cam_rotate_right")):
new_rotation *= Quat(Vector3.UP * -rotation_amount).get_euler()
rotation = rotation.linear_interpolate(new_rotation, delta * movement_time)发布于 2021-10-27 18:48:54
类型
您可以声称new_rotation是一个Quat (export(Quat))。但是,您不仅要立即重写它(在_ready中),还要用一个Vector3覆盖它(rotation是一个表示欧拉角的Vector3 ):
func _ready():
new_rotation = rotation如果您创建了一个类型化的导出变量,戈多就会告诉您这个问题:
export var new_rotation:Quat是的,GDScript有类型化变量。用它们。
角度表示
如果您想使用四元数(如视频中所示),您可以获得这样的旋转Quat:
var new_rotation:Quat
func _ready():
new_rotation = transform.basis.get_rotation_quat()然后用乘法合成四元数,用slerp插值,最后用get_euler()进行插值。
顺便说一下,当您创建一个传递一个Quat的Vector3时,它被理解为欧拉角。这相当于统一的Quaternion.Euler (他们在视频中使用)。另外,调用to_euler可以将Quat转换为欧拉角,这使得使用Quat变得毫无意义,因为它只是从欧拉角度创建的(而这根本不是他们在视频中所做的)。
如果您想使用欧拉角,您应该添加它们,而不是乘以它们。
但是,由于您只关心垂直旋转,我在这里告诉您:使用float。保持简单。你把密码放哪儿了。
关于插值的注记
Vector3.linear_interpolate (或Quat.slerp或lerp)的权重介于0到1之间,如果为0,则得到原始值。如果是1,则得到新的值。
增加内插会平滑运动,但也会给你减速/减速的效果。所以你失去了敏锐的控制。
如果你平滑旋转并急剧停止,将角度乘以δ和一些缩放常数。也就是说,与其执行以下操作:Quat(Vector3.UP * rotation_amount),不如执行以下操作:Quat(Vector3.UP * rotation_amount * delta)。不做插值。
你把密码放哪儿了?
如果您要在Camera节点中编写该代码,它将无法工作。因为rotation改变了摄像机所看到的方向。这正是我们不想要的。相反,我们想绕着太空中的其他点旋转。
因此,将其设置在场景树中:
Pivot:Spatial
└ Camera您可以将Pivot (一个Spatial节点)放置在地面上,然后将Camera定位到空中观察它。然后将旋转逻辑放入Pivot中。因为Pivot只负责旋转,所以你可以用float来表示角度。生活简单简单(用lerp插值float)。
你能在一个节点上完成吗?是。我有一个过度设计的解决方案,正是这样做的其他地方 (包括解释为什么它不是最好的想法)。
https://stackoverflow.com/questions/69741116
复制相似问题