Raycast вдоль поверхности объектов, сохраняя горизонтальность луча в unity

#c# #unity3d #rotation #raycasting #direction

#c# #unity3d #поворот #raycasting #направление

Вопрос:

Я пытаюсь выполнить raycast вдоль поверхностей объектов, чтобы создать сетку поверхности жидкости в контейнерах, сделанных из объектов, независимо от их вращения. В настоящее время я выполняю преобразование.вверх / вправо / вперед, используя X и Z, но устанавливая Y в 0 для направления лучей. Кажется, это работает, когда объект вращается по нескольким осям.

Пример ошибки

Здесь вы можете видеть, что направление зеленого луча не вдоль грани. Я думаю, что решение может быть связано с принятием значения y, которое я игнорирую, и каким-то образом применяю его к x и z.

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

Комментарии:

1. Какой код вы уже пробовали? У вас уже есть способ вычислить нормаль интересующей вас грани?

2. Можете ли вы более подробно описать, что вы подразумеваете под «raycast вдоль граней объектов»?

3. @NSJacob1 В основном raycast вдоль преобразования объектов, при этом луч всегда должен быть горизонтальным (в мировом пространстве).

4. @Ruzihm То, что я пробовал до сих пор, — это определение направления луча Vector3(object.transform.right.x,0 ,object.transform.right.z) и так далее для каждого направления. И это работает до тех пор, пока вы не повернете объект по всем 3 осям. Я могу получить нормаль от попадания луча, поскольку происхождение лучей определяется точкой контакта луча, попадающего на объект.

5. Итак … просто чтобы убедиться, что я понимаю … вы ищете векторы, которые лежат вдоль горизонтальной плоскости и поверхности объекта?

Ответ №1:

Если у вас есть нормаль к интересующей вас поверхности, вы можете использовать Vector3.Cross для нахождения касательной, которая также ортогональна вверх. Просто не забудьте проверить, равен ли результат (0,0,0) в случае, если up и нормаль являются коллинеарными, тогда вы можете выбрать произвольное горизонтальное направление мира.

 public class test : MonoBehaviour
{
    void Update()
    {
        Vector3 dir = HorizontalTangent(transform.up);
        Debug.DrawLine(transform.position, transform.position   dir,Color.red, 0f);
    }

    Vector3 HorizontalTangent(Vector3 surfaceNorm)
    {
        Vector3 res = Vector3.Cross(Vector3.up, surfaceNorm);
        if (res == Vector3.zero) res = Vector3.right;
        return res;
    }
}
 

пример

Комментарии:

1. Идеально, делает именно то, что я искал. Спасибо.