• [unity][通过代码]控制模型旋转,动态改变模型角度,让模型转动到固定角度


    阅读建议

    ⏰阅读时长 : 10分钟
    🏫阅读难度 : 初级
    🌾阅读收获 : 了解模型的旋转基本原理,了解瞬间旋转和过度旋转的理论,并学习到一种过渡方式的代码编写
    🖇例子地址 : https://gitee.com/asiworld/unity3d-basic-function-code
    🤡demo效果 :
    请添加图片描述

    一.方式:[通过设置angle/三元数/vector3的方式来瞬间设置角度]

    🐒 1. 原理

    Transform.eulerAngles : 以欧拉角表示的旋转(以度为单位)。

    欧拉角可以通过围绕各个轴执行三个单独的旋转来表示三维旋转。在 Unity 中,围绕 Z 轴、X 轴和 Y 轴(按该顺序)执行这些旋转。

    可以通过设置此属性来设置四元数的旋转,并且可以通过读取此属性来读取欧拉角的值。

    使用 .eulerAngles 属性设置旋转时,务必要了解,虽然提供 X、Y 和 Z 旋转值描述旋转,但是这些值不存储在旋转中。而是将 X、Y 和 Z 值转换为四元数的内部格式。

    读取 .eulerAngles 属性时,Unity 将四元数的内部旋转表示形式转换为欧拉角。因为可通过多种方式使用欧拉角表示任何给定旋转,所以读出的值可能与分配的值截然不同。如果尝试逐渐增加值以生成动画,则这种情况可能会导致混淆。

    若要避免这些类型的问题,使用旋转的建议方式是避免在读取 .eulerAngles 时依赖一致的结果,特别是在尝试逐渐增加旋转以生成动画时。有关实现此目标的更佳方式,请参阅四元数 * 运算符。

    以下示例说明基于用户的输入使用 eulerAngles 旋转 GameObject。该示例说明我们从不依赖于读取 Quanternion.eulerAngles 来增加旋转,而是使用 Vector3 currentEulerAngles 来设置它。所有旋转更改都在 currentEulerAngles 变量中进行,这些更改随后应用于四元数,从而避免上面提到的问题。

    🎨 2. 步骤

    1. 创建模型
    2. 创建脚本
    3. 编写脚本
      using System.Collections;
      
      using UnityEngine;
      
      namespace ubfc.rotate_1
      {
          public class rotate_1_1 : MonoBehaviour
          {
              // Start is called before the first frame update
              IEnumerator Start()
              {
                  yield return new WaitForSeconds(0.5f);
                  transform.eulerAngles = new Vector3(45, 45, 45);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    4. 挂在脚本
    5. 运行

    🎞 3. 效果展示

    请添加图片描述

    ☕ 4. 总结

    此方法比较适合刚入门的使用者,可以直接转向对应的角度,在一帧的过程就完成转动内容,

    ======> 适用场景

    1. 在update中一直转向一个动态的角度
    2. 一瞬间转向某个角度

    ======> 优点

    1. 新手更容易理解角度的概念,在我们的生活中基本上使用的都是欧拉角
    2. 操作简单,一行代码就可以处理好角度问题

    ======> 缺点

    1. 因为使用的是欧拉角,所以在处理的时候经常会出现万向轴的问题,不过对于瞬时变化影响不大.
    2. 主要是容易让开发者习惯三元数的操作之后后续很难改正.

    二.方式:[通过设置angle/三元数/vector3的方式,慢慢的转动角度]

    🐒 1. 原理

    使用的和方式一一样的技术,只是由瞬间变化的角度改为,也就是说中间加了一个目标角度的变量,整个过程在一个update,或者是一个协程中.

    🎨 2. 步骤

    1. 创建模型

    2. 创建脚本

    3. 编写脚本

      using UnityEngine;
      
      
      namespace ubfc.rotate_1
      {
          public class rotate_1_2 : MonoBehaviour
          {
              // Update is called once per frame
              void Update()
              {
                  transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, new Vector3(45, 45, 45), Time.deltaTime);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    4. 挂在脚本

    5. 运行

    🎞 3. 效果展示

    请添加图片描述

    ☕ 4. 总结

    主要是慢慢移动的过程的实现方式,我们这里列举了一种非常简单的方式,当然还有其他的方式可以使用,大家可以作为参考,根据自己的需求不同自己进行修改

    ======> 适用场景

    1. 从一个角度缓慢移动到另一种角度

    ======> 优点

    1. 缓慢转动,有转动动画,效果较好

    ======> 缺点

    1. 旋转角度不能大于360度,否则会有bug

    三.方式:[通过设置rotation/四元数/Quaternion的方式来瞬间设置角度]

    🐒 1. 原理

    Transform.rotation :

    一个 Quaternion,用于存储变换在世界空间中的旋转。

    Transform.rotation 存储 Quaternion。可以使用 rotation 来旋转 GameObject 或提供当前旋转。请勿尝试编辑/修改 rotation。Transform.rotation 小于 180 度。

    Transform.rotation 没有万向锁。

    要旋转 Transform,请使用 Transform.Rotate,它将使用欧拉角。

    如果要匹配在检视面板中看到的值,请对返回的 Quaternion 使用 Quaternion.eulerAngles 属性。

    🎨 2. 步骤

    1. 创建模型

    2. 创建脚本

    3. 编写脚本

      using System.Collections;
      
      using UnityEngine;
      
      namespace ubfc.rotate_1
      {
          public class rotate_1_3 : MonoBehaviour
          {
              // Start is called before the first frame update
              IEnumerator Start()
              {
                  yield return new WaitForSeconds(0.5f);
                  transform.rotation = Quaternion.Euler(45, 45, 45);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    4. 挂在脚本

    5. 运行

    🎞 3. 效果展示

    在这里插入图片描述

    ☕ 4. 总结

    对于角度的控制最好用的方式,这种方式的操作方式其实并不方便,很多时候需要通过欧拉角进行转换,但是他这里面有个得天独厚的优势,就是使用这个四元数操作角度不容易出现bug,或者说不会出现bug.

    ======> 适用场景

    1. 和之前的方式一的适用场景基本一直,用于在update中控制角度等
    2. 不一样的地方主要是增加了万向轴的操作,所谓万向轴的操作主要用于在插值动画中,从一个角度状态编完第二种角度状态的过程中,如果角度差距比较大,四元数不会有bug,而三元数会有bug

    ======> 优点

    1. 对于角度操作有更好的兼容性,不会出现bug

    ======> 缺点

    1. 需要一定的学习成本,不容易理解

    四.方式:[通过设置rotation/四元数/Quaternion的方式来慢慢设置角度]

    🐒 1. 原理

    原理和方式三是一样的,只是加入了过程,过程在update或者协程中进行.

    🎨 2. 步骤

    1. 创建模型

    2. 创建脚本

    3. 编写脚本

      using UnityEngine;
      
      
      namespace ubfc.rotate_1
      {
          public class rotate_1_4 : MonoBehaviour
          {
              // Update is called once per frame
              void Update()
              {
                  transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(45, 45, 45), Time.deltaTime); 
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    4. 挂在脚本

    5. 运行

    🎞 3. 效果展示

    在这里插入图片描述

    ☕ 4. 总结

    对于角度变化非常好用的方式,尤其是对于那种操作角度非常复杂的情况,比如阀门可能需要旋转很多线圈

    ======> 适用场景

    1. 阀门转动
    2. 模型固定角度转动
    3. 存在万向锁的旋转问题

    ======> 优点

    1. 兼容性非常强,不会出现万向锁问题

    ======> 缺点

    1. 操作起来经常会使用欧拉角进行转换.

    五.方式:[通过插件dotween,动态改变模型角度,让模型慢慢旋转]

    🐒 1. 原理

    Dotween作为unity最常用的第三方动画插件,肯定是在所有点动动画必不可少的,我们利用Dotween已经封装好的接口进行直接调用就行,Dotween会帮助我们完成这个过程的差值计算.

    🎨 2. 步骤

    1. 引入dotween插件
      在这里插入图片描述

    2. 初始化dotween插件
      在这里插入图片描述

    3. 创建模型

    4. 创建脚本

    5. 编写脚本

      using DG.Tweening;
      
      using System.Collections;
      
      using UnityEngine;
      
      
      namespace ubfc.rotate_1
      {
          public class rotate_1_5 : MonoBehaviour
          {
              // Start is called before the first frame update
              IEnumerator Start()
              {
                  yield return new WaitForSeconds(0.5f);
                  transform.DORotate(new Vector3(45, 45, 45), 5.0f).SetEase(Ease.Linear);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    6. 挂在脚本

    7. 运行

    🎞 3. 效果展示

    在这里插入图片描述

    ☕ 4. 总结

    操作方式比较简单,性能也非常好,对于新手和老手都是非常合适的,灵活多变,有较多预先曲线,甚至可以自己设置曲线,可以说满足段动画的所有要求,并且在支持的变量类型上也非常的丰富,基本覆盖了所有的数据内容,非常好用.

    ======> 适用场景

    1. 一次性的动画,我常用点动动画来形容

    ======> 优点

    1. 平滑的处理已经被集成,我们需要做的只是选择对应的插值方案,和告诉插件对应的时间

    ======> 缺点

    1. 无法使用在很频繁的调用上,只能使用在点动动画上

    六.方式:[通过transfrom组件的rotate函数进行旋转]

    🐒 1. 原理

    使用 Transform.Rotate 以各种方式旋转 GameObjects。通常以欧拉角而不是四元数提供旋转。

    可以在世界轴或本地轴中指定旋转。

    世界轴旋转使用 Scene 的坐标系,因此在开始旋转 GameObject 时,它的 x、y 和 z 轴与 x、y 和 z 世界轴对齐。所以,如果在世界空间中旋转一个立方体,它的轴就会与世界对齐。在 Unity 编辑器的 Scene 视图中选中一个立方体时,将显示左Gizmos下以及正向/反向旋转轴的旋转 Gizmos。移动这些 Gizmos 将使立方体绕轴旋转。如果取消选择然后重新选择该立方体,这些轴将重新开始在世界中对齐。

    本地旋转使用 GameObject 本身的坐标系。因此,新建的立方体将使用设置为零旋转的 x、y 和 z 轴。旋转该立方体将更新旋转轴。如果取消选择然后重新选择该立方体,将按之前的相同方向显示这些轴。

    🎨 2. 步骤1. 创建模型

    1. 创建脚本
    2. 编写脚本
    using UnityEngine;
    
    
    namespace ubfc.rotate_1
    {
        public class rotate_1_6 : MonoBehaviour
        {
            // Update is called once per frame
            void Update()
            {
                transform.Rotate(Vector3.one);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 挂在脚本
    2. 运行

    🎞 3. 效果展示

    在这里插入图片描述

    ☕ 4. 总结

    在设置角度和旋转角度的时候经常会使用的一种方式,可以设置旋转的角度,比如我们想x轴方向旋转10度,那么我们直接传一个(10,0,0)的vector3就可以完成,这样做我们就可以把这个代码使用在瞬间旋转和update持续旋转中都可以,兼容性也非常的高

    ======> 适用场景

    1. 按照角度旋转的任何场景,但是传入参数必须是欧拉角,也就说旋转的格式要是欧拉角,当然这种方式有优势也有弊端,就是rotation的表现毕竟是四元数,二欧拉角作为三元数适应场景虽然多,但是会出现bug的可能

    ======> 优点

    1. 使用所有自增的旋转.
    2. 使用欧拉角作为参数,更好理解

    ======> 缺点

    1. 如果需要转到固定角度需要提前得到想要旋转的角度,也就是目标角度

    总结

    旋转的原理比较简单,总的来讲只是控制transform组件的属性,那么是以瞬间变化还是有一个段动画,还是延时的,这个就完全由自己业务逻辑来决定了,这个就没有具体的难点了,如果有任何疑问可以随时在我的博客中联系我.

    😘求求老爷给个一键三连吧

  • 相关阅读:
    设计模式之策略模式
    【Spring Boot 源码学习】OnWebApplicationCondition 详解
    DDoS渗透与攻防实战 (一) : 初识DDoS
    【Mysql主从配置方法---单主从】
    Spring源码-总体架构体系和源码环境搭建
    Elasticsearch 8.X:这个复杂的检索需求如何实现?
    Mac-postman存储文件目录
    驱动day4
    轻量级的日志采集组件 Filebeat 讲解与实战操作
    C代码写的比Codex还溜的AI神器开源
  • 原文地址:https://blog.csdn.net/JianShengShuaiest/article/details/126881492