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

Posted 谢斯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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);
            
        
    
    
  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);
            
        
    
    
  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);
            
        
    
    
  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); 
            
        
    
    
  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);
            
        
    
    
  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. 总结

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

======> 适用场景

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

======> 优点

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

======> 缺点

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

总结

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

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

Unity 鼠标控制视角功能和动画播放冲突解决办法

环境是 unity 5.6.4

情况说明:

  1 模型动画单独播放是没问题的。

  2 鼠标控制模型是没问题的。

  3 在start中播放模型动画,即使鼠标控制视角代码还挂载着,但是模型却无法用鼠标旋转等操作。

解决办法

  给模型动画添加父级Gameobject,用鼠标控制模型的父级旋转,而不是直接控制模型旋转,这样播放动画和鼠标功能都可以使用。

以上是关于[unity][通过代码]控制模型旋转,动态改变模型角度,让模型转动到固定角度的主要内容,如果未能解决你的问题,请参考以下文章

unity中camera摄像头控制详解

在Unity场景中控制日夜的轮转

Unity 鼠标控制视角功能和动画播放冲突解决办法

unity HTC Vive 通过手柄控制3D物体移动、旋转

Unity模型添加旋转动画就变形,怎么回事?

小功能⭐️Unity动态更换天空盒旋转天空盒