Объект не вращается в правильном направлении от Атан2 до Кватерниона.

Я пытаюсь повернуть объект по оси z, учитывая точку, которую я вычислил под углом с помощью функции Atan2. Затем я создаю кватернион, чтобы ввести его во вращение объекта. Однако он не вращается в предположительно правильном направлении. Если я рисую углы, заданные функциями Atan2, я визуализирую систему углов по часовой стрелке, но если я рисую углы, которые должны быть так, чтобы мой объект отображался в правильном направлении, я визуализирую систему против часовой стрелки. Решения, создающие словарь со значениями, полученными функцией Atan2 в качестве ключей, и их значения - это углы, на которые объект будет вращаться в правильном направлении. Но я все еще не понимаю, что происходит. Я надеюсь, что кто-то может помочь мне понять это, потому что нет решения хуже, чем то, которое решает, но не знает, что происходит.

введите здесь описание изображения

public class ArrowMovement : MonoBehaviour
{
    public Vector2Variable currentPlayerDirection;
    public Vector3Variable currentPlayerPosition;
    public InputAxis inputAxis;

    private float anglePassed;
    private Dictionary<float, float> realAngles = new Dictionary<float, float>();

    void Awake()
    {
        realAngles.Add(-135, -135);
        realAngles.Add(-90, 180);
        realAngles.Add(-45, 135);
        realAngles.Add(0, 90);
        realAngles.Add(45, 45);
        realAngles.Add(90, 0);
        realAngles.Add(135, -45);
        realAngles.Add(180, -90);
    }

    void Update()
    {
        Vector3 offsetVector = new Vector3(0.2f, 0.05f, 0);
        transform.position = currentPlayerPosition.Value;

        // Rotation
        float angle = Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall) * Mathf.Rad2Deg;
        Quaternion rotation = Quaternion.Euler(0, 0, realAngles[angle]);
        transform.rotation = rotation;
    }
}

person user3324336    schedule 07.12.2019    source источник


Ответы (2)


Прежде всего, вы должны знать, что такое inputAxis. Я могу предположить из вашей диаграммы, что вы ожидаете, что для inputAxis.verticall == 0 угол должен быть 0. Давайте посмотрим на Mathf.Athan2(y,x) - эквивалент arctan(y/x), поэтому результат будет нулевым, только если y равно нулю. Но в вашем коде Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall) даст 0, когда inputAxis.horizontal == 0 - это вертикальное направление (ваша первая диаграмма).

Вторая проблема - неправильное направление вращения. Это может произойти, когда одна из входных осей перевернута. Вероятно, inputAxis измеряется в другой системе координат относительно вашего объекта, то есть Z вашего объекта -Z вашего inputAxis. В любом случае inputAxis.verticall можно инвертировать

float angle = Mathf.Atan2(inputAxis.horizontal, -inputAxis.verticall) * Mathf.Rad2Deg;

Также вам следует избегать решения простой геометрической задачи путем «создания словаря» или чего-то подобного. Даже если вы не знаете, как inputAxis работает и результат неверный - сделайте два шага, чтобы исправить это: 1. исправить направление вращения - просто измените угол _ 15_; 2. зафиксировать нулевое положение - добавить статическое вращение. В вашем случае это 90 градусов Quaternion.Euler(0, 0, 90 - angle). И это второй способ решения проблемы.

person mr NAE    schedule 11.02.2020

Создание словаря - не лучший способ, потому что он не принимает во внимание углы между теми, которые вы установили, поэтому для преобразования одной диаграммы в другую я бы создал функцию, которая выглядит так:

float ChangeAngleDiagram(float angle) {
    return -(angle + 90f)+180;
}
person Anis Brachemi    schedule 08.12.2019
comment
Вы правы и большое вам спасибо за функцию. Я все еще сомневаюсь, почему такое поведение происходит. - person user3324336; 08.12.2019