2011-12-10 78 views
6

我的问题是我想旋转一个气缸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编辑器中看到的)涉及三角函数的级联,因此容易出现舍入误差,尤其是对于简单的浮点类型。

为了解决您的问题,我建议在开始旋转之前存储初始Quaternion对象,并在流程结束时将其设置。一些伪代码:

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")即可。动画终止时,最后使用动画事件通知。

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

+0

如果我曾经喜欢你的建议将是改变对象的本地轴,或者将它只能旋转对象的动画? – Dave

+0

您可以为游戏对象的变换的成员设置动画。 transform.rotation在欧拉角 – Kay

+0

感谢您的帮助。尽管如此,它更像是一种侧重解决问题的方式。我不能说如果(transform.eulerAngles.y == 40.0f),因为即使旋转朝向给出更准确的结果仍然存在错误。我还没有尝试过这个动画建议,但是我现在就去试试看。 – Dave

0

看看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);