Аэродинамика в Unity ч.2
В первой части я рассказал о том, как с помощью Unity заставил самолёт взлететь. Сейчас речь пойдёт о том, как я приделал к нему штурвал. И на какие ухищрения пришлось пойти в реализации аркадной физики моего летательного аппарата.
Маневры
Для управления самолётом в воздухе есть три основных манёвра.
Крен (Roll) — Поворот самолёта вокруг своей продольной оси
Рысканье (Yaw) — Поворот самолета вокруг своей вертикальной оси
Тангаж (Pitch) — Поворот самолёта вокруг своей поперечной оси
Реализация
Немного о структуре прототипа.
AircraftController — MonoBehaviour, который принимает ввод игрока и в обработчике Update передаёт эти данные в объект currentAircraft.
В каждом FixedUpdate рассчитывается физика самолёта. Вообще - я реализовал это в отдельном MonoBehaviour, но в контексте поста это неважно.
AircraftModel — класс, реализующий сущность самолёта. Содержит в себе несколько полей, каждое из которых отвечает за свою область. А также собирает и спавнит самолёт по префабу в своём конструкторе.
AircraftData — наследует у ScriptableObject. Я его использую для хранения всех характеристик самолёта. Мощность двигателя, площадь крыла, масса и так далее.
AircraftControlState — Содержит данные о текущем состоянии рулей управления а также текущую тягу двигателя. Не путать с AircraftController, который получает от игрока нажатые кнопки.
AircraftPhysics — Самый интересный для нас класс. Методы приведенные в первой части как раз отсюда. В конце поста я размещу класс целиком. А до этого тезисно опишу, какие он претерпел изменения после предыдущего поста, и что нового я туда добавил.
Что изменилось?
Во-первых, я добавил в класс AircraftPhysics пять полей класса Transform. Они предназначены для хранения определённых точек самолёта. Нос, хвост, два крыла и центр масс. К этим точкам мы будем применять силы.
ThrustForce_calculate — сила тяги теперь воздействует на точку носа самолёта. Более реалистично, т.к. сила прикладывается именно пропеллером.
DragForce_calculate — сила сопротивления теперь зависит от угла отклонения. Чем больше самолёт повернут от потока воздуха, тем больше площадь сопротивления. Регулируется minDrag и maxDrag из aircraftData.
LiftForce_calculate — Подъёмная сила теперь применяется на три точки: два крыла и хвостовой стабилизатор. Это помогло мне стабилизировать взлёт и посадку. Также в расчете подъёмной силы теперь участвует угол атаки крыла, и предусмотрен срыв потока (когда угол атаки становится слишком большим подъемная сила резко падает).
Что добавлено?
Управление
PitchForce_calculate — передаётся сила для тангажа, действует на хвост самолёта. Считается по аналогии с подъёмной силой.
YawForce_calculate — передаётся сила для рысканья. Изначально прилагал эту силу на хвост, т. к. за этот манёвр вроде как отвечает поворот вертикального стабилизатора, но у меня не получилось это сделать нормально, и самолёт как будто носило боком. Так что теперь сила действует на центр масс, направлена в сторону поворота под прямым углом.
RollForce_calculate — передаётся сила для крена самолета. Прилагается сразу на оба крыла. На одно вниз, на второе — вверх. Сюда добавил сопротивление, которое зависит от угловой скорости самолёта вокруг своей оси. Без него в бочке самолёт неоправданно быстро закручивался.
Стабилизация
stabPitchForce_calculate, stabYawForce_calculate, stabRollForce_calculate — Все три метода сообщают самолёту вращающий момент, который зависит от угловой скорости в каждой из трех осей отдельно.
По сути в этих методах происходит перманентное притормаживание тангажа, ролла и рысканья. Оно линейно и зависит только от угловой скорости и постоянного коэффициента, поэтому совсем не реалистично, но это самый простой способ остановить вращение самолёта после манёвра.
Если игрок жмёт клавишу крена, он ждёт, что крен прекратится после того, как он отпустит кнопку. Для этого тут эти методы.
StabilizeForce_calculate — это, наверное, самое большое моё упрощение. Мне нужно было добиться того, чтобы самолёт выравнивался по вектору скорости. Я пытался выдумать аналоги подъемной силы, которые действуют на вертикальный и горизонтальный стабилизаторы в зависимости от отклонения, но настроить параметры у меня не получилось.
В итоге я пришёл к тому, чтобы применять на самолёт две силы одинаковой величины. Одна действует на нос самолёта и направлена по вектору скорости. Вторая действует на центр масс и направлена в противоположную сторону.
Идея в том, что две силы уравновешивают друг друга по продольной оси самолёта, но создают момент, который возвращает самолёт на вектор скорости. Чем больше отклонение, тем больше момент. Величина силы считается по формуле подъёмной силы, так как в моём понимании она зависит также от потока воздуха, но параметры стабилизации мы используем отдельные.
В предыдущих трех видео тоже можно наблюдать эту силу, я обозначил её оранжевым цветом.
Таким образом я реализовал управление самолётом. Понятно, что нужно будет доводить до ума, но для прототипа достаточно.
Спасибо за внимание!
В своём телеграм-канале я регулярно делюсь прогрессом
Также, если кому-то интересно, привожу класс AircraftPhysics полностью