[C#] Creando un terreno procedural (infinito) en Unity3D con CoherentNoise

Iniciado por z3nth10n, 3 Diciembre 2013, 20:52 PM

0 Miembros y 1 Visitante están viendo este tema.

z3nth10n

Hola buenas, pues hago este tema aquí ya que Unity3D (tiene 3 lenguajes de scripting) y yo he usado C#, y como los de la página no me contestan, pues hago como siempre, pregunto por aquí...

A lo mejor al título le sobraba lo de infinito, ya que bueno, pues un terreno generado proceduralmente suele ser infinito...

Y yendo al tema, pues me gustaría que me dieseis ideas de como podría lograr esto, yo tengo esta Class que me genera el terreno infinitamente:

http://subversion.assembla.com/svn/coherentnoise/

Pues bueno, puede ser el Ruido más coherente del mundo, pero cuando le cambias el Terreno va como pollo sin cabeza.. xD

Y bueno, pues me gustaría retocar un poco esta función: http://subversion.assembla.com/svn/coherentnoise/trunk/CoherentNoise/Generation/Fractal/FractalNoiseBase.cs

Código (csharp) [Seleccionar]
public override float GetValue(float x, float y, float z)
{
float value = 0;
float signal = 0;

x *= Frequency;
y *= Frequency;
z *= Frequency;

for (int curOctave = 0; curOctave < OctaveCount; curOctave++)
{
// Get the coherent-noise value from the input value and add it to the
// final result.
signal = m_Noise.GetValue(x, y, z);
// äåôîëòíûé ïåðëèí - ñêëàäûâàåò âñå çíà÷åíèÿ ñ óìåíüøàþùèìñÿ âåñîì
value = CombineOctave(curOctave, signal, value);

// Prepare the next octave.
// scale coords to increase frequency, then rotate to break up lattice pattern
var rotated = s_Rotation*(new Vector3(x, y, z) * Lacunarity);
x = rotated.x;
y = rotated.y;
z = rotated.z;
}

return value;
}


Y como yo pa esto de las matemáticas soy un poco cazurro (ojo soy bueno, pero a tanto no llego) vosotros que sois mayores que yo, me gustaría que me echaseis una mano, para poder o por o menos intentar que mi Terreno infinito sea coherente por todas partes... El código del terreno infinito os lo dejo por este Pastebin:

http://pastebin.com/E4cZ3nUv

Y el código que lo genera todo:

Código (csharp) [Seleccionar]
   static void GenerateHeights(Terrain terrain, int last)
           {
   
               var Pink = seed;
               var n = new CoherentNoise.Generation.Fractal.PinkNoise(Pink) ; //213321
             
               float[,] heights = new float[terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight];
             
               for (int i = 0; i < terrain.terrainData.heightmapWidth; i++) //terrain.terrainData.heightmapWidth * lastChunkCharged
               {
                   for (int k = 0; k < terrain.terrainData.heightmapHeight; k++) //terrain.terrainData.heightmapHeight * lastChunkCharged
                   {
                       var x = n.GetValue((((float)i + terrain.terrainData.heightmapWidth * last) / ((float)terrain.terrainData.heightmapWidth * last)) * tileSize, (((float)k + terrain.terrainData.heightmapHeight * last) / ((float)terrain.terrainData.heightmapHeight * last)) * tileSize, 0);
                       heights[i, k] = x / 5 + baseLine;
                   }
               }
             
               terrain.terrainData.SetHeights(0,0, heights);
             
           }


Os explico como funciona un poco esto de los Noises, el n.GetValue ahí arriba, devuelve un valor entre 0 y 1, y a eso se lo aplica a la altura máxima del mapa con una regla de 3...

Mi lógica es la siguiente (esto lo puedo explicar mejor en Español, por que en inglés me veo negro), se supone que X funciona la de FractalNoiseBase.cs (GetValue) da un valor entre 0 y 1 en relación a las coordenadas, si hago un sistema, en el que se cuenten los terrenos cargados y se aplique a estos pues debería cargar algo ordenador, es que si no, por cada terreno que se cargue empezaría el ciclo desde 0 a contar y si hago eso siempre se va a generar lo mismo siempre, puesto que las posiciones van a ser 0, 1, 2, ..., 125 (resolución maxima de los detalles del apa) y vuelta a empezar con el siguiente mapa, 0, 1, 2, ... 125, entonces, necesito saber porque no va...

Otra cosa curiosa es que tengo un NullReferenceException, en donde antes no lo tenía, (yo creo que ha sido al introducir el nuevo parametro en la función GetHeights llamado last que resulta que por alguna razon no lo introducto bien):

Código (csharp) [Seleccionar]
float[,] heights = new float[terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight];

Si le quitamos el parametro last, no nos da ningún error, y es algo que me ralla bastante por no sabe, porque da ese error solo por un parametro...

A ver, si los mas pros del foro en lo que C# se refiere me pueden echar un cable...

Gracias, y un saludo.
:-\

Interesados hablad por Discord.

USLO

Hola que pasa Ikillnukes !
Cuando cargas el terreno o cuando llamas a la funcion de carga del terreno.(En que momento lo cargas?En el update en el Load principal? ).
Yo cargaria el mapa en el load.luego hazte tu algoritmo de descargar terreno y cargar nuevo terreno(Cada vez que salga de un extremo .)La mejor forma de hacerlo , es dibujando los terreno y ecribiendo tu metodologia.

z3nth10n

Gracias USLO pero ya solucione el error con otro code de por ahí...

Interesados hablad por Discord.