Unity 以一定角速度转向动态目标的旋转方式对比
2021-04-18 07:27
标签:缺陷 坐标 oid 简洁 范围 直接 简单 obj orm 1.欧拉角旋转 public void Rotate(Vector3 eulers, [DefaultValue("Space.Self")] Space relativeTo); 就容易想到的就是transform.Rotate方法: 1 RotationObj.transform.Rotate(Vector3.up * Palstance * Time.deltaTime); 其中Palstance代表角速度。 但很快就会发现这个方法有2个很大的缺陷: ①需要利用cross值(叉积)来手动判断是绕旋转轴逆时针还是顺时针旋转 如果叉积为正,说明目标体在旋转体右侧,需顺时针旋转; 如果叉积为负,说明目标体在旋转体左侧,需逆时针旋转 具体判断如下: 其中offset代表目标体与旋转体坐标间的向量。 ②难以判断何时应该停止旋转,且角速度过大时很容易造成在到达目标向量附近来回鬼畜旋转 一般的考虑是,当旋转体的前方向向量transform.forward与offset小于一定阈值时停止旋转,例如: 但当角速度过快时,很容易错过[0,0.1]这一角度范围,但如果把范围设置过大,有没办法精准对齐,于是就造成了在目标向量附近来回鬼畜旋转的状况; 当然了,也可以用一种非常生硬的方式来解决: 即设置另一个阈值范围(并且这个阈值范围最好和当前角速度正相关,可以计算出基于当前角速度一帧内最大的旋转角度进行设置),当小于该阈值范围时直接瞬切,因为本来就是在一帧内的角度运动,所以不会有任何违和感。 也可以考虑将判定范围与该旋转阈值设置为同一个。完整旋转方式如下: 上面的方式经过调整后虽然能够实现准确转向,但看上去并不简单直接,那有没有更简洁快速的旋转方式呢。 2.插值旋转 Lerp(a,b,t); 旋转朝向实际上可以认为是对transform.forward进行关于角速度的插值变化: 1 RotationObj.transform.forward = Vector3.Lerp(RotationObj.transform.forward, offset, Time.deltaTime * Palstance / angle).normalized; Time.deltaTime/(angel/Palstance)=Time.deltaTime * Palstance / angle; 利用当前角度与角速度相除计算出当前帧率下的预计旋转时间,随后用当前帧率与预计旋转时间的比值来对两个向量进行插值。 这种方法非常简单,但也有一个问题是没办法做到匀速旋转,角色的朝向,当前帧速率和角度可能会随时发生变化。 3.四元数旋转 四元数类中自带朝向旋转的方法,但需要先转换出目标向量对应的四元数。该方式可以实现匀速率旋转。 Unity 以一定角速度转向动态目标的旋转方式对比 标签:缺陷 坐标 oid 简洁 范围 直接 简单 obj orm 原文地址:https://www.cnblogs.com/koshio0219/p/13295175.html 1 var cross = Vector3.Cross(RotationObj.transform.forward, offset).y;
2 if (cross > 0)
3 {
4 //右
5 if (Palstance 0)
6 {
7 Palstance = -Palstance;
8 }
9 }
10 else if (cross 0)
11 {
12 //左
13 if (Palstance > 0)
14 {
15 Palstance = -Palstance;
16 }
17 }
1 var angle = Vector3.Angle(RotationObj.transform.forward, offset);
2 if (angle .1f)
3 return ;
1 //基于当前角速度一帧内最大的旋转角度
2 if (angle Time.deltaTime)
3 {
4 RotationObj.transform.forward = offset;
5 }
1 //基于当前角速度一帧内最大的旋转角度
2 if (angle Time.deltaTime)
3 {
4 RotationObj.transform.forward = offset;
5 return;
6 }
7
8 var cross = Vector3.Cross(RotationObj.transform.forward, offset).y;
9 if (cross > 0)
10 {
11 //右
12 if (Palstance 0)
13 {
14 Palstance = -Palstance;
15 }
16 }
17 else if (cross 0)
18 {
19 //左
20 if (Palstance > 0)
21 {
22 Palstance = -Palstance;
23 }
24 }
25 RotationObj.transform.Rotate(Vector3.up * Palstance * Time.deltaTime);
1 Quaternion q = Quaternion.LookRotation(offset);
2 RotationObj.transform.rotation = Quaternion.RotateTowards(RotationObj.transform.rotation, q, Palstance * Time.deltaTime);
文章标题:Unity 以一定角速度转向动态目标的旋转方式对比
文章链接:http://soscw.com/index.php/essay/76209.html