Преодоление ограничений плавания для миров размером с планету в Unity

8

Насколько я знаю, из-за проблем точности с плавающей запятой вряд ли возможно продвинуться дальше, чем на 1 млн. Единиц от мирового происхождения в Unity.

Создание мира с радиусом более 1 млн. Единиц потребует либо использования doubleпеременных для переменных, либо использования некоторой техники пространственного деления, чтобы разделить массивную сцену на иерархические порции, причем наименьший из них составляет около 10 000 единиц, т.е. каждая позиция в мировом пространстве будет выражена согласно иерархии чанка, объект находится внутри и куча floatпеременных, представляющих его локальное положение (и, возможно, вращение и масштабирование) внутри последнего чанка.

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

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

Спасибо!

Макс Майсак
источник

Ответы:

5

Вы думаете очень статично.

Просто потому, что объект находится на расстоянии полсвета, не требует никаких проблем. Если координаты объекта хранятся относительно куска, а не относительно мира, это тривиально. Добро пожаловать, как если бы вы писали мир вокселей на нативном коде.

Итак, давайте предположим концепцию, называемую locales . Это набор кусков, которые находятся в непосредственной близости друг от друга. Что важно, так это то, что внутреннее пространство поплавка внутри данного региона никогда не превышает предел безопасности. Вам нужно определить, каковы ваши дискретные локали обработки, начните с того, что вы берете все куски, которые попадают в радиус от позиции сущности n (может быть игрок или что-то еще). В моем текущем движке я проверяю, что если хотя бы один фрагмент из двух разных языковых стандартов перекрывается, то эти языковые стандарты объединяются в один языковой стандарт / набор уникальных кусков. Это гарантирует, что вы никогда не обработаете все сущности в каком-либо отдельном блоке более одного раза в данном кадре.

Теперь, когда у вас есть наборы локалей / чанков, вы можете выполнять игровую логику для них и их содержимого. И не важно , как далеко они находятся далеко от игрока или происхождения. Важно то, что вы получаете кусок, который является примерно центральным для каждого набора, рассматриваете его как источник, то есть float[0.0,0.0,0.0], и продолжаете свой путь оттуда. Учитывая типичный диапазон обзора в игре, я гарантирую вам, что вам никогда не понадобится видеть больше нескольких километров, что вполне выполнимо float, без серьезных проблем.

Помимо Unity, одним из вариантов является написать движок с нуля, я думаю, и использовать что-то вроде libfixmath, где вы все еще можете использовать десятичные точки, но, поскольку они не плавают , у них никогда не будет этих проблем с точностью. Но я гарантирую, что вам понадобятся куски и локали по другим причинам, так что это, вероятно, не стоит усилий.

инженер
источник
Вы сказали, что мне никогда не нужно будет видеть больше, чем на расстоянии нескольких километров, но как насчет мира размером с планету, который я должен быть в состоянии полностью наблюдать из космоса (см. Externalra )?
Макс Майсак
@MaksimMaisak Логика игры требует численной точности; рендеринга нет. Вам никогда не нужно будет видеть подробный, точный мир из космоса. Существует определенная высота, на которой вы можете плавно переходить от точной, наземной системы, которую я описал выше, к менее точной, с космической точки зрения, плавно (если вы правильно играете в карты). Но имейте в виду, что есть разница между рендерингом и игровой логикой.
инженер
А как вы делите пространство на куски? Вы начинаете с кусков и группируете их в локали, или начинаете с локалей и делите на куски?
Макс Майсак
Вы начинаете с кусков. «Locales» здесь просто означает «окрестности фрагментов», поэтому концепция фрагмента является обязательным условием.
инженер
Как кусок может быть «перекрывающим» тогда?
Макс Майсак
6

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

Оттуда, что я хотел бы предложить больше всего, это то, что вы читаете удивительную статью по адресу: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.471.7201&rep=rep1&type=pdf . Здесь сравниваются некоторые способы решения проблемы, которую вы описываете (включая локальные координаты, как описано в Arcane Engineer в его ответе), и подробно рассказывается о знаменитом ныне известном решении с плавающей точкой. На самом деле это то, что я бы использовал в большинстве случаев (на самом деле, это то, что я использую в своем приложении).

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

Тем не менее, если вы решите, что вам следует попробовать локальные системы координат (которые могут стать довольно сложным решением в зависимости от того, куда вы идете с этим), тогда второй пункт в моем связанном ответе для вас. Самая важная часть - статья, написанная парнем, который впервые применил это решение в новаторской игре Dungeon Siege: http://scottbilas.com/files/2003/gdc_san_jose/continuous_world_paper.pdf

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

https://www.youtube.com/watch?v=VKWvAuTGVrQ

Надеюсь, поможет.

MAND
источник
3

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

  • Этот недавний доклад CppCon: «Демистификация с плавающей точкой» , который очень актуален независимо от языка программирования. Один очень интересный момент, представленный в отношении точности, заключается в том, что точная точка плавания находится в диапазоне [-1, + 1]. Поэтому нормализованные поплавки - лучший способ, если вы можете их использовать.

  • Еще одно место, в которое вы, возможно, захотите заглянуть, чтобы получить какие-то идеи, - это классическая игра Dungeon Siege . В игре использовалась система непрерывного мира, которая основывалась на узле / плитке, и каждая позиция была относительно текущего узла. Там очень подробно описание системы , используемой в игре в этом техническом документе . Я также написал несколько абзацев об этом в своем блоге . В то время эта схема была нова, но, вероятно, она не так полезна сегодня, в документе, указанном выше, упоминаются некоторые из проблем, которые у них были. Тем не менее, это интересно с исторической точки зрения и может по-прежнему служить вам источником идей и вдохновения.

glampert
источник