【问题标题】:3D rotation in Godot (GDScript) using Euler angles使用欧拉角在 Godot (GDScript) 中进行 3D 旋转
【发布时间】:2021-10-27 15:07:29
【问题描述】:

我正在尝试为基于this 视频的模拟游戏创建 3D 相机,该视频展示了如何在 Unity 中进行操作。在将代码转换为 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)

【问题讨论】:

    标签: 3d quaternions godot euler-angles


    【解决方案1】:

    类型

    您声称new_rotationQuat (export(Quat))。但是您不仅要立即覆盖它(在 _ready 中),还要使用 Vector3 覆盖它(rotation 是代表欧拉角的 Vector3):

    func _ready():
        new_rotation = rotation
    

    如果你创建了一个类型化的导出变量,Godot 会告诉你这个问题:

    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 时,它被理解为欧拉角。这相当于 Unity 的Quaternion.Euler(他们在视频中使用)。此外,调用to_euler 会将Quat 转换为欧拉角,这使得使用Quat 毫无意义,因为它只是从欧拉角创建的(这根本不是他们在视频中所做的)。


    如果您想使用欧拉角,您应该将它们相加而不是相乘。


    但是,由于您只关心围绕垂直方向的旋转,我在这里告诉您:使用float。把事情简单化。关键你把代码放在哪里。


    插值说明

    Vector3.linear_interpolate(或Quat.slerplerp)的权重是一个介于0和1之间的值。如果是0,则得到原始值。如果为 1,则获得新值。

    添加插值会使运动变得平滑,但也会给您带来减速/减速效果。所以你失去了敏锐的控制力。

    如果您平滑旋转并急停,请将角度乘以 delta 和一些缩放常数。也就是说,不要这样做:Quat(Vector3.UP * rotation_amount) 你这样做:Quat(Vector3.UP * rotation_amount * delta)。并且不进行插值。


    你把代码放在哪里?

    如果您在Camera 节点中编写该代码,它将无法工作。因为rotation 改变了相机的观察方向。这正是我们不想要的。相反,我们希望围绕空间中的其他点旋转。

    因此,在场景树中进行设置:

    Pivot:Spatial
    └ Camera
    

    您可以将Pivot(一个Spatial 节点)放在地面上,然后将Camera 放置在空中观察它。你把旋转逻辑放在Pivot 中。由于 Pivot 只负责旋转,因此您可以使用 float 作为角度。生活轻松简单(使用lerp 插入float)。


    你能在一个节点上做吗?是的。我有一个过度设计的解决方案,完全可以做到elsewhere(包括解释为什么它不是最好的主意)。

    【讨论】:

      猜你喜欢
      • 2019-10-13
      • 2019-07-07
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-28
      相关资源
      最近更新 更多