Unity3D euler поддерживает плавное изменение по одной оси - PullRequest
0 голосов
/ 03 ноября 2018

Я пытаюсь повернуть куб на 90 градусов по одной оси, все работает нормально, если есть оси в 0 позиции. Но если какая-либо ось в любой позиции, например, 90 или -90, он начинает вращаться бесконечно.

Видео как это выглядит: https://youtu.be/PE4YH19ndCc

public Vector3 targetEulerAngles;
public float spd = 0.1f;
GameObject mainCube;
public void Awake()
{
    mainCube = GameObject.FindGameObjectWithTag("mainCube");
}
public void FixedUpdate()
{
    mainCube.transform.eulerAngles = Vector3.Lerp(mainCube.transform.eulerAngles, targetEulerAngles, spd);
}
public void RotateToLeft()
{
    targetEulerAngles = new Vector3(targetEulerAngles.x + 90f, targetEulerAngles.y, targetEulerAngles.z);
}
public void RotateToRight()
{
    targetEulerAngles = new Vector3(targetEulerAngles.x - 90f, targetEulerAngles.y, targetEulerAngles.z);
}
public void RotateToUp()
{
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z - 90f);
}
public void RotateToDown()
{
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z + 90f);
}

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

То, что @ joel64 сказал в своем ответе, определенно верно, но здесь проблема не в этом.

Проблема в том, что вы используете Lerp неправильно. Последний аргумент Lerp (a, b, c) НЕ СКОРОСТЬ, это прогресс от 0 до 1, где c <= 0 означает результат = a, c> = 1 означает результат = b, а все остальные значения находятся между , Ваш код постоянно вращает куб и никогда не останавливается, просто со временем он вращается все меньше и меньше.

С углами Эйлера это очень заметно из-за ошибок преобразования, при использовании кватернионов это будет менее заметно, но тем не менее - вращение никогда не останавливается.

Чтобы сделать все правильно, вам нужно написать еще немного кода. Вам нужна некоторая переменная для хранения текущего прогресса вращения, и вы должны помнить, где началось вращение. Затем поверните куб из начальной позиции в целевую позицию с учетом прогресса и увеличивайте прогресс в каждом кадре.

О, и не забывайте о deltaTime, если вы хотите, чтобы ваш оборот был одинаковым на любом FPS.

Финальный код будет:

public Vector3 targetEulerAngles;
public float spd = 0.1f;
GameObject mainCube;

private Quaternion startRotation;
private float progress = 0;

public void Awake() {
    mainCube = GameObject.FindGameObjectWithTag("mainCube");
}
public void FixedUpdate() {
    if (progress == 0) startRotation = mainCube.transform.rotation;
    mainCube.transform.rotation = Quaternion.Lerp(startRotation, Quaternion.Euler(targetEulerAngles), progress);
    progress += spd*Time.fixedDeltaTime;
}
public void RotateToLeft() {
    targetEulerAngles = new Vector3(targetEulerAngles.x + 90f, targetEulerAngles.y, targetEulerAngles.z);
    progress = 0;
}
public void RotateToRight() {
    targetEulerAngles = new Vector3(targetEulerAngles.x - 90f, targetEulerAngles.y, targetEulerAngles.z);
    progress = 0;
}
public void RotateToUp() {
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z - 90f);
    progress = 0;
}
public void RotateToDown() {
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z + 90f);
    progress = 0;
}
0 голосов
/ 03 ноября 2018

иногда даже при использовании углов Эйлера я получаю странные результаты, поэтому вместо них я использую кватернионы

возможно попробуйте это в вашем фиксированном обновлении

mainCube.transform.rotation = Quaternion.Lerp(mainCube.transform.rotation, Quaternion.Euler(targetEulerAngles), spd);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...