En esta serie de tutoriales que se va a generar procesalmente niveles usando la unidad. En el primer tutorial vamos a utilizar de ruido pseudoaleatorio para generar mapas de altura y selecciona terreno tipos de acuerdo a la altura en cada parte de nuestro nivel. En los próximos tutoriales, vamos a biomas asignar para cada parte del nivel y, al final, vamos a generar un objeto de mapa de nivel que todavía se puede editar manualmente de acuerdo a las necesidades del juego.

Esta serie de tutoriales se inspira y se expande sobre técnicas presentadas por Sebastian Lague, Holistic3D y esta charla GDC en la generación de procedimiento en No Man Sky.

resto de la serie:. Parte 2, parte 3
No se pierda! extremos de la oferta en

  • Accede a los más de 200 cursos
  • Nuevos cursos añadió mensual
  • Cancelar en cualquier momento
  • Los certificados de terminación

    ACCESO ahora

    Con el fin de seguir este tutorial, que se espera que esté familiarizado con los siguientes conceptos:


    • programación C #
    • conceptos unidad básica, como la importación de bienes, la creación de casas prefabricadas y la adición de componentes

      Antes de comenzar a leer el tutorial, crear un nuevo proyecto de la Unidad.

      Tabla de contenidos

      archivos de código fuente

      Puede descargar los archivos de código fuente tutorial aquí.

      Generación de ruido

      Con el fin de generar niveles de procedimiento, vamos a funciones de ruido uso en nuestro código. Una función de ruido es básicamente una función que genera valores pseudoaleatorios basado en algunos argumentos de entrada. Por pseudoaleatoria que significa los valores miran al azar, a pesar de ser generada de forma algorítmica. En la práctica, se puede ver este ruido como una variable, que puede ser utilizado como los valores de altura, temperatura o humedad de una región de nivel. En nuestro caso, vamos a utilizarlo como la altura de las diferentes coordenadas de nuestro nivel.

      Hay diferentes funciones de ruido, pero vamos a utilizar uno especialmente popular llamado Ruido Perlin. No es necesario para entender completamente Ruido Perlin, puesto que la unidad proporciona una IMPLEMENTACIÓN ella. Lo que voy a explicar en este tutorial es la forma en que se puede utilizar en el código.

      Por lo tanto, vamos a empezar por la creación de una secuencia de comandos que vamos a generar un mapa de ruido. En primer lugar, crear un nuevo script llamado NoiseMapGeneration. Esta secuencia de comandos tendrá una función llamada GenerateNoiseMap, que recibirá como parámetros la altura mapa, mapa y ancho de una escala. Entonces, se generará una matriz que representa un mapa de ruido, con el ruido en cada coordenada del nivel.

      Para cada coordenada, que generan el ruido vaue usando la función Mathf.PerlinNoise. Esta función recibe dos parámetros y generar un valor entre 0 y 1, que representa el ruido. Tenga en cuenta que vamos a utilizar los ejes X y Z para acceder a las coordenadas de nivel, mientras que el eje y se puede utilizar para cambiar la altura de nuestro nivel en una coordenada dada. Por lo tanto, los parámetros de la función perlinNoise serán los índices x, z dividido por la escala de nivel. En la práctica, el parámetro de escala de nivel actúa como un parámetro de zoom en el nivel. Al final, se devuelve el mapa de ruido.
      NoiseMapGeneration clase pública: MonoBehaviour {float pública [,] GenerateNoiseMap (int mapDepth, int mapWidth, la escala de flotación) {// crear un mapa de ruido vacío con el mapDepth y mapWidth coordina flotador [,] noiseMap = new float [mapDepth, mapWidth]; for (int zIndex = 0; zIndex Ahora necesitamos alguna manera de visualizar este mapa de ruido. Lo que vamos a hacer es crear un plano GameObject para representar un azulejo en nuestro nivel. Entonces, podemos mostrar los valores de ruido generados por la pintura de los vértices de baldosas de acuerdo con sus valores de ruido correspondientes. Una vez más, este ruido puede representar cualquier cosa que desee, tales como la altura, Temperatura, humedad, etc. En nuestro caso, se representará la altura de ese vértice.

      Creación de baldosa de nivel

      Empecemos mediante la creación de un nuevo plano (objetos 3D -> Plane) objeto llamado Nivel del azulejo. Esto creará el objeto más adelante, ya con una malla Renderizador, que vamos a utilizar para mostrar el mapa de ruido.

      Nivel Tile objeto en el Inspector Unidad

      Antes de mostrar el mapa de ruido en el azulejo, es importante que usted entienda cómo una malla de plano se parece. La siguiente figura muestra el un plano creado en la unidad junto con su malla. Observe que los vértices de malla no son sólo los cuatro vértices avión. En lugar de ello, la malla contiene varios vértices intermedios que están conectados en el interior del avión. Básicamente, lo que vamos a hacer es el uso de cada uno de los vértices como coordenada para nuestro mapa de ruido más tarde. De esta manera, se puede asignar un color a cada vértice (que será una altura más tarde) de acuerdo con cada valor de ruido generado.

      cuadrícula azulejo en vista Escena Unidad

      Ahora, vamos a crear el siguiente script llamado TileGeneration. Este script será responsable de generar un mapa de ruido para el azulejo y luego asignar una textura a la misma de acuerdo con el mapa de ruido. Como este mapa de ruido se utiliza para alturas asignar a cada vértice, de ahora en adelante voy a llamarlo un mapa de altura .

      En primer lugar, el aviso de que el guión tiene los siguientes atributos:


      • noiseMapGeneration: la secuencia de comandos que se utiliza para generar el mapa de altura
      • tileRenderer: el procesador de malla, que se utiliza para mostrar el mapa de altura
      • meshFilter: el componente de filtro de malla, que se utiliza para acceder a la malla de vértices
      • meshCollider: el componente colisionador de malla, que se utiliza a colisiones mango con la baldosa
      • levelScale: la escala del mapa de altura

        Básicamente, en el método de inicio se llamará al método GenerateTile, que va a hacer todo esto. Lo primero que hace es calcular la profundidad y la anchura del mapa de altura. Ya que estamos usando un plano cuadrado, el número de vértices debe ser un cuadrado perfecto (en nuestro caso, la Unidad plano por defecto tiene 121 vértices). Por lo tanto, si tomamos la raíz cuadrada del número de vértices, obtendremos el mapa de profundidad y anchura, que será 11. A continuación, se llama al método GenerateNoiseMap con esta profundidad y anchura, así como la levelScale.
        TileGeneration clase pública: MonoBehaviour {[SerializeField] NoiseMapGeneration noiseMapGeneration; [SerializeField] privada MeshRenderer tileRenderer; [SerializeField] privada MeshFilter meshFilter; [SerializeField] privada MeshCollider meshCollider; [SerializeField] mapScale flotador privado; vacío Inicio () {GenerateTile (); } Void GenerateTile () {// Calcular profundidad de la loseta y el ancho basado en la malla vértices Vector3 [] meshVertices = this.meshFilter.mesh.vertices; int tileDepth = (int) Mathf.Sqrt (meshVertices.Length); int tileWidth = tileDepth; // calcular las compensaciones sobre la base de la posición del azulejo flotador [,] de alturas = this.noiseMapGeneration.GenerateNoiseMap (tileDepth, tileWidth, this.mapScale); // generar un mapa de elevación usando ruido Texture2D tileTexture = BuildTexture (de alturas); this.tileRenderer.material.mainTexture = tileTexture; } Privada Texture2D BuildTexture (float [,] de alturas) {int tileDepth = noiseMap.GetLength (0); int tileWidth = noiseMap.GetLength (1); Color [] = new mapa de colores de color [tileDepth * tileWidth]; for (int zIndex = 0; zIndex Después de generar el mapa de altura, el script llamará al método BuildTexture, que creará la Texture2D para este azulejo. A continuación, asignamos esta textura al material de baldosas.

        El método BuildTexture creará una matriz de colores, que se utiliza para crear el Texture2D. Luego, para cada coordenada del mapa de altura, se elegirá un tono de gris en base al valor de la altura. Podemos hacer esto mediante el uso de la función Color.Lerp. Esta función recibe como parámetros dos colores (en nuestro caso en blanco y negro) y un valor flotante entre 0 y 1 (en nuestro caso el valor de ruido). Entonces, se elige un color entre los dos los seleccionados de acuerdo con el valor flotante. Básicamente, cuanto menor es la altura, más oscuro será el color. Al final, se crea un Texture2D usando esta matriz de color y devolverlo.

        Ahora que la secuencia de comandos TileGeneration es completa, añadimos nuestras dos secuencias de comandos para el objeto Nivel del azulejo.

        Nivel Azulejos en inspector de la Unidad de teja guión Generación

        Y entonces, podemos tratar de jugar nuestro juego para visualizar el mapa de altura. La imagen siguiente muestra un mapa de altura generado usando una escala de 3. Sugerencia: es más fácil de visualizar el mosaico si se cambia de nuevo a la vista de escena después de comenzar el juego. De esta manera se puede mover fácilmente la cámara para ver baldosas de diferentes ángulos.

        Teja juego de objetos con el mapa de altura aplica

        Asignación de terrenos tipos

        Nuestro siguiente paso es asignar tipos de terreno (como agua, hierba, roca, montaña) a diferentes valores de altura. Además, cada tipo de terreno tendrá un color asociado a él, por lo que podemos añadir colores a nuestra baldosa de nivel.

        En primer lugar, tenemos que crear una clase TerrainType en el guión TileGeneration. Cada tipo de terreno tendrá un nombre, la talla y el color. Además, hay que añadir la etiqueta [System.Serializable] antes de la declaración de la clase. Esto nos permitirá establecer los atributos TerrainType en el editor más tarde. Por último, vamos a añadir otro atributo a la escritura TileGeneration, que será una serie de TerrainTypes. Esos serán los tipos de terreno disponibles para nuestro nivel.
        [System.Serializable] TerrainType public class {nombre de la cadena pública; altura del flotador público; el color del color pública;} public class TileGeneration: MonoBehaviour {[SerializeField] TerrainType privada [] terrainTypes;} 12345678910111213 [System.Serializable] publicclassTerrainType {publicstringname; publicfloatheight; publicColor de color;} publicclassTileGeneration: MonoBehaviour {[SerializeField] privateTerrainType [] terrainTypes;}

        a continuación, podemos establecer los tipos de terreno para la baldosa de nivel en el editor. Esos son los tipos de terreno que voy a utilizar. Puede ponerlos como se prefiere, pero es importante que los tipos de terreno están en un orden ascendente de los valores de altura, ya que esto será pronto sea necesario.

        baldosa de nivel en el inspector de la Unidad con los ajustes de los tipos de terreno

        Ahora vamos a cambiar el guión TileGeneration utilizar esos tipos de terreno a colores asignar a la baldosa. Básicamente vamos a cambiar el método de BuildTexture, en lugar de escoger un tono de gris para el color, vamos a elegir un terreno de acuerdo con el valor de ruido (usando un método ChooseTerrainType). A continuación, se le asigna el color tipo de terreno a la baldosa de nivel de coordenadas.
        privado Texture2D BuildTexture (float [,] de alturas) {int tileDepth = heightMap.GetLength (0); int tileWidth = heightMap.GetLength (1); Color [] = new mapa de colores de color [tileDepth * tileWidth]; for (int zIndex = 0; zIndex el método ChooseTerrainType simplemente iterar a través de la matriz terrainTypes y devolver el primer tipo de terreno cuya altura es mayor que el valor de altura (que es Por eso es importante que los tipos de terreno están en orden ascendente de altura).
        TerrainType ChooseTerrainType (altura del flotador) {// para cada tipo de terreno, de verificación si la altura es menor que el uno para el foreach tipo de terreno (TerrainType terrainType en terrainTypes) {// devolver el primer tipo de terreno cuya altura es mayor que la generada si (altura Ahora podemos tratar de jugar el juego de nuevo para ver nuestra azulejo con colores. Usted notará que el azulejo se ve un poco borrosa, pero no se preocupe por eso ahora. Se verá mejor una vez que tenemos varios azulejos en el nivel.

        baldosa de nivel de tierra-como colores aplicados

        Cambio de alturas de malla

        Hemos asignado terreno tipos de las coordenadas de mosaico. Sin embargo, todavía es un avión, incluso en las regiones montañosas. Lo que vamos a hacer ahora es usar el mapa de altura para asignar diferentes alturas a los vértices de baldosas. Podemos hacer que al cambiar la coordenada y de los vértices.

        Con el fin de hacerlo, vamos a crear un nuevo método en las TileGeneration script llamado UpdateMeshVertices. Este método será responsable de cambiar los vértices Plano malla de acuerdo con el mapa de altura, y será llamado en el final del método GenerateTile. Básicamente, se repetirá a través de todas las coordenadas de mosaico y cambiar el vértice correspondiente coordenada y para ser el valor de ruido multiplicada por un heightMultiplier. Al cambiar la heightMultiplier podemos cambiar la forma de las miradas nivel gusta. Al final, se actualiza la matriz de vértices de la malla y llamar a la RecalculateBounds y métodos RecalculateNormals. Estos métodos deben ser llamados cada vez que cambie vértices de la malla. También tenemos que actualizar la malla en el MeshCollider.
        TileGeneration clase pública: MonoBehaviour {[SerializeField] heightMultiplier flotador privado; UpdateMeshVertices private void (float [,] de alturas) {int tileDepth = heightMap.GetLength (0); int tileWidth = heightMap.GetLength (1); Vector3 [] meshVertices = this.meshFilter.mesh.vertices; // iterar a través de todas las coordenadas de alturas, la actualización de la int index vértice vertexIndex = 0; for (int zIndex = 0; zIndex A continuación, se puede asignar un heightMultiplier a la baldosa de nivel y tratar de ejecutar el juego. La siguiente figura muestra un azulejo usando un heightMultiplier de 3. Podemos ver las montañas en él, pero todavía hay un problema. Estamos aplicando alturas incluso para las regiones de aguas, que los hacen parecer raro, ya que deben ser planas. Eso es lo que vamos a arreglar ahora.

        Nivel Tile objeto en el Inspector Unidad baldosa de nivel con el mapa de mayor altura aplica

        Lo que vamos a hacer es crear una función personalizada que recibe como entrada los valores de altura de nuestro mapa de altura y declaraciones rectificadas valores de altura. Esta función debe devolver un valor 0 para todos los valores de altura por debajo de 0,4, por lo que las regiones de agua son avión. Podemos hacer eso mediante la adición de otro atributo en el guión TileGeneration que es un AnimationCurve. Entonces, cuando el assiging y valor de cada vértice de coordenadas, se evalúa el valor de la altura en esta función, antes de multiplicarlo por el heightMultiplier.
        utilizando System.Collections; usando System.Collections.Generic; usando UnityEngine; TileGeneration clase pública: MonoBehaviour {[SerializeField] heightMultiplier flotador privado; [SerializeField] privada AnimationCurve heightCurve; UpdateMeshVertices private void (float [,] de alturas) {int tileDepth = heightMap.GetLength (0); int tileWidth = heightMap.GetLength (1); Vector3 [] meshVertices = this.meshFilter.mesh.vertices; // iterar a través de todas las coordenadas de alturas, la actualización de la int index vértice vertexIndex = 0; for (int zIndex = 0; zIndex Ahora vamos a crear este heightCurve. Podemos hacer esto en el Editor, seleccionándolo en el objeto baldosa de nivel. La curva debe ser similar a la de abajo. Se puede crear una curva como esta seleccionando la tercera en el menú, a continuación, añadir una clave (botón derecho del ratón -> Agregar clave) en el punto 0.4 y luego arrastrándolo a 0. También tendrá que cambiar las fronteras de la Key de manera que es plano hasta 0,4.

        curva de altura con una subida empinada después de 0,4

        Por último, si intenta ejecutar el juego debe mostrar el nivel con áreas planas de agua, que debe mirar mucho mejor.

        Nivel objeto Azulejo con heightCurve aplica

        La construcción de un nivel con múltiples baldosas

        La última cosa que vamos a hacer en este tutorial es la adición de varios azulejos para construir un nivel completamente. Cada baldosa de nivel va a generar sus propios valores de altura y los azulejos de vecinos debería tener alturas continuas. Por lo tanto, lo primero que vamos a hacer es asegurarse de que los azulejos Nivel tendrá los mismos valores de altura en sus fronteras.

        puede hacer eso, asegurándose de que estamos llamando a la función perlinNoise con los mismos valores de los argumentos de los píxeles del borde. Con el fin de hacerlo, vamos a añadir parámetros de desplazamiento en la función GenerateNoiseMap. Esos desplazamientos se añaden a la x y z en el cálculo de índices de las muestras X y Z. Más tarde, esas compensaciones se corresponden con la posición del nivel del azulejo, de manera que la altura es continua a lo largo de los azulejos.
        NoiseMapGeneration clase pública: MonoBehaviour {float pública [,] GenerateNoiseMap (int mapDepth, int mapWidth, escala, flotador offsetX, flotar offsetZ) {// crear un mapa de ruido vacío con el mapDepth y mapWidth coordenadas flotador [,] = noiseMap nuevo flotador [mapDepth, mapWidth]; for (int zIndex = 0; zIndex Entonces, tenemos que añadir aquellos parámetros de desplazamiento al llamar GenerateNoiseMap en el guión TileGeneration. El valor de estos parámetros será el opuesto de las coordenadas X y Z de la baldosa de nivel.
        void GenerateTile () {// Calcular profundidad de la loseta y el ancho basado en la malla vértices Vector3 [] meshVertices = this.meshFilter.mesh.vertices; int tileDepth = (int) Mathf.Sqrt (meshVertices.Length); int tileWidth = tileDepth; // calcular las compensaciones en base a la posición del flotador baldosas offsetX = -this.gameObject.transform.position.x; flotar offsetZ = -this.gameObject.transform.position.z; // generar un mapa de elevación usando flotador ruido [,] de alturas = this.noiseMapGeneration.GenerateNoiseMap (tileDepth, tileWidth, this.mapScale, offsetX, offsetZ, olas); // construir un Texture2D del mapa de altura Texture2D tileTexture = BuildTexture (de alturas); this.tileRenderer.material.mainTexture = tileTexture; // actualizar el azulejo malla vértices de acuerdo con las UpdateMeshVertices mapa altura (de alturas); } 1234567891011121314151617181920voidGenerateTile () {// Calcular profundidad de la loseta y anchura en base a la verticesVector3 malla [] meshVertices = this.meshFilter.mesh.vertices; inttileDepth = (int) Mathf.Sqrt (meshVertices.Length); inttileWidth = tileDepth; // Calcular las compensaciones sobre la base de la baldosa positionfloatoffsetX = -this.gameObject.transform.position.x; floatoffsetZ = -this.gameObject.transform.position.z; // generar un mapa de elevación usando noisefloat [,] de alturas = this.noiseMapGeneration.GenerateNoiseMap ( tileDepth, tileWidth, this.mapScale, offsetX, offsetZ, olas); // construir un Texture2D desde la altura mapTexture2D tileTexture = BuildTexture (de alturas); this.tileRenderer.material.mainTexture = tileTexture; // actualizar el azulejo de malla vértices según los mapUpdateMeshVertices altura (de alturas);}

        Antes de la creación de todo el nivel con varios azulejos, vamos a crear sólo dos de ellos y ponerlos lado a lado para comprobar si las alturas son continuas en las fronteras. Por ejemplo, creé los dos azulejos a continuación.

        Nivel Tile 1 objeto en el Inspector Unidad Nivel de baldosas 2 objeto en el Inspector Unidad

        A continuación, cuando se ejecuta el juego, que debe ser similar a un solo nivel con dos fichas.

        Nivel del azulejo objetos uno al lado del otro con los mapas de altura aplican

        Lo que vamos a hacer ahora es generalizando esto a un nivel con cualquier número de fichas. En primer lugar, guardar el objeto baldosa de nivel como una casa prefabricada, por lo que puede crear una instancia de copias de él más tarde. A continuación, vamos a crear un nuevo script llamado LevelGeneration. Este script será responsable de la creación de múltiples Nivel Azulejos. Tendrá los siguientes atributos:


        • mapWidthInTiles: número de azulejos en el eje x
        • mapDepthInTiles: número de azulejos en el eje Z
        • tilePrefab: Nivel prefabricada del azulejo, que se utiliza para crear instancias de la azulejos

          A continuación, el método GenerateLevel creará el Nivel Tiles de iteración a través de todas las coordenadas de mosaico. Para cada baldosa, que calcula su posición sobre la base de la baldosa de coordenadas y luego una instancia de una copia del mismo a partir de la teja prefabricada Nivel. Al final, este método se llama GenerateLevel dentro del método de inicio.
          LevelGeneration clase pública: MonoBehaviour {[] SerializeField privadas mapWidthInTiles int, mapDepthInTiles; [SerializeField] privada GameObject tilePrefab; vacío Inicio () {GenerateMap (); } Void GenerateMap () {// obtener las dimensiones de las baldosas de la loseta prefabricada Vector3 tileSize = tilePrefab.GetComponent () .bounds.size; int tileWidth = (int) tileSize.x; int tileDepth = (int) tileSize.z; // para cada baldosa, una instancia de un azulejo en la posición correcta para (int xTileIndex = 0; xTileIndex ().bounds.size;inttileWidth=(int)tileSize.x;inttileDepth=(int)tileSize.z;// for each Tile, instantiate a Tile in the correct positionfor(intxTileIndex=0;xTileIndexNow, remove the Level Tiles from y our scene and add a single Level object, with some tiles in the x and z axis. The figure below shows an example of a Level with 10 tiles in each axis. You may also want to change the Level Scale and Height Multiplier for the Level Tiles to make the level look better. In the figure below I used a Level Scale of 10 and a Height Multiplier of 5. However, you can still see some repeating patterns in the level, as well as some weird-shaped regions. So, our last step in this tutorial will be to polish a little bit the Noise Map generation to make the level look more natural.

          Level object with Level Generation script attachedLarge level map with terrain generation applied

          Adding multiple waves

          What we are going to in order to polish the noise map generation is adding more noise waves. Basically, when you call Mathf.PerlinNoise, you’re sampling points from a noise wave. So, if we change this wave frequency and amplitude we change the noise result. Another way of changing the noise values is adding a random seed in the samples. By creating multiple waves with different frequency, amplitude, we can generate more interesting noise, which will led to levels that look more natural. The different seed values, by their turn, allows us to remove the repetitions in the level.

          So, first, let’s create a Wave class inside the NoiseMapGeneration Script. Like the TerainType, the Wave will be a Serializable class with a few attributes. The attributes we are going to use are the seed, frequency and amplitude of the wave, as discussed earlier.

          [System.Serializable]public class Wave { public float seed; public float frequency; public float amplitude;}123456[System.Serializable]publicclassWave{publicfloatseed;publicfloatfrequency;publicfloatamplitude;}

          Then, we change the GenerateNoiseMap method to receive an Array of Waves as parameter. Then, instead of calling Math.PerlinNoise a single time, we call it once for each Wave, using the wave seed, frequency and amplitude. Notice that the frequency is multiplied by the sample value, while the amplitude is multiplied by the noise result. In the end, we need to divide the noise by the sum of amplitudes, so that its result will remain between 0 and 1.

          public float[,] GenerateNoiseMap(int mapDepth, int mapWidth, float scale, float offsetX, float offsetZ, Wave[] waves) { // create an empty noise map with the mapDepth and mapWidth coordinates float[,] noiseMap = new float[mapDepth, mapWidth]; for (int zIndex = 0; zIndex < mapDepth; zIndex++) { for (int xIndex = 0; xIndex < mapWidth; xIndex++) { // calculate sample indices based on the coordinates, the scale and the offset float sampleX = (xIndex + offsetX) / scale; float sampleZ = (zIndex + offsetZ) / scale; float noise = 0f; float normalization = 0f; foreach (Wave wave in waves) { // generate noise value using PerlinNoise for a given Wave noise += wave.amplitude * Mathf.PerlinNoise (sampleX * wave.frequency + wave.seed, sampleZ * wave.frequency + wave.seed); normalization += wave.amplitude; } // normalize the noise value so that it is within 0 and 1 noise /= normalization; noiseMap [zIndex, xIndex] = noise; } } return noiseMap; }1234567891011121314151617181920212223242526publicfloat[,]GenerateNoiseMap(intmapDepth,intmapWidth,floatscale,floatoffsetX,floatoffsetZ,Wave[]waves){// create an empty noise map with the mapDepth and mapWidth coordinatesfloat[,]noiseMap=newfloat[mapDepth,mapWidth];for(intzIndex=0;zIndexNow, we need to add an Array of Waves as a new attribute of the TileGeneration Script, so that we can send it to the GenerateNoiseMap method.

          public class TileGeneration : MonoBehaviour { [SerializeField] private Wave[] waves; void GenerateTile() { // calculate tile depth and width based on the mesh vertices Vector3[] meshVertices = this.meshFilter.mesh.vertices; int tileDepth = (int)Mathf.Sqrt (meshVertices.Length); int tileWidth = tileDepth; // calculate the offsets based on the tile position float offsetX = -this.gameObject.transform.position.x; float offsetZ = -this.gameObject.transform.position.z; // generate a heightMap using noise float[,] heightMap = this.noiseMapGeneration.GenerateNoiseMap (tileDepth, tileWidth, this.mapScale, offsetX, offsetZ, waves); // build a Texture2D from the height map Texture2D tileTexture = BuildTexture (heightMap); this.tileRenderer.material.mainTexture = tileTexture; // update the tile mesh vertices according to the height map UpdateMeshVertices (heightMap); }}1234567891011121314151617181920212223242526publicclassTileGeneration:MonoBehaviour{[SerializeField]privateWave[]waves;voidGenerateTile(){// calculate tile depth and width based on the mesh verticesVector3[]meshVertices=this.meshFilter.mesh.vertices;inttileDepth=(int)Mathf.Sqrt(meshVertices.Length);inttileWidth=tileDepth;// calculate the offsets based on the tile positionfloatoffsetX=-this.gameObject.transform.position.x;floatoffsetZ=-this.gameObject.transform.position.z;// generate a heightMap using noisefloat[,]heightMap=this.noiseMapGeneration.GenerateNoiseMap(tileDepth,tileWidth,this.mapScale,offsetX,offsetZ,waves);// build a Texture2D from the height mapTexture2D tileTexture=BuildTexture(heightMap);this.tileRenderer.material.mainTexture=tileTexture;// update the tile mesh vertices according to the height mapUpdateMeshVertices(heightMap);}}

          Finally, we add some Wave values in the Level Tile prefab and then we can play the game again to see the new level. The figure below shows the values I’m using in this tutorial to generate the level in the righthand figure. Notice that I changed the Level Scale and Height Multiplier again, to make the level look better. You may have to try different values until you find the one that looks better to you.

          Level Tile object in the Unity InspectorLevel Tile object with numerous generated waves

          And this concludes this procedural level generation tutorial! In the next one we are going to generate tempereatures and moisture values for our level, so that we can select biomes for different level areas.

          Access part 2 here

          Mensajes relacionados
          Huge generated game world from Unity

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *