Comment créer d'énormes terrains dans Unity?

19

Comment créer des terrains extrêmement immenses dans Unity? Il semble que je puisse régler la largeur et la longueur sur de grandes valeurs. Mais la résolution Heightmap ne monte que jusqu'à 4097 et la résolution Detail ne monte que jusqu'à 4048.

Des idées?

Daniel Pendergast
la source
Je suis désolé d'être un buzzkill: sol.gfxile.net/mmorpg.html
Nailer

Réponses:

21

Divisez le terrain en «morceaux» carrés, chargez ceux qui vous intéressent (principalement: ceux près de la caméra actuellement active) dans Update () et - si vous êtes à court d'espace (vous le serez probablement), déchargez loin ceux qui ne sont pas nécessaires .

Utilisez des modèles low-poly pré-calculés pour les LoD de terrain lointains, sauf si cela ne vous dérange pas d'avoir une faible distance de vision. De plus, si vous avez besoin de la carte de hauteur du terrain pour un terrain éloigné pour quelque chose (comme le mouvement d'un PNJ ou une autre simulation), créez une variante à basse résolution ou à résolution variable de votre terrain à garder en mémoire; n'utilisez pas les données complètes du terrain pour cela. Cela peut être fait automatiquement lors du chargement du jeu, mais généralement c'est une meilleure idée de créer un outil qui crée ces données pré-générées lors de la construction ou du package.

Enfin: pour éviter les problèmes de précision en virgule flottante, vous devrez repositionner toute la scène à chaque fois que votre caméra principale s'éloigne (0,0f, 0,0f, 0,0f).

Question éventuellement pertinente sur Unity Answers http://answers.unity3d.com/questions/17225/dynamic-terrain-loading.html

Martin Sojka
la source
Je vous remercie! très bonne réponse. Juste une question, quand je place les voisins des terrains, que se passerait-il si les terrains n'étaient pas à la même hauteur sur les bords?
Daniel Pendergast
1
@Dan: Vous obtiendrez des trous dans le paysage. Il existe différentes manières de gérer cela, à peu près le long de la ligne "assurez-vous que le paysage a la même hauteur sur les bords", "ajoutez des jupes verticales à partir des bords vers le bas sur une certaine hauteur pour masquer les trous" et "ajoutez des bandes triangulaires générées" pour assembler les trous. " Lequel vous utilisez dépend de vous (et du moteur, en partie). La seconde, avec les jupes, est celle que j'ai vue le plus souvent.
Martin Sojka
1
ou comme je l'ai dit, vous aimeriez utiliser un script pour assembler les terrains :-)
Valmond
Quelqu'un at-il des scripts?
Daniel Pendergast
@Dan: Il y a quelques scripts sur le lien Unity Answers dans la réponse. En plus de cela, je ne peux pas vous aider avec le code pour Unity pour le moment, toute ma programmation de jeu (de niveau amateur) se fait avec Ogre3D comme moteur de rendu.
Martin Sojka
3

Vous aurez besoin de briser les terrains en morceaux, c'est à dire. plusieurs terrains plus petits. Vous aurez besoin de `` coller '' ces uns contre les autres (avec un script) afin qu'il n'y ait pas de `` trous '' entre eux, sinon vous pouvez simplement commencer à les faire tout de suite.

Vous voudrez peut-être aussi savoir que depuis Unity3D ~ 3.0, vous ne pouvez pas déplacer les éléments (lire les terrains et les objets) trop loin (comme +/- 100000 pas IIRC), donc cela influencera la taille maximale de votre monde.

Je l'utilise de toute façon dans mon jeu de RPG en ligne (à l'exception que j'utilise uniquement Unity3D pour la conception de niveaux, pas pour le jeu réel).

Juste parce que je suis curieux, souhaitez-vous partager des informations sur votre jeu (comme l'avancement, le type, les graphiques, le style, etc.)?

Valmond
la source
2

Nous avons implémenté d'énormes terrains dans Unity5 en traitant des données SRTM pour la terre entière en cartes de hauteur pour des TerrainDataobjets avec différents niveaux de détails [1]. Il y a deux ou trois choses à considérer:

  1. Les bords mêmes des cartes de hauteur doivent se chevaucher d'au moins un échantillon et vous devez positionner vos terrains en conséquence. Terrain.SetNeighborsne connectera pas le maillage, ne tient compte que des différents niveaux de détails effectués par Unity.

  2. Vous avez nécessairement besoin de 2 ^ n + 1 échantillons de hauteur par TerrainDataobjet, sinon Unity attribuera simplement une hauteur de 0 aux parties non définies.

  3. Si vous en avez moins de 2 Go TerrainData, vous pouvez vous en passer en les ayant en tant qu'actifs dans un dossier de ressources et en Resource.Loadles exécutant. Si vous avez plus de 2 Go, cette approche ne fonctionnera plus car il ne peut pas y avoir plus de 2 Go de ressources avec les versions Unity. Dans ce cas, vous devrez créer des AssetBundles et les charger de manière asynchrone avec l' WWWobjet. Cela a pour effet secondaire indésirable d'appeler Shader.Parsechacun d'eux avec une surcharge d'environ 500 ms. J'ai signalé cela sur les forums [2] et j'attends toujours une réponse. Je soumettrai éventuellement un rapport de bogue.

  4. Ne pensez pas à l'utiliser AssetDatabase.LoadAssetAtPath, il n'est disponible que dans l'éditeur et non dans les builds Unity.

[1] https://www.youtube.com/watch?v=2UsyVuWoFbQ
[2] http://forum.unity3d.com/threads/shader-parse-delays-loading-of-assetbundle-containing-no-shader .358235 /

sradomski
la source
0

Il existe des solutions tierces.

ce code peut créer des terrains d'une largeur de 99 999 mètres, les montagnes sont des formules de bruit, mais vous pouvez mélanger 100 formules de bruit dans une carte si vous le souhaitez. par exemple, sur ce terrain, le nombre total de triangles disponibles sur une carte est compris entre 66 millions, basse résolution et 200 millions moyenne résolution. voici une carte triangulaire de 66 millions, où des triangles de 0,7 million sont mis à jour autour de la caméra. terrain géant d'unité, WASD et espace

compréhensible
la source
Existe-t-il du code source pour cela? Tout ce que je vois, c'est un jeu de plugin d'unité.
AttackingHobo
j'ai le code source, il m'a fallu un certain temps pour écrire. je suis chez ant d0t stewart chez yahoo d0t com
com.prehensible
0

Je recommanderais de charger votre terrain en morceaux. En utilisant des terrains plus petits, et peut-être que votre script pourrait vérifier si vous êtes à une certaine proximité de votre terrain en utilisant transform.position - terrain.transform.position. J'ai en fait écrit un article de blog sur la façon d'optimiser votre jeu dans son ensemble, et j'ai parlé du chargement de blocs. J'espère que cela t'aides.

Hudson
la source
Notez que ce conseil est déjà présent dans la réponse acceptée de Martin Sojka d'il y a 6 ans. Si vous souhaitez simplement partager un lien pertinent, un commentaire sur cette réponse pourrait être plus approprié.
DMGregory
À l'avenir, je le ferai. Je vous remercie. Je suis encore nouveau pour publier sur l'échange de pile :)
Hudson