Actualmente estoy trabajando en un mundo infinito, inspirado principalmente en Minecraft.
Un trozo consta de bloques de 16x16x16. Un bloque (cubo) es 1x1x1.
Esto funciona muy bien con un ViewRange de 12 Chunks (12x16) en mi computadora. Multa.
Cuando cambio la altura del fragmento a 256, esto se convierte, obviamente, en un retraso increíble.
Entonces, lo que básicamente quiero hacer es apilar trozos. Eso significa que mi mundo podría ser [∞, 16, ∞] pedazos grandes.
La pregunta ahora es cómo generar trozos sobre la marcha.
Por el momento, genero fragmentos no existentes circulares alrededor de mi posición (de cerca a lejos). Como todavía no apilo fragmentos, esto no es muy complejo.
Como nota al margen importante aquí: también quiero tener biomas, con diferente altura mínima / máxima. Entonces, en Biome Flatlands, la capa más alta con bloques sería 8 (8x16); en Biome Mountains, la capa más alta con bloques sería 14 (14x16). Solo como ejemplo.
Lo que podría hacer sería cargar 1 trozo encima y debajo de mí, por ejemplo.
Pero aquí el problema sería que las transiciones entre diferentes bioms podrían ser mayores que una porción en y.
Mi trozo actual cargando en acción
Para completar aquí mi "algoritmo" actual de carga de fragmentos
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;
}
}
fuente
No creo que pueda hacer esto simplemente cargando ciertas capas debido al problema de las transiciones.
Mi inclinación sería almacenar algunos metadatos con cada fragmento:
1) ¿El bloque es completamente aéreo? Si es así, no hay necesidad de renderizarlo.
2) Para cada cara del bloque es opaco. Una cara opaca significa que no necesita considerar el siguiente fragmento. (Tenga en cuenta, sin embargo, que dependiendo de dónde esté el trozo podría haber hasta tres caras involucradas; se debe procesar un trozo si alguna de las tres no es opaca. Sospecho que esto es mejor precalculado). b1 es visible y tiene una cara no opaca f1 o b2 es visible tiene una cara no opaca f2 o b3 es visible tiene una cara no opaca f3).
Desafortunadamente, hay más de 7000 fragmentos dentro de su rango de visión de 12 fragmentos. Sin embargo, esperaría que algunas ubicaciones tengan más de tres fragmentos verticales que en realidad se deben procesar utilizando este enfoque que reduce el recuento de fragmentos a probablemente no más de 1500.
Aplicaría el mismo tipo de lógica dentro de un trozo: cuando cargue un trozo, calcule qué uniones son transparentes y qué uniones son opacas tocando opacas, solo necesita representar caras donde alguien pueda verlas. (Tenga en cuenta que en Minecraft tiene tres tipos de bloque: transparente, opaco y que altera la visión: vidrio, puertas, cercas, etc. Solo puede omitir transparente-transparente y opaco-opaco).
fuente