Surmonter les limitations des flotteurs pour les mondes de la taille d'une planète dans Unity


8

Pour autant que je sache, aller plus loin que 1 million d'unités d'origine mondiale dans Unity n'est guère possible en raison de problèmes de précision en virgule flottante.

Pour créer un monde de plus d'un million d'unités dans un rayon, il faudrait soit utiliser des doublevariables pour les coordonnées, soit utiliser une technique de division spatiale pour diviser une scène massive en morceaux hiérarchiques, le plus petit d'entre eux étant d'environ 10 000 unités, c'est-à-dire que chaque position de l'espace mondial serait exprimée par la hiérarchie des morceaux, l'objet est floatdedans et un tas de variables représentant sa position locale (et éventuellement la rotation et la mise à l'échelle) à l'intérieur du dernier morceau.

Quoi qu'il en soit, cela nécessiterait la mise en œuvre d'un tout nouveau système de coordonnées, donc j'aimerais savoir si cela est possible dans Unity, et si oui, comment puis-je le faire fonctionner avec les systèmes Unity existants comme la physique, etc.

PS Je ne peux pas simplement déplacer le monde vers son origine pendant que le joueur bouge car je veux que les choses se passent simultanément autour de la planète.

Merci!

Réponses:


5

Vous pensez en termes très statiques.

Tout simplement parce qu'un objet est à l'autre bout du monde ne nécessite aucun problème. Si les coordonnées d'entité sont stockées par rapport à un morceau plutôt que par rapport au monde, cela est trivial à réaliser. Bienvenue à la façon dont vous devriez le faire si vous écriviez un monde voxel en code natif.

Supposons donc un concept appelé locales . C'est un ensemble de morceaux qui sont très proches les uns des autres. Ce qui compte, c'est que l'espace flottant interne à un lieu donné ne dépasse jamais la limite de sécurité. Vous devez déterminer quels sont vos paramètres régionaux de traitement discrets, commencez par prendre tous les morceaux qui se trouvent dans un rayon de la position de l'entité n (pourrait être le joueur ou autre chose). Dans mon moteur actuel, je m'assure que si même un bloc de deux paramètres régionaux différents se chevauchent, ces paramètres régionaux fusionnent en un seul paramètre régional / ensemble de blocs uniques. Cela garantit que vous ne traitez jamais toutes les entités dans un même bloc plus d'une fois, dans une trame donnée.

Maintenant que vous avez vos locales / chunk-sets, vous pouvez exécuter la logique du jeu sur eux et leur contenu. Et peu importe à quelle distance ils sont éloignés du joueur ou de l'origine. Ce qui importe, c'est que vous obteniez un morceau qui est à peu près au centre de chaque ensemble, que vous le floattraitiez comme l'origine, c'est-à-dire [0.0,0.0,0.0], et que vous vous dirigiez vers l'extérieur à partir de là. Étant donné la portée de vue typique dans un jeu, je vous garantis que vous n'aurez jamais besoin de voir plus de quelques kilomètres, ce qui est très faisable avec float, sans problèmes graves.

Mis à part Unity, une option consiste à écrire un moteur à partir de zéro, je suppose, et à utiliser quelque chose comme libfixmath, où vous pouvez toujours utiliser des points décimaux mais parce qu'ils ne flottent pas , ils n'auront jamais ces problèmes de précision. Mais je vous garantis que vous aurez besoin de blocs et de paramètres régionaux pour d'autres raisons, donc cela ne vaut probablement pas la peine.


Vous avez dit que je n'aurais jamais besoin de voir à plus de quelques kilomètres, mais qu'en est-il d'un monde de la taille d'une planète, que je devrais pouvoir observer pleinement depuis l'espace (voir extérieur )?
Maks Maisak

@MaksimMaisak La logique du jeu nécessite une précision numérique; le rendu ne fonctionne pas. Vous n'aurez jamais besoin de voir le monde détaillé et précis de l'espace. Il y a une certaine hauteur à laquelle vous pouvez passer du système précis sur le terrain que j'ai décrit ci-dessus à la perspective d'espace moins précise, de manière transparente (si vous jouez correctement vos cartes). Mais gardez à l'esprit qu'il y a une différence entre le rendu et la logique du jeu.
Ingénieur

Et comment divisez-vous l'espace en morceaux? Commencez-vous avec des morceaux et regroupez-les en paramètres régionaux, ou commencez-vous avec des paramètres régionaux et divisez-vous en morceaux?
Maks Maisak

Vous commencez avec des morceaux. «Locales» signifie ici simplement «quartiers de morceaux», donc le concept de morceau est la condition préalable.
Ingénieur

Comment un morceau peut-il alors «se chevaucher»?
Maks Maisak

6

C'est une question qui revient fréquemment. Je prendrai la liberté de vous transmettre une autre réponse assez détaillée que j'ai déjà donnée au même problème, au lieu de simplement la répéter ici: Un système de coordonnées personnalisé est-il possible dans Unity

À partir de là, ce que je suggérerais le plus, c'est que vous lisiez cet article étonnant sur: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.471.7201&rep=rep1&type=pdf . Il compare certaines des façons de résoudre le problème que vous décrivez (y compris les coordonnées locales, comme décrit par Arcane Engineer dans sa réponse) et donne des détails sur la célèbre solution d'origine flottante de nos jours. C'est, en fait, ce que j'irais dans la plupart des cas (en fait, c'est ce que j'utilise dans mon application).

Bien sûr, vous avez mentionné que la solution d'origine flottante ne répond pas à vos besoins. Mais cela peut ne pas être le cas même si vous voulez que les choses continuent de se produire dans des régions très éloignées du monde. Vous pouvez avoir à peu près n'importe quelle IA se produisant où vous le souhaitez - vous ne devriez pas faire de vérifications de collision ou de positionnement précis trop loin du joueur (c'est-à-dire au-delà du seuil d'imprécision du flotteur). Mais de toute façon, franchement, dans les applications réelles, vous ne pourriez probablement jamais avoir autant de collisions et de positionnement dans un jeu en raison des limitations de traitement. Et encore, il pourrait y avoir des solutions à cette limitation que vous voyez sur la solution d'origine flottante, selon les caractéristiques de votre jeu. Encore une fois, je vous suggère de ne pas jeter cette solution avant une lecture plus approfondie à ce sujet.

Pourtant, si vous décidez d'essayer des systèmes de coordonnées locaux (ce qui peut devenir une solution assez complexe selon où vous allez avec), alors le deuxième élément de ma réponse liée est pour vous. L'élément le plus important est le document écrit par le gars qui a mis en œuvre cette solution pour la première fois dans le jeu pionnier Dungeon Siege: http://scottbilas.com/files/2003/gdc_san_jose/continuous_world_paper.pdf

Il y a aussi une vidéo d'il y a quelques années, où des gens de Unity commentent cette solution et expliquent même une implémentation moderne du concept dans Unity:

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

J'espère que cela aide.


3

Je ne sais pas si vous avez déjà opté pour une solution, mais je voudrais mentionner deux autres ressources qui pourraient être utiles à vous et à d'autres lecteurs à l'avenir.

  • Cette récente conférence CppCon: "Demystifying Floating Point" , qui est très pertinente quel que soit le langage de programmation. Un point très intéressant présenté à propos de la précision est que le point idéal de la précision du flotteur se situe entre [-1, + 1]. Les flotteurs normalisés sont donc la meilleure façon de procéder si vous pouvez les utiliser.

  • Un autre endroit dans lequel vous voudrez peut-être chercher des idées est le jeu classique Dungeon Siege . Le jeu a utilisé un système mondial continu basé sur un nœud / tuile et chaque position était relative au nœud actuel. Il y a une description très détaillée du système utilisé par le jeu dans ce livre blanc . J'ai également écrit quelques paragraphes à ce sujet dans mon blog . Cette configuration était nouvelle à l'époque, mais elle n'est probablement pas aussi utile aujourd'hui, le document lié ci-dessus mentionne quelques-uns des problèmes rencontrés. Néanmoins, il est intéressant d'un point de vue historique et pourrait encore vous servir de source d'idées et d'inspiration.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.