对象 Unity 的旋转以错误的值旋转

Posted

技术标签:

【中文标题】对象 Unity 的旋转以错误的值旋转【英文标题】:Rotation of Object Unity rotating at wrong value 【发布时间】:2011-12-10 18:03:30 【问题描述】:

我的问题是我希望能够将圆柱体旋转 9 次。 360/9 是 40,所以我需要做的就是旋转 40 度 9 次。但是这不起作用,因为当我第一次旋转圆柱体而不是 40 度时,它旋转了 39.99 度。这也发生在其他轮换中。

我这样做是在旋转。

if(Input.GetKeyUp("i"))
      transform.GetChild(m_Section).Rotate(0,40.0f,0);

我有统一版本 3.4,它不是专业版,我正在用 C# 编码。

感谢任何帮助,因为我刚刚开始尝试学习团结。

【问题讨论】:

【参考方案1】:

Unity3D 以一种非常抽象的数学表示形式存储旋转,称为quaternion。从和到欧拉角的转换(您在 Unity 编辑器中看到的)涉及级联三角函数,因此容易出现舍入错误,尤其是对于简单的浮点类型。

为了在您的情况下解决此问题,我建议在开始旋转之前存储初始四元数对象并在过程结束时设置它。一些伪代码:

public class RotationController : MonoBehaviour 
    Quaternion rotationAtStart;
    int numOfRotations = 0;

    void rotate () 
        numOfRotations++;
        if (numOfRotations == 1) 
            rotationAtStart = transform.rotation;
         else if (numOfRotations < 9) 
            transform.Rotate (new Vector3 (0,40.0f,0));
         else if (numOfRotations == 9) 
            transform.rotation = rotationAtStart;
        
    
    void Update () 
        if (numOfRotations < 9) 
            rotate ();
        
    
    

360°的特殊情况使得这种方法很稳定。对于小于 360° 的情况,您必须忍受小的舍入误差。对于这种情况,我建议计算目标四元数Quaternion.RotateTowards,并在最后一步中将其设置为模拟 360 度情况。

另一个对你有用的东西是Animations。您可以将动画定义为平滑或离散步骤,如果按下“i”,只需调用GameObject.animation.Play("MyRotation")。最后使用 AnimationEvent 以在动画终止时获得通知。

最后 Mathf 包含一个函数Approximately 处理浮点不精确的问题。

【讨论】:

如果我使用你建议的动画会改变对象的局部轴还是只会旋转对象? 您为游戏对象变换的成员设置动画。 transform.rotation 是欧拉角 感谢您的帮助。不过,这更像是一种解决问题的方法,而不是解决方法。我不能说 if(transform.eulerAngles.y == 40.0f) 因为即使旋转方向给出了更准确的结果,仍然存在错误。我还没有尝试过动画建议,但我现在就试一试。【参考方案2】:

看看Kungfoomanin this post的答案,他描述了旋转超过90度或90度以及270度的问题。他提供了一个扩展,它将始终为您要设置的值计算 Quaternion 的正确挂件。看看这里:

using UnityEngine;
using System.Collections;

public class ExtensionVector3 : MonoBehaviour 

    public static float CalculateEulerSafeX(float x)
        if( x > -90 && x <= 90 )
            return x;
        

        if( x > 0 )
            x -= 180;
         else 
            x += 180;
        
        return x;
    

    public static Vector3 EulerSafeX(Vector3 eulerAngles)
        eulerAngles.x = CalculateEulerSafeX(eulerAngles.x);
        return eulerAngles;
    

我是这样使用的:

Quaternion newQuat = m_directionalLight.transform.rotation;
Vector3 nL = new Vector3(ExtensionVector3.CalculateEulerSafeX(xNewValueLight), 
                         0, 
                         0);
newQuat.eulerAngles = nL;

m_directionalLight.transform.rotation = 
     Quaternion.Lerp(m_directionalLight.transform.rotation, 
                     newQuat, 
                     Time.deltaTime);

【讨论】:

以上是关于对象 Unity 的旋转以错误的值旋转的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D中的对象不以直角看其他对象

Unity - Blender - Unity 中的对象获得错误的枢轴

如何使游戏对象在旋转平面中围绕 Unity 中的另一个游戏对象旋转

在 Unity 3D 中旋转对象

unity 对象旋转,自转

Unity,改变子对象的旋转。无法访问子对象