Unity3D - Относительное положение на оси Y независимо от вращения? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть объект (A) с другим объектом (B) рядом с ним.Я пытаюсь вычислить «высоту» объекта B, чтобы я мог расположить другой объект на этой высоте относительно положения объекта A. Я знаю, что это звучит как бред (я немного устал), поэтому я поставил диаграммычтобы попытаться объяснить.

Итак, на левом изображении желтая линия представляет то, что я пытаюсь вычислить.У меня есть позиция (оранжевая) на поверхности цилиндра (серая) (расчетная позиция с использованием данных сетки), которую я пытаюсь использовать для расчета радиуса объекта (черная линия).Для этого мне нужно положение в центре объекта (серый) на той же высоте (красная точка), чтобы я мог рассчитать направление от одного к другому и использовать длину (. Magnitude) в качестве радиуса.

Моя проблема в том, что я не могу понять, как я могу рассчитать высоту (желтая линия) без поворота, имеющего какой-либо эффект.

В настоящее время я использую projectOnPlane, однако еслия поворачиваю объект, как видно на втором изображении, радиус значительно уменьшается, когда он должен быть согласованным, поскольку объект не меняет размер.

Vector3 RadDirection = (Vector3.ProjectOnPlane(orangePoint, grey.transform.up) - Vector3.ProjectOnPlane(grey.transform.position, grey.transform.up));
float radius = RadDirection.magnitude;

Любая помощь будет принята с благодарностью, спасибо.

enter image description here

** ОБНОВЛЕНИЕ: Серый блок на диаграмме - это позиция вектора 3, а не игровой объект.Расчет радиуса, который я пытаюсь сделать, происходит во время выполнения, поэтому я не могу привязать объект к серому и просмотреть инспектор.

** ОБНОВЛЕНИЕ 2: Извините, что-то, что я должен был упомянуть.Объект, на котором я делаю это, не всегда будет идеальным цилиндром, это может быть что-то вроде бокала, где мне нужно вычислить радиус стакана, а не ствол.Другим примером может быть химический стакан, который обычно сужается к точке, поэтому мне нужно будет вычислить радиус на высоте оранжевой точки.Извините, я должен был указать это в вопросе.

Вот диаграмма, иллюстрирующая, что я имею в виду в обновлении 2. Опять оранжевая точка выступает в качестве визуального представления положения Vector3 на поверхности объекта (вв этом случае мензурка) меш.

** Обновление 3: я, кажется, решил проблему, поэтому я разместил свой ответ ниже, но на момент написания я не могу принять его (придется подождать 2дней) и так не могу закрыть / ответить на вопрос.Я хотел бы поблагодарить всех, кто внес свой вклад и попытался помочь мне решить эту проблему.Я надеюсь, что когда-нибудь смогу помочь вам всем:)

enter image description here

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Я, кажется, решил свою проблему, используя следующее:

public static Vector3 ProjectPointOnLine(Vector3 linePoint, Vector3 lineVec, Vector3 point)
    {
        //get vector from point on line to point in space
        Vector3 linePointToPoint = point - linePoint;

        float t = Vector3.Dot(linePointToPoint, lineVec);

        return linePoint + lineVec * t;
    }

Я нашел это здесь, у него есть много других полезных функций: http://wiki.unity3d.com/index.php/3d_Math_functions

Я в основном передаюпроисхождение стакана (зеленая точка) как «linePoint», направление вверх стакана «lineVec» с beaker.transform.up и, наконец, я передаю точку мира vector3 на поверхности сетки стакана (оранжевая точка)он возвращает точку в середине стакана на той же высоте, что и моя оранжевая точка.Затем я просто вычитаю одно из другого и принимаю величину в качестве радиуса.Рассчитанное значение радиуса является верным в том смысле, что это именно то значение, которое я ожидал, и оно изменяется только после шестого знака после запятой во время вращения, что дает достаточную точность, поскольку мне нужны только три или четыре знака после запятой.

Я счастливпредоставьте дополнительную информацию или помощь, если кому-то еще потребуется помощь в этом.

0 голосов
/ 21 сентября 2018

Вы можете использовать transform.TransformDirection() или transform.InverseTransformDirection()

Чтобы получить высоту, возьмите результат вычитания и установите координаты X, Z на ноль:

Vector3 height = orangeBox.position - greenPoint.position; 
height.x = 0; 
height.z = 0; 

Полное решение:

    Vector3 direction = orangeBox.position - greenPoint.position;
    direction = greyBox.transform.InverseTransformDirection(direction);
    direction.x = 0;
    direction.z = 0;
    height = direction.magnitude;
    redPoint.position = greenPoint.position + greyBox.transform.up * height;
...