Пост

Дневник разработки: сетябрь

Битва за хорошую физику, часть 1

Добрый день!

Сентябрь вышел очень продуктивным месяцем, потому что гораздо проще работать, не выходя на улицу, когда за окном плотная серая пелена из туч, срывается дождь, а столбик термометра не поднимается выше +5 °C. За это время мне удалось решить самую сложную задачу в моей жизни: физику ракет.

Я много раз говорил, что возможность планировать полеты и выполнять их без прямого управления игрока, а также реальный масштаб Солнечной системы — это основные фичи игры. Но они в том числе накладывают некоторые ограничения.

Например, из-за точности чисел с плавающей точкой в PhysX, все вычисления физики для ракет с включенным двигателем должны выполняться не далее, чем в 10 километрах от начала координат. Иначе постоянно накапливающиеся ошибки во время вычислений будут приводить к дрожанию корабля и его сходу с орбиты, а в худшем придет Кракен и всё уничтожит. Обычно это решается постоянным перемещением всего мира вокруг корабля, и таким образом он остается недалеко от центра координат.

Представьте, что изображенная сфера — это Земля. Тогда размер площади пространства, по которому корабль может спокойно летать, перед тем, как мы вынуждены будем сдвинуть весь мир, будет меньше одного пикселя!

Но смотрите, какая возникает проблема. Представьте, что у вас есть два корабля: один на орбите Марса, а второй около Земли. Среднее расстояние между ними будет составлять 225 миллионов километров. И так получилось, что они одновременно включают двигатели. Что делать в этом случае? Невозможно переместить один мир, таким образом, что оба корабля одновременно находились у начала координат. Значит придется пожертвовать одним из кораблей, перемещая другой в начало координат, потому что ошибки вычислений будут настолько большими, что любая ракета почти мгновенно врежется в планету. Или игра в принципе не должна допускать возникновения подобной ситуации, но это рушит весь смысл планирования полетов.

Изначально я пробовал реализовать простую физику полета в числах двойной точности. Вышло неплохо и даже работало для небольших ракет с одним двигателем и выдавало очень точные результаты. Но потом я дошел до списка задач, которые нужно было еще реализовать:

  • Несколько двигателей, расположенных в разных местах ракеты и с разными силами, влияющими на ракету.
  • Базовая аэродинамика.
  • Столкновения с поверхностью планет и другими кораблями.

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

Я начал искать возможные варианты решения. И, спустя три месяца, оно нашлось в неожиданном месте. Менее года назад в Unity добавили поддержку нескольких физических сцен (или физических миров). Это значит, что у меня появлялась возможность запускать несколько физических симуляций, причем они никак между собой не будут взаимодействовать. Таким образом, для вышеописанного случая с двумя кораблями, мне всего лишь нужно создать два физических мира, поместить в них физическое представление ракет, переместить мир в каждой симуляции таким образом, чтобы корабли оказались у начала координат, выполнить вычисления и затем синхронизировать результаты с видимым миром. Звучит просто, не так ли? Нет, это чертовски сложно. Но все же гораздо проще, чем переизобретение физического движка.

На данном изображении корабли находятся далеко друг от друга и каждый из них обрабатывается в отдельной физической сцене (большая зеленая сфера)

Но каким образом корабли будут взаимодействовать друг с другом, если они расположены в разных симуляциях? Это хороший вопрос. Если два или более корабля приближаются друг к другу и расстояние между ними станет меньше шести километров, я помещу оба корабля в один физический мир. Если расстояние превысит это число, то я верну их в свои собственные миры. И благодаря тому, что я выполняю все вычисления для всей ракеты целиком, а не отдельно для каждой из ее деталей, все это достаточно быстро работает даже на моем пятилетнем компьютере. Конечно же, там есть еще что оптимизировать, но это будет основной задачей для Раннего доступа.

В этом случае корабли приближаются друг к другу и мы перемещаем второй в симуляцию первого

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

Спасибо за внимание и не забудьте присоединиться к нашему сообществу в Дискорде!

P.S. Две недели назад Valve в очередной раз изменила алгоритмы магазина, после чего трафик на странице игры практически упал до 0. Если у вас есть друзья, которые любят космос и ракеты, пожалуйста отправьте им ссылку на страницу игры. Вы — моя единственная надежда.

Авторский пост защищен лицензией CC BY 4.0 .

© unbeGames. Некоторые права защищены.

Популярные теги