3d - 使用欧拉角在 Godot (GDScript) 中进行 3D 旋转
问题描述
我正在尝试根据该视频为模拟游戏创建一个 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)
解决方案
类型
您声称new_rotation
是Quat
( export(Quat)
)。但是您不仅要立即覆盖它(在 中_ready
),还可以用 a 覆盖它Vector3
(rotation
是Vector3
表示欧拉角的 a):
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
传递 aVector3
时,它被理解为欧拉角。这相当于 Unity 的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
它只负责旋转,因此您可以使用 afloat
作为角度。生活轻松简单(用于lerp
插值float
)。
你能在一个节点上做吗?是的。我有一个过度设计的解决方案,可以在其他地方完全做到这一点(包括解释为什么它不是最好的主意)。
推荐阅读
- ocaml - Base 弃用了一些有用的函数
- c++ - 我收到运行时错误提示“运行时错误:引用绑定到空指针”
- themes - 如何为 CodeBlocks 更改或添加深色主题?
- three.js - 三个JS在知道原点和距离的平面上找到一个点
- python - urllib.error.HTTPError: HTTP Error 403: Forbidden in my web scraping
- php - 如何使用 Algolia Instantsearch 获得随机结果
- esp8266 - 波特率更改后 ESP8266 不工作
- node.js - 如何在 reactjs 中更新我的评论数组?
- python - 堆叠和重塑 Numpy 数组
- powershell - Powershell 让 IE 自动化 | 填写付款表格问题