【问题标题】:Incrementing Euler angles beyond 360 degrees增加欧拉角超过 360 度
【发布时间】:2017-01-06 05:44:07
【问题描述】:

我对一些与欧拉角有关的 Unity 文档感到有些困惑。我只是想知道我是否不了解差异,或者示例不遵循最佳实践。文档here 状态:

仅使用此变量来读取角度并将其设置为绝对值。不要增加它们,因为当角度超过 360 度时它会失败。请改用 Transform.Rotate。

同时,代码示例似乎使用了可能超过 360 度的增量:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public float yRotation = 5.0F;
    void Update() {
        yRotation += Input.GetAxis("Horizontal");
        transform.eulerAngles = new Vector3(10, yRotation, 0);
    }
    void Example() {
        print(transform.eulerAngles.x);
        print(transform.eulerAngles.y);
        print(transform.eulerAngles.z);
    }
}

如果变量超过 360 度,增加变量然后使用该变量设置值绝对仍然存在超过 360 度的风险吗?

【问题讨论】:

  • 我认为该示例是一种特殊情况,可以安全地使 y 无限增加,因为 y 是唯一定期更改的轴,而 x 和 z 保持不变。如果所有轴都可能是可修改的,那么当你的欧拉在 360 处交换时,增加 y 可能会导致问题。你甚至可能进入万向节锁定状态。我想这就是推荐使用 Transform.Rotate 的原因。

标签: c# unity3d


【解决方案1】:

当您使用欧拉角旋转对象时,当它达到 360 并尝试进一步超过时,它变为(负)-360 并逐渐从 -359 增加到 -1。

执行以下代码后,您的值不会超过 360 并且将保持正数。

float rotateAngle = rotateObject.transform.localEulerAngles.y;
// Convert negative angle to positive angle
rotateAngle = (rotateAngle > 180) ? rotateAngle - 360 : rotateAngle;
rotateObject.transform.localEulerAngles = new Vector3(rotateObject.transform.localEulerAngles.x, rotateAngle, rotateObject.transform.localEulerAngles.z);

【讨论】:

  • 谢谢,我明白你的意思了,但是文档中的示例代码是否仍然存在超过 360 的风险?
【解决方案2】:

存在差异。做的时候:

transform.eulerAngles.y += 1F;

您正在调用Vector3 中的+= 运算符。

但是,当您这样设置eulerAngles 时:

float newY = transform.eulerAngles.y + 1F;
transform.eulerAngles = new Vector3(.., newY, ..);

你在Transform中调用了一个setter,而在这个setter里面,它可能包含了更新Transform.rotation的动作。

不同之处在于 Unity 可以在 Transform 类而不是 Vector3 类中实现更新逻辑,这在此处更有意义。

我们可以在下面的documentation 中进一步验证这一点:

不要单独设置 eulerAngles 轴之一(例如 eulerAngles.x = 10个; ) 因为这会导致漂移和不希望的旋转。什么时候 将它们设置为新值一次设置它们,如上所示。 团结 将角度转换为存储在 变换.旋转。

【讨论】:

  • 这里要补充的一点是,这仅适用于 Javascript。此外,要解决这个问题,您实际上可以执行以下操作:transform.eulerAngles.y += yRotation % 360;。你不应该,但知道变通方法是件好事。
  • @Programmer 你的意思是transform.eulerAngles.y += 1F 在c# 中安全工作? :O
  • 没有。它不会编译。这就是 C# 中对它的保护。这将在 Javascript 中编译,您将遇到文档中提到的问题。
  • @Programmer 哦我明白了,有趣,不知道
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
相关资源
最近更新 更多