Пользовательский LookAt и что за ним стоит

Я пытался понять математику (тригонометрию и линейную алгебру), стоящую за функцией transform.LookAt(). Я следовал учебнику и пытался изменить его в соответствии со своими потребностями, но пока мне это не удалось.

Я пытаюсь создать камеру (в трехмерном пространстве), которая следует за игроком с пользовательским смещением, но в то же время пользователь может увеличивать и уменьшать масштаб камеры, сохраняя при этом это смещение Vector3. Я также блокирую другие оси и просто хочу применить вращение только к оси X. Проблема с моим скриптом в том, что угол кажется зажатым между 45° и 90° градусами. я думаю, что я что-то упускаю

private void LookAt(Transform t) 
{
    Vector3 forward = _camPos - (t.position + new Vector3(0, t.GetComponent<CapsuleCollider>().height / 2, 0));
    Debug.DrawRay(forward, -forward, Color.blue);
    Vector3 right = Vector3.Cross(target.up, forward);
    Debug.DrawRay(forward, right, Color.magenta);
    Vector3 newUp = Vector3.Cross(Vector3.forward, right);
    Debug.DrawRay(forward, newUp, Color.yellow);

    float angle = Mathf.Atan2(forward.magnitude, newUp.magnitude) * Mathf.Rad2Deg;

    mainCam.transform.rotation = Quaternion.Euler(angle, 0, 0);
}
  • Мой код сначала получает прямой вектор (гипотенуза в прямоугольном треугольнике) от камеры к цели. Примечание здесь, что это дает противоположное направление, но это не имеет значения, потому что
  • затем он вычисляет «правильный» вектор, имея перекрестное произведение прямого вектора и целевого вектора вверх.
  • затем он вычисляет вектор «newUp» (противоположный в прямоугольном треугольнике), имея перекрестное произведение прямого и правого векторов.
  • вычисляет вращение X, используя тангенс дуги, который является отношением между hpyotenuse/противоположным

Как видите, векторные расчеты такие же, как на скриншоте.

  • синий -прямой вектор
  • пурпурный правый вектор
  • желтый вектор

вперед, вправо и newUp векторы

Тем не менее, камера правильно фокусируется на персонаже только тогда, когда я уменьшаю коэффициент масштабирования, то есть приближаю камеру к нему:

Глядя на цель (правильно) только с расстояния

Что мне не хватает? Помощь очень ценится!

Разве это не всплыло на днях? В Unity есть множество примеров камер погони. Почти уверен, что в Standard Assets есть такой.

user585968 28.10.2022 11:27

Я знаю, что есть Quaternion.LookRotation() и Transform.LookAt(), но я хотел знать математику, стоящую за ними, для учебных целей. Каждый пост, который я проверял, говорил одно и то же, но совсем не объяснял математику.

Narc0t1CYM 28.10.2022 11:29

С математической точки зрения в Интернете можно найти углы между двумя точками.

BugFinder 28.10.2022 11:44

Я бы удостоверился, что все векторы нормализованы. Я также презираю углы Эйлера, поэтому я бы просто установил ваши векторы вперед / вправо / вверх как строки / столбцы (я не буду искать ведьму) матрицы 4x4, которую затем можно преобразовать в кватернион (который, вероятно, также необходимо нормализовать ). Таким образом, вы можете быть уверены, что вращение точно соответствует вашим векторам, а не возиться с углами Эйлера.

JonasH 28.10.2022 11:58

_ "но я хотел знать математику, стоящую за этим, для учебных целей. Каждый пост, который я проверял, говорил одно и то же, но совсем не объяснял математику" - быстрый поиск . Смотрите также en.wikipedia.org/wiki/3D_projection

user585968 28.10.2022 11:58

Спасибо JonasH за полезный ответ. Я попробую то, что вы сказали позже, и вернусь к вам, если это было решением!

Narc0t1CYM 28.10.2022 12:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

  1. Убедитесь, что все нормализовано, я не думаю, что это строго необходимо, но помогает сохранить небольшие значения.
  2. Добавьте проверку для обработки, если прямое направление и target.up близки к параллельным, и либо выберите какой-либо другой восходящий вектор, либо выдайте ошибку, чтобы вы могли обнаружить проблему.
  3. Постройте матрицу вращения напрямую.

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

Матрица вращения (то есть 3x3) на практике представляет собой всего три ортогональных вектора, это также очень полезный способ визуализации матриц. Я думаю, что каждый вектор должен соответствовать строке в матрице, но я не знаком с единицей, и соглашения могут быть разными.

А матрица 4х4 — это просто матрица поворота + столбец для перевода и лишняя строка. Так что просто используйте SetRow (или SetColumn) для каждого из ваших векторов вперед/вправо/вверх, используя 0 для w-значения вектора 4. Затем вы можете преобразовать матрицу в кватернион, я могу не финансирует такую ​​встроенную функцию в единстве, и это кажется немного странным, но ссылка должна показывать принцип, и должно быть много других статей, которые показывают математику, стоящую за ним.

Спасибо за этот информативный ответ, особенно за ссылки и использование 0 для значений w, потому что я все еще только начинаю изучать математику для 3d. Я принял ваш ответ, потому что, основываясь на предоставленной вами информации, я смогу обойтись!

Narc0t1CYM 28.10.2022 15:59

Другие вопросы по теме