首页 > 编程知识 正文

c++报数游戏,unity生命周期函数执行顺序

时间:2023-05-05 12:09:22 阅读:156225 作者:4797

四元数的Unity API Quaternion类quaternion (四元数)用于计算unity的旋转。 这些计算紧凑、高效,不受通用锁的困扰,能够简单且迅速地进行球面插补。 在Unity内部,使用四元数表示所有旋转。

Quaternion基于多个,直观理解并不容易。 但是,很少需要访问或修改一个四元数的参数(x、y、z、w )。 在大多数情况下,您只需获取和使用现有旋转(例如,从变换),或使用四元数创建新旋转(例如,在两个旋转之间平滑插入)。

在大多数情况下,你可能会使用这些函数。

Quaternion.LookRotation,quaternion.angle quaternion.Euler quaternion.slerp quaternion.fromtorotation quaternion.iden

Unity的默认方向在深入理解API之前,需要明确方向、旋转是如何表示的基本概念。

Unity使用的是左手坐标系。 将世界坐标系和东南西北结合起来看,大致如下图所示。

缺省方向如下表所示。

坐标轴的对应方向x右(东)-x左)西) y上(y下z前)北)-Z后)南)假设以你自己的身体为例,你站在地上朝北。 此时是默认方向。 也就是说,Unity中的方向朝向z轴方向。 此时,x轴在东边,y轴对应正上方。 此时对应的欧拉角为[ 0,0,0 ],此时对应的前方矢量为[ 0,0,1 ],上方矢量为[ 0,1,0 ]。

在这里区分了左右上下前后的概念。 因为这些概念还支持Vector3和Transform类中的相应方向函数。

方向表示法欧拉角表示法用一组欧拉角表示旋转,XYZ的三个参数表示对应轴服从递归YZX的旋转。 因此,(0,90,90 )表示沿z轴旋转90度,然后沿y轴旋转90度。 详情请参照上述文章《【Unity编程】Unity中的欧拉旋转》。

在前方上方矢量定义法的编程中,大多数情况下需要明确指定方位。 要确定方向,请使用两个向量:向前向量和向上向量。 一个方向的前方和上方确定后,这个方向也完全确定。

例如,如果现在只提供了你现在面向北方的方向,这个方向完全确定吗? 很明显没有。 你的右侧躺在地上,是朝北还是朝北? 此时,需要另一个向量,即上方。 给定上方,这个方向完全确定。

上方需要严格拿出来吗? 在Unity中,我们往往不需要给出严格的向上。 例如,还有上面的例子,如果我朝北,我会先发出(0,0,1 )表示我的前方向量。 那么,是否可以表示出不是(0,0.5,0.5 )这样严格的上方向量的方向呢? 答案也很好。 因为这两个向量明显确定了一个方向。 虽然前方很严密,但实际的上方是通过前方向你给出的上方向量旋转90度得到的。 也就是说,提供(0,1,0 )作为上方向量和提供所有方向的向量(在下图的弧度范围内) (不包括z和-Z )的结果相同。

绕轴旋转定义法第三种定义旋转的方法是绕某指定轴旋转一定角度。 该方法还可以从默认方向(在这种情况下为向前z,向上y )出发,以确定沿指定轴方向旋转指定角度的相对旋转。 旋转后的前方和上方是确定的。 因此,该方法也可用于确定方向。

从a方向到b方向的相对旋转表示法中,也有从a方向到b方向的相对旋转的方法。 这表示旋转的相对变化。 例如,a表示(0,1,0 ),b表示) 0,0,1 ),也就是说相对旋转量表示原来的上方向前旋转了,这样的四元数也以欧拉角) 90,0,0 ),也就是说沿着x轴旋转了90度

请注意,上面的四种表示方法中,有些是显式的向上向量,而有些是只显式的向前向量。 为了清楚起见,它们都从默认向量出发,如果没有明确指定向上方向,则使用默认的向上方向,即y方向。

eulerAngles成员变量返回欧拉角、与当前四元数对应的欧拉角的this[int]使用类似数组和下标的形式,从四元数开始,四个四元数参数x、y、z、w分别为x、y 你最好更改四个参数,不要更改四元数。 否则,实际上不要更改四个参数:静态成员identity单位四元数,即默认的无旋转状态。 在这种情况下,它与世界坐标相同,以z表示前方,y表示上方的成员函数的形式解释voidset。 (floatnew_x,float new_y,float new_z,float new_w )设置x,float new_w ),其功能与this[]相同Vector3 toDirection )设置为voidsetlookrotation (vector3to direction ),这是静态函数fromtorotation的结果

ookRotation的结果void ToAngleAxis(out float angle, out Vector3 axis)设置成静态函数AngleAxis的结果

说明:成员函数几个set方法多用于将当前四元数设置成目标四元数,目标四元数的构建方法与对应名称的静态函数相同。

静态函数 函数形式解释static float Angle(Quaternion a, Quaternion b)计算两个四元数前方矢量之间的夹角度数static Quaternion AngleAxis(float angle, Vector3 axis)构建一个四元数,它表示沿着一个轴旋转固定角度,即上述表示法③static float Dot(Quaternion a, Quaternion b)计算两个四元数之间的点积,返回一个标量,这个函数一般用不到,它的点积不代表什么具体的物理含义,具体定义方法见我的前述文章static Quaternion Euler(float x, float y, float z)构建一个四元数,它用欧拉旋转表示,即上述表示法①static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection)构建一个四元数,它表示从指向fromDirection方向到指向toDirection方向的相对旋转量,见上述表示法④static Quaternion Inverse(Quaternion rotation)构建一个四元数,它是指定的四元数的逆,也就是逆向旋转,比如原四元数表示相对+X轴旋转了90度,那么此函数结果就是相对+X轴旋转了-90度static Quaternion Lerp(Quaternion a, Quaternion b, float t)构建一个四元数,表示从四元数a到b的球面插值,所谓的插值也就是中间旋转量,从a作为起点,此时对应t为0,到b为终点,此时对应t为1。当t取0-1之间的小数时,就代表了中间的插值结果。这个方法与Slerp相同,计算速度快,但是精度低,如果相对旋转变化量很小,则效果不理想static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float t)与Lerp相同,区别是,Lerp的t值会被钳制在[0,1]之间,而此方法则不会,t允许超出计算static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up)构建一个四元数,使用前方上方矢量确定朝向,也就是上述表示法②static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta)构建一个四元数,表示从一个四元数from(的前方)向着另外一个四元数(的前方)旋转,但不能超出指定的角度,也就是如果两个前方矢量夹角超过指定角度,则旋转到达指定角度时就停止,若是夹角本身不足的话,则结果直接为目标四元数to,与上述表示法④的意思很接近static Quaternion Slerp(Quaternion a, Quaternion b, float t)球面插值,与Lerp功能相同,t值也被钳制,计算精度高,但是速度相对较慢static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float t)与Slerp功能相同,只是t值不被钳制,允许超出计算static Quaternion operator * (Quaternion lhs, Quaternion rhs)乘法运算符重载,当表示两个连续的旋转时,可以使用lhs * rhs的形式得出连续旋转的结果,lhs为左值,rhs为右值。注意左值是先进行的旋转,叠加右值旋转。用法示例:lhs = lhs * rhs;static Vector3 operator *(Quaternion rotation, Vector3 point)乘法运算符重载,表示对一个矢量point施加旋转rotation,得出旋转后的结果矢量。用法示例:Vector3 result=rotation * point 验证前方上方矢量表示法

为了验证前方上方矢量表示法的实际上方会重新计算,我设计了以下小实验。

在场景中设置三个物体,它们的朝向是打乱的,从左到右分别对应1、2、3。可以使用以下代码将三个物体朝向调整为一致。

//前方上方矢量界定法的实际上方会重新计算 m_t1.transform.rotation = Quaternion.LookRotation(Vector3.forward, Vector3.up); m_t2.transform.rotation = Quaternion.LookRotation(Vector3.forward, new Vector3(0,0.5f,-0.5f)); m_t3.transform.rotation = Quaternion.LookRotation(Vector3.forward, new Vector3(0,0.5f,0.5f));

在start方法中执行上述代码后,如下:

三个物体朝向是一致的,也就说明了上方矢量确实是进行了重新计算。

总结几种表示方法

下面使用代码总结几种表示法,对应同样的四元数,大致有四种表示方法。

//旋转量的4种表示形式 Quaternion q1=Quaternion.Euler(90, 0, 0); Quaternion q2 = Quaternion.LookRotation(Vector3.down ,Vector3.forward); Quaternion q3 = Quaternion.AngleAxis(90,Vector3.right); Quaternion q4 = Quaternion.FromToRotation(Vector3.up, Vector3.forward); showQ("q1",q1); showQ("q2",q2); showQ("q3",q3); showQ("q4",q4);

它们的输出结果是:

也就是说,这几种形式表示的四元数结果完全相同。

将四元数旋转应用于子弹射击示例

当枪管转动起来,子弹仍然沿着正确的朝向发射出去,可以使用很简单的几句话,修改之前的代码后如下:

Bullet_2 bullet = m_compPool.takeUnit<Bullet_2>(); //发射时,将子弹的初始位置为枪口的当前位置 bullet.m_transform.position = m_transform.position; //将子弹的初始化旋转设置为指向当前枪口前方 bullet.m_transform.rotation = Quaternion.LookRotation(m_transform.forward);

本节代码可点此下载。觉得有用你就点个赞。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。