Wie kann ich in Unity riesige Terrains erstellen?


Antworten:


21

Teilen Sie das Gelände in quadratische "Brocken" auf, laden Sie die, die Sie interessieren (meistens: die in der Nähe der aktuell aktiven Kamera) in Update () und - wenn Sie nicht genug Platz haben (wahrscheinlich auch), laden Sie die nicht benötigten Brocken aus der Ferne .

Verwenden Sie vorberechnete Low-Poly-Modelle für weit entfernte Gelände-LoDs, es sei denn, Sie haben nichts dagegen, einen geringen Sichtabstand zu haben. Wenn Sie die Geländehöhenkarte eines weit entfernten Geländes benötigen (z. B. für NPC-Bewegungen oder andere Simulationen), erstellen Sie eine Variante Ihres Geländes mit niedriger oder variabler Auflösung, um den Speicherplatz zu erhalten. Verwenden Sie nicht die vollständigen Geländedaten dafür. Dies kann beim Laden des Spiels automatisch erfolgen. Im Allgemeinen ist es jedoch besser, ein Tool zu erstellen, das diese vorgenerierten Daten während des Builds oder Pakets erstellt.

Zum Schluss: Um Probleme mit der Gleitkommapräzision zu vermeiden, müssen Sie die gesamte Szene jedes Mal neu positionieren, wenn sich Ihre Hauptkamera weit von (0.0f, 0.0f, 0.0f) entfernt.

Möglicherweise relevante Frage zu Unity Answers http://answers.unity3d.com/questions/17225/dynamic-terrain-loading.html


Vielen Dank! gute Antwort. Nur eine Frage: Wenn ich die Nachbarn des Geländes festlege, was würde passieren, wenn die Geländehöhe an den Rändern nicht gleich ist?
Daniel Pendergast

1
@ Dan: Du wirst Löcher in die Landschaft bekommen. Es gibt verschiedene Vorgehensweisen, etwa wie "Stellen Sie sicher, dass die Landschaft an den Rändern dieselbe Höhe hat", "Fügen Sie Röcke hinzu, die vertikal von den Rändern abwärts verlaufen, um die Löcher zu maskieren" und "Fügen Sie generierte Dreiecksstreifen hinzu die Löcher zusammennähen. " Welches Sie verwenden, liegt ganz bei Ihnen (und zum Teil beim Motor). Der zweite mit den Röcken ist der, den ich am häufigsten gesehen habe.
Martin Sojka

1
oder wie gesagt, Sie möchten ein Skript verwenden, um das Gelände zu säumen :-)
Valmond

Hat jemand irgendwelche Skripte?
Daniel Pendergast

@ Dan: Es gibt einige Skripte unter dem Link Unity Answers in der Antwort. Abgesehen davon kann ich Ihnen derzeit nicht mit Code für Unity helfen. Alle meine (Hobby-) Spieleprogramme werden mit Ogre3D als Rendering-Engine erstellt.
Martin Sojka

3

Sie müssen das Gelände in Stücke aufteilen, dh. mehrere kleinere gelände. Sie müssen sich gegenseitig (mit einem Skript) "nähen", damit sich keine "Löcher" zwischen ihnen befinden. Andernfalls können Sie sie sofort ausführen.

Vielleicht möchten Sie auch wissen, dass Sie seit Unity3D ~ 3.0 keine Objekte (Gelände und Objekte lesen) zu weit weg bewegen können (wie +/- 100000 Schritte IIRC), sodass dies die maximale Größe Ihrer Welt beeinflusst.

Ich verwende dies sowieso in meinem Online-RPG-Spiel (mit der Ausnahme, dass ich Unity3D nur für das Level-Design verwende, nicht für das eigentliche Spiel).

Nur weil ich neugierig bin, möchtest du ein paar Informationen über dein Spiel teilen (wie Fortschritt, Typ, Grafik, Stil usw.)?


2

In Unity5 haben wir riesige Terrains implementiert, indem wir SRTM-Daten für die gesamte Erde in Höhenkarten für TerrainDataObjekte mit unterschiedlichen Detaillierungsebenen verarbeitet haben [1]. Es gibt ein paar Dinge zu beachten:

  1. Die Kanten der Höhenkarten müssen sich um mindestens ein Sample überlappen und Sie müssen Ihr Terrain entsprechend positionieren. Terrain.SetNeighborswird das Netz nicht verbinden, sondern nur unterschiedliche Detailebenen berücksichtigen, die von Unity ausgeführt werden.

  2. Sie benötigen notwendigerweise 2 ^ n + 1 Höhenmuster pro TerrainDataObjekt, andernfalls weist Unity den nicht gesetzten Teilen nur eine Höhe von 0 zu.

  3. Wenn Sie weniger als 2 GB haben TerrainData, können Sie davonkommen, dass Sie sie als Assets in einem Ressourcenordner und Resource.Loadzur Laufzeit haben. Wenn Sie mehr als 2 GB haben, funktioniert dieser Ansatz nicht mehr, da mit Unity-Builds nicht mehr als 2 GB Ressourcen zur Verfügung stehen. In diesem Fall müssen Sie AssetBundles erstellen und diese asynchron mit dem WWWObjekt laden . Dies hat den unerwünschten Nebeneffekt, Shader.Parsedass jeweils ein Overhead von ca. 500ms benötigt wird. Ich habe dies in den Foren gemeldet [2] und warte immer noch auf eine Antwort. Ich werde irgendwann einen Fehlerbericht einreichen.

  4. Denken Sie nicht über die Verwendung nach AssetDatabase.LoadAssetAtPath, sie ist nur im Editor und nicht in Unity-Builds verfügbar.

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


0

Es gibt Lösungen von Drittanbietern.

Mit diesem Code können Terrains mit einer Breite von 99.999 Metern erstellt werden. Die Berge sind beliebige Rauschformeln. Sie können jedoch auch 100 Rauschformeln in einer Karte mischen, wenn Sie möchten. In diesem Terrain liegt die Gesamtzahl der auf einer Karte verfügbaren Dreiecke beispielsweise zwischen 66 Millionen, niedriger Auflösung und 200 Millionen mittlerer Auflösung. Hier ist eine 66-Millionen-Dreieckskarte, auf der 0,7 Millionen Dreiecke um die Kamera herum aktualisiert werden. Unityplayer Riesengelände, WASD und Space


Gibt es dafür Quellcode? Ich sehe nur ein Unity-Plugin-Spiel.
AttackingHobo

Ich habe den Quellcode, es hat eine Weile gedauert, bis ich ihn geschrieben habe. ich bin bei ant d0t stewart bei yahoo d0t com
com.prehensible

0

Ich würde empfehlen, Ihr Gelände in Stücke zu laden. Wenn Sie kleinere Terrains verwenden und Ihr Skript möglicherweise mithilfe von transform.position - terrain.transform.position überprüfen kann, ob Sie sich in einer bestimmten Nähe zu Ihrem Terrain befinden. Ich habe tatsächlich einen Blog-Beitrag darüber geschrieben, wie Sie Ihr Spiel als Ganzes optimieren können, und ich habe über das Laden von Chunks gesprochen. Hoffe das hilft.


Beachten Sie, dass dieser Hinweis bereits in der akzeptierten Antwort von Martin Sojka vor 6 Jahren enthalten ist. Wenn Sie nur einen relevanten Link teilen möchten, ist ein Kommentar zu dieser Antwort möglicherweise besser geeignet.
DMGregory

In der Zukunft werde ich. Vielen Dank. Ich bin noch neu in der Veröffentlichung auf Stapelaustausch :)
Hudson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.