Вращение Object Unity вращается с неправильным значением - PullRequest
6 голосов
/ 10 декабря 2011

Моя проблема в том, что я хочу иметь возможность вращать цилиндр 9 раз. 360/9 - это 40, поэтому мне нужно только повернуть на 40 градусов 9 раз. Однако это не работает, поскольку, когда я поворачиваю цилиндр в первый раз вместо 40 градусов, он поворачивается на 39,99 градусов. Это происходит и при других поворотах.

Я вращаюсь, делая это.

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

У меня версия Unity 3.4, она не профессиональная, и я пишу код на C #.

Любая помощь оценена, поскольку я только начал пытаться учиться единству.

Ответы [ 2 ]

1 голос
/ 12 декабря 2011

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.

Еще одна полезная вещь для вас - Анимации . Вы можете определить анимацию как плавную или дискретную и просто вызвать GameObject.animation.Play("MyRotation"), если нажата «i». Используйте AnimationEvent в конце, чтобы получить информацию о завершении анимации.

И, наконец, Mathf содержит функцию Приблизительно , которая занимается проблемой неточности с плавающей запятой.

0 голосов
/ 20 июля 2015

Посмотрите на ответ Kungfooman в этом посте , он описывает проблему с поворотом на 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...