Je travaille actuellement sur un monde infini, principalement inspiré de minecraft.
Un chunk est constitué de 16x16x16 blocs. Un bloc (cube) est 1x1x1.
Cela fonctionne très bien avec une ViewRange de 12 morceaux (12x16) sur mon ordinateur. Bien.
Lorsque je change la hauteur du morceau à 256, cela devient - évidemment - un décalage incroyable.
Donc, ce que je veux faire, c'est empiler des morceaux. Cela signifie que mon monde pourrait être [∞, 16, ∞] gros morceaux.
La question est maintenant de savoir comment générer des morceaux à la volée?
Pour le moment, je génère des morceaux non existants circulaires autour de ma position (de près à loin). Comme je n'empile pas encore de morceaux, ce n'est pas très complexe.
Comme remarque importante ici: Je veux aussi avoir biomes, avec différentes hauteurs min / max. Ainsi , dans Biome Flatlands la couche la plus élevée avec des blocs serait 8 (8x16) - dans Biome montagnes la plus haute couche avec des blocs serait 14 (14x16). Comme exemple.
Ce que je pourrais faire serait de charger 1 morceau au-dessus et en dessous de moi par exemple.
Mais ici, le problème serait que les transitions entre différents biomes pourraient être plus grandes qu'un morceau sur y.
Mon chargement de morceaux actuel en action
Pour l'exhaustivité ici, mon "algorithme" de chargement de blocs actuel
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;
}
}
la source
Je ne pense pas que vous puissiez le faire en chargeant simplement certaines couches à cause du problème des transitions.
Ma tendance serait de stocker des métadonnées avec chaque morceau:
1) Le bloc est-il entièrement aérien. Si c'est le cas, il n'est pas nécessaire de le restituer.
2) Pour chaque face du bloc est-elle opaque. Un visage opaque signifie que vous n'avez pas besoin de considérer le prochain morceau. (Notez, cependant, que selon l'endroit où se trouve le morceau, il peut y avoir jusqu'à trois faces impliquées - un morceau doit être rendu si l'un des trois n'est pas opaque. Je soupçonne que c'est mieux pré-calculé - rendu si long soit b1 est visible et a une face non opaque f1 soit b2 est visible a une face non opaque f2 ou b3 est visible a une face non opaque f3.)
Il y a malheureusement plus de 7000 morceaux dans votre plage de vision de 12 morceaux. Cependant, je m'attendrais à ce que peu d'emplacements aient plus de trois morceaux verticaux qui doivent être rendus en utilisant cette approche qui réduit le nombre de morceaux à probablement pas plus de 1500.
J'appliquerais le même type de logique au sein d'un morceau - lorsque vous chargez un morceau, calculez quelles jonctions sont transparentes et quelles jonctions sont opaques touchant opaques - il vous suffit de rendre les faces où quelqu'un peut les voir. (Notez que dans Minecraft, vous avez trois types de blocs - transparents, opaques et altérant la vision - verre, portes, clôtures, etc. Vous ne pouvez ignorer que transparent-transparent et opaque-opaque.)
la source