首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于欧拉角的戈多三维旋转(GDScript)

基于欧拉角的戈多三维旋转(GDScript)
EN

Stack Overflow用户
提问于 2021-10-27 15:07:29
回答 1查看 1.5K关注 0票数 0

我正试图为一个基于视频的模拟游戏创建一个3D摄像头,它展示了如何在团结中实现这一点。在将代码转换到GDScript时,我遇到了一个问题:我无法让摄像机旋转。下面是我对视频中脚本旋转部分的GDScript解释(时间戳: 8:50-10:10):

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-27 18:48:54

类型

您可以声称new_rotation是一个Quat (export(Quat))。但是,您不仅要立即重写它(在_ready中),还要用一个Vector3覆盖它(rotation是一个表示欧拉角的Vector3 ):

代码语言:javascript
复制
func _ready():
    new_rotation = rotation

如果您创建了一个类型化的导出变量,戈多就会告诉您这个问题:

代码语言:javascript
复制
export var new_rotation:Quat

是的,GDScript有类型化变量。用它们。

角度表示

如果您想使用四元数(如视频中所示),您可以获得这样的旋转Quat

代码语言:javascript
复制
var new_rotation:Quat

func _ready():
    new_rotation = transform.basis.get_rotation_quat()

然后用乘法合成四元数,用slerp插值,最后用get_euler()进行插值。

顺便说一下,当您创建一个传递一个QuatVector3时,它被理解为欧拉角。这相当于统一的Quaternion.Euler (他们在视频中使用)。另外,调用to_euler可以将Quat转换为欧拉角,这使得使用Quat变得毫无意义,因为它只是从欧拉角度创建的(而这根本不是他们在视频中所做的)。

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

但是,由于您只关心垂直旋转,我在这里告诉您:使用float。保持简单。你把密码放哪儿了。

关于插值的注记

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

增加内插会平滑运动,但也会给你减速/减速的效果。所以你失去了敏锐的控制。

如果你平滑旋转并急剧停止,将角度乘以δ和一些缩放常数。也就是说,与其执行以下操作:Quat(Vector3.UP * rotation_amount),不如执行以下操作:Quat(Vector3.UP * rotation_amount * delta)。不做插值。

你把密码放哪儿了?

如果您要在Camera节点中编写该代码,它将无法工作。因为rotation改变了摄像机所看到的方向。这正是我们不想要的。相反,我们想绕着太空中的其他点旋转。

因此,将其设置在场景树中:

代码语言:javascript
复制
Pivot:Spatial
└ Camera

您可以将Pivot (一个Spatial节点)放置在地面上,然后将Camera定位到空中观察它。然后将旋转逻辑放入Pivot中。因为Pivot只负责旋转,所以你可以用float来表示角度。生活简单简单(用lerp插值float)。

你能在一个节点上完成吗?是。我有一个过度设计的解决方案,正是这样做的其他地方 (包括解释为什么它不是最好的想法)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69741116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档