Ich arbeite derzeit an einer unendlichen Welt, die hauptsächlich von Minecraft inspiriert ist.
Ein Chunk besteht aus 16x16x16 Blöcken. Ein Block (Würfel) ist 1x1x1.
Dies läuft sehr reibungslos mit einem ViewRange von 12 Chunks (12x16) auf meinem Computer. Fein.
Wenn ich die Chunk-Höhe auf 256 ändere, wird dies offensichtlich zu einer unglaublichen Verzögerung.
Grundsätzlich möchte ich also Brocken stapeln. Das heißt, meine Welt könnte [∞, 16, ∞] Chunks groß sein.
Die Frage ist nun, wie man Brocken im laufenden Betrieb erzeugt.
Im Moment generiere ich nicht vorhandene Brocken, die kreisförmig um meine Position liegen (nah bis fern). Da ich noch keine Chunks staple, ist dies nicht sehr komplex.
Als wichtige Randnotiz hier: Ich möchte auch Biome mit unterschiedlicher Min / Max-Höhe haben. In Biome Flatlands wäre die höchste Schicht mit Blöcken 8 (8x16) - in Biome Mountains wäre die höchste Schicht mit Blöcken 14 (14x16). Nur als Beispiel.
Was ich tun könnte, wäre zum Beispiel 1 Stück über und unter mir zu laden.
Aber hier wäre das Problem , dass Übergänge zwischen verschiedenen Biomen größer als ein Stück auf y sein könnten.
Mein aktueller Chunk wird in Aktion geladen
Der Vollständigkeit halber hier mein aktueller Chunk-Lade- "Algorithmus"
private IEnumerator UpdateChunks(){
for (int i = 1; i < VIEW_RANGE; i += ChunkWidth) {
float vr = i;
for (float x = transform.position.x - vr; x < transform.position.x + vr; x += ChunkWidth) {
for (float z = transform.position.z - vr; z < transform.position.z + vr; z += ChunkWidth) {
_pos.Set(x, 0, z); // no y, yet
_pos.x = Mathf.Floor(_pos.x/ChunkWidth)*ChunkWidth;
_pos.z = Mathf.Floor(_pos.z/ChunkWidth)*ChunkWidth;
Chunk chunk = Chunk.FindChunk(_pos);
// If Chunk is already created, continue
if (chunk != null)
continue;
// Create a new Chunk..
chunk = (Chunk) Instantiate(ChunkFab, _pos, Quaternion.identity);
}
}
// Skip to next frame
yield return 0;
}
}
quelle
Ich glaube nicht, dass Sie dies tun können, indem Sie aufgrund des Problems der Übergänge einfach bestimmte Ebenen laden.
Meine Neigung wäre es, einige Metadaten mit jedem Block zu speichern:
1) Ist der Block vollständig luftig? Wenn ja, müssen Sie es nicht rendern.
2) Für jede Seite des Blocks ist es undurchsichtig. Ein undurchsichtiges Gesicht bedeutet, dass Sie den nächsten Block nicht berücksichtigen müssen. (Beachten Sie jedoch, dass je nachdem, wo sich der Block befindet, bis zu drei Gesichter betroffen sein können - ein Block muss gerendert werden, wenn eines der drei nicht undurchsichtig ist. Ich vermute, dass dies am besten vorberechnet ist - so lange rendern entweder b1 ist sichtbar und hat eine nicht undurchsichtige Fläche f1 oder b2 ist sichtbar hat eine nicht undurchsichtige Fläche f2 oder b3 ist sichtbar hat eine nicht undurchsichtige Fläche f3.)
Es gibt leider über 7000 Chunks in Ihrem Sichtbereich von 12 Chunks. Ich würde jedoch erwarten, dass nur wenige Standorte mehr als drei vertikale Chunks haben, die tatsächlich mit diesem Ansatz gerendert werden müssen, wodurch die Chunk-Anzahl auf wahrscheinlich nicht mehr als 1500 reduziert wird.
Ich würde dieselbe Art von Logik innerhalb eines Blocks anwenden - wenn Sie einen Block laden, berechnen Sie, welche Übergänge transparent und welche Übergänge undurchsichtig sind und sich undurchsichtig berühren - müssen Sie nur Gesichter rendern, bei denen jemand sie sehen kann. (Beachten Sie, dass Sie in Minecraft drei Arten von Blöcken haben - transparent, undurchsichtig und das Sehvermögen verändernd - Glas, Türen, Zäune usw. Sie können nur transparent-transparent und undurchsichtig-undurchsichtig überspringen.)
quelle