如何设置一个变量以包含旋转度?
我正在尝试在我正在构建的游戏中实现倾斜的技工。为此,我想设置一个变量以充当旋转度的默认数(理想情况下x0
,y0
和z0
)和一个用于向右倾斜的字符的旋转度(理想的x0.6
,y0
和z0
)。
这是我的代码(对于上下文,将此脚本连接到一个空间节点,称为Upperbody
):
extends Spatial
const LEAN_LERP = 5
export var default_degrees : Vector3
export var leaning_degrees : Vector3
func _process(delta):
if Input.is_action_pressed("LeanRight"):
transform.origin = transform.origin.linear_interpolate(leaning_degrees, LEAN_LERP * delta)
else:
transform.origin = transform.origin.linear_interpolate(default_degrees, LEAN_LERP * delta)
if Input.is_action_pressed("LeanLeft"):
transform.origin = transform.origin.linear_interpolate(-leaning_degrees, LEAN_LERP * delta)
else:
transform.origin = transform.origin.linear_interpolate(default_degrees, LEAN_LERP * delta)
如您所见,我都有default_degrees
and code> leaning_degrees '类型设置为vector3
,而不是旋转度等效的(当前未知)。
我的问题是:如何设置一个变量以包含旋转度?
谢谢。
I'm trying to implement a leaning mechanic in a game that I'm building. To do that I want to set one variable to act as the default number of rotation degrees (ideally x0
, y0
, and z0
), and one for the rotation degrees of a character that is leaning to the right (ideally x0.6
, y0
, and z0
).
Here's my code (for context, this script is attached to a Spatial node called UpperBody
):
extends Spatial
const LEAN_LERP = 5
export var default_degrees : Vector3
export var leaning_degrees : Vector3
func _process(delta):
if Input.is_action_pressed("LeanRight"):
transform.origin = transform.origin.linear_interpolate(leaning_degrees, LEAN_LERP * delta)
else:
transform.origin = transform.origin.linear_interpolate(default_degrees, LEAN_LERP * delta)
if Input.is_action_pressed("LeanLeft"):
transform.origin = transform.origin.linear_interpolate(-leaning_degrees, LEAN_LERP * delta)
else:
transform.origin = transform.origin.linear_interpolate(default_degrees, LEAN_LERP * delta)
As you can see, I have both default_degrees
and leaning_degrees
' types set to Vector3
instead of the (currently unknown) equivalent for rotational degrees.
My question is this: how do I set a variable to contain rotational degrees?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有用于欧拉角的专用类型。取而代之的是,您将使用…鼓卷…
vector3
。实际上,如果您看到 rotation_degrees 属性,您会发现它被定义为
vector3
。当然,这并不是表示旋转/方向的唯一方法。最终,转换有两个部分:
vector3
称为Origin
代表转换。基础
称为基础
,该基础代表转换的其余部分(旋转,缩放和反射,以及剪切或偏斜)。一个
基础
可以想到vector3
的三人,每个代表坐标系的轴之一。考虑基础
的另一种方法是3乘3矩阵。因此,无论您用来代表旋转或方向的用品最终都将转换为
基础
(然后替换或与转换的Basic
组成)。现在,您想插入旋转,对吗?欧拉角对插值不利。相反,您可以
transform.interpalle_with_with
)插值:变换(变换
)。基础
使用basis.slerp
)。quat
使用quat.slerp
)。另一方面,Euler角度非常适合输入。在这种特殊情况下,这意味着与在检查员中写下这些数字相比,将头缠绕在数字上是相对容易的。
因此,我们有两个途径:
变换
,基础
或quat
。转换
,BaseN
或quat
。Euler与
Quat
quat
具有一个构造函数,该构造器为欧拉角(Euler Angles)带有一个构造函数。捕获的是,它是弧度中的欧拉角。因此,我们需要将学位转换为弧度(我们可以用deg2rad
)。像这样:或者,您可以做到这一点:
我们还需要从转换中获取当前的四元素:
插入它们:
并替换Quat:
上线假设转换仅是旋转,缩放和翻译。如果我们想保持偏斜,可以做到这一点:
在下一节中解释。
通知我们最终将
quat
转换为base /代码>。因此,也许我们最好完全避免四次季节。
Euler与
基础的角度
基础
类还具有一个构造函数,其工作函数的工作原理,就像我们在quat quat
中找到的构造函数一样。因此,我们可以做到这一点:这次捕获是
基础
不仅代表旋转。因此,如果这样做,我们将失去缩放率(以及任何其他转换基础
具有)。我们可以保留这样的缩放:当然,当前的
基础
是:我们这样插值:
我们替换了
基础
这样:老实我对上述方法不满意。我将向您展示一种让
基础
您插值仅用于旋转的方法(因此,它可以保留任何偏斜的原始基础
不仅是其比例)它更多的参与。让我们再次从这里开始:我们不会扩展,而是要获得一个
基础
,那只是当前一个的旋转。我们可以通过从基础
转到quat
和back:我们以与以前相同的方式进行操作来做到这一点:
但是要替换
基础
我们要替换。保留有关旧的所有内容,不是旋转。换句话说,我们将要:以
基础
:进行
删除其旋转(即与旋转的倒数构成):
与:
相同
这就是我们设置的:
我已经测试了以确保构图顺序正确。而且,是的,上面显示的用于保存偏斜的代码是基于此
的
。创建
转换
从Euler角度是通过基础
:我们可以使用此方法保留刻度和翻译:
如果您想同时插入翻译,则可以设置您的目标位置,而不是
transform.origin
。当前转换是:
我们这样插入它们:
我们可以设置:
如果我们嵌入式这些变量,我们有这:
如果要保留偏斜,请使用
基础
方法。euler Angles的替代输入
我们发现interpolating变换实际上是非常非常简单的。有没有一种方法可以轻松输入
变换
? 修辞问题。我们可以在场景中添加一些position3d
。定位并旋转它们(即使position3d
没有大小),然后将它们缩小(甚至比较),然后使用transform
。我们可以使
position3d
您的空间
的孩子(这有点奇怪,但对此不太认真)或兄弟姐妹。无论如何,我们的想法是,我们将从这些position3d
中采取变换
,并使用它来插入空间
。它的代码与以前相同:实际上,当我们在其中时,为什么没有三个
position3d
:您根据输入选择要使用的目标,然后将其插值:
将节点路径放在我离开的节点路径
...
。。然后, Euler Angles版本:
There is no dedicated type for Euler angles. Instead you would use … drum roll …
Vector3
.In fact, if you see the
rotation_degrees
property, you will find it is defined as aVector3
.That, of course, isn't the only way to represent rotations/orientations. Ultimately, the Transform has two parts:
Vector3
calledorigin
which represents the translation.Basis
calledbasis
which represent the rest of the transformation (rotation, scaling and reflection, and shear or skewing).A
Basis
can be thought of a trio ofVector3
each representing one of the axis of the coordinate system. Another way to think ofBasis
is as a 3 by 3 matrix.Thus whatever you use to represent rotations or orientations will ultimately be converted to a
Basis
(and then either replace or be composed with theBasis
of the transform).Now, you want to interpolate the rotations, right? Euler angles aren't good for interpolation. Instead you could interpolate:
Transform
using interpolate_withTransform.interpolate_with
).Basis
usingBasis.slerp
).Quat
usingQuat.slerp
).On the other hand, Euler angles are good for input. In this particular case that means it is relative easy to wrap your head around what the numbers mean compared to writing any of these in the inspector.
Thus, we have two avenues:
Transform
,Basis
orQuat
.Transform
,Basis
orQuat
.Euler angle to
Quat
The
Quat
has a constructor that takes a vector for Euler angles. The catch is that it is Euler angles in radians. So we need to convert degrees to radians (which we can do withdeg2rad
). Like this:Alternatively, you could do this:
We also need to get the current quaternion from the transform:
Interpolate them:
And replace the quat:
The above line assumes the transformation is only rotation, scaling, and translation. If we want to keep skewing, we can do this:
The explanation for that is in the below section.
Notice we ended up converting the
Quat
to aBasis
. So perhaps we are better off avoiding quaternions entirely.Euler angle to
Basis
The
Basis
class also has a constructor that works like the one we found inQuat
. So we can do this:The catch this time is that
Basis
does not only represent rotation. So if we do that, we are losing scaling (and any other transformation theBasis
has). We can preserve the scaling like this:Ah, of course, the current
Basis
is this:We interpolate like this:
And we replace the
Basis
like this:To be honest, I'm not happy with the above approach. I'll show you a way to have the
Basis
you interpolate be only for rotation (so it can preserve any skewing the originalBasis
had, not only its scale), but it is a little more involved. Let us start here again:And we will not scale that, instead we want to get a
Basis
that is only the rotation of the current one. We can do that by going fromBasis
toQuat
and back:We interpolate the same way as before:
But to replace the
Basis
we want to keep everything about the oldBasis
that wasn't the rotation. In other words we are going to:Take the
Basis
:Remove its rotation (i.e. compose it with the inverse of its rotation):
Which is the same as:
And apply the new rotation:
And that is what we set:
I have tested to make sure the composition order is correct. And, yes, code for preserving skewing with
Quat
I showed above is based on this.Euler angle to
Transform
The way to create a
Transform
from Euler angles is via aBasis
:We could preserve scale and translation with this approach:
If you want to interpolate translation at the same time, you can set your target position instead of
transform.origin
.The current transform is, of course:
We interpolate them like this:
And we can set that:
If we inline these variables, we have this:
If you want to preserve skewing, use the
Basis
approach.Alternative input to Euler angles
We have found out that interpolating transforms is actually very easy. Is there a way to easily input a
Transform
? Rhetorical question. We can add somePosition3D
to the scene. Position and rotate them (and even scale them, even thoughPosition3D
has no size), and then use theTransform
from them.We can make the
Position3D
children of yourSpatial
(which is somewhat odd, but don't think too hard about it), or as sibling. Regardless, the idea is that we are going to take thetransform
from thesePosition3D
and use it to interpolate thetransform
of yourSpatial
. It is the same code as before:In fact, while we are at it, why not have three
Position3D
:Then you pick which target to use depending on input, and interpolate to that:
Put the node paths where I left
...
.Ok, Ok, here is one of the Euler angles versions: