I. Introduction▲
Cette série explique comment générer de manière procédurale des continents dans Unity.
		Vous pouvez retrouver les autres épisodes de cette série dans le sommaire dédié.
II. Vidéo▲
Unity - Génération procédurale de terrain - Carte de diminution du terrain
III. Résumé▲
La carte de diminution du terrain permet de s'assurer que le terrain est complètement entouré d'eau. Ainsi, lors de la génération, nous appliquons un décalage des hauteurs générées par le bruit suivant la carte de diminution.
		Cette nouvelle carte sera aussi générée à la volée.
IV. Implémentation▲
Créez un nouveau script C#, nommé FallOffGenerator.cs :
using UnityEngine;
using System.Collections;
public static class FalloffGenerator {
    public static float[,] GenerateFalloffMap(int size) {
        float[,] map = new float[size,size];
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                float x = i / (float)size * 2 - 1;
                float y = j / (float)size * 2 - 1;
                float value = Mathf.Max (Mathf.Abs (x), Mathf.Abs (y));
                map [i, j] = value;
            }
        }
        return map;
    }La fonction GenerateFalloffMap() génère la carte (carrée) de diminution à la taille voulue.
V. Affichage du résultat▲
Il est toujours pratique d'afficher ce que nous venons de générer, ne serait-ce que pour confirmer que le résultat est celui attendu.
Pour cela, nous réutilisons le mécanisme mis en place précédemment, en ajoutant une entrée FalloffMap dans l'énumération et qui est utilisée dans la fonction DrawMapInEditor() :
public void DrawMapInEditor() {
    MapData mapData = GenerateMapData (Vector2.zero);
    MapDisplay display = FindObjectOfType<MapDisplay> ();
    if (drawMode == DrawMode.NoiseMap) {
        display.DrawTexture (TextureGenerator.TextureFromHeightMap (mapData.heightMap));
    } else if (drawMode == DrawMode.ColourMap) {
        display.DrawTexture (TextureGenerator.TextureFromColourMap (mapData.colourMap, mapChunkSize, mapChunkSize));
    } else if (drawMode == DrawMode.Mesh) {
        display.DrawMesh (MeshGenerator.GenerateTerrainMesh (mapData.heightMap, meshHeightMultiplier, meshHeightCurve, editorPreviewLOD), TextureGenerator.TextureFromColourMap (mapData.colourMap, mapChunkSize, mapChunkSize));
    } else if (drawMode == DrawMode.FalloffMap) {
        display.DrawTexture(TextureGenerator.TextureFromHeightMap(FalloffGenerator.GenerateFalloffMap(mapChunkSize)));
    }
}On réutilise simplement la fonction DrawTexture() pour l'affichage.
VI. Utilisation de la carte▲
La carte de diminution n'est générée qu'une seule fois. Pour cela, la génération est lancée dans la méthode Awake() :
float[,] falloffMap;
void Awake() {
    falloffMap = FalloffGenerator.GenerateFalloffMap (mapChunkSize);
}Toutefois, la carte ne sera générée que si on démarre le jeu. Il est donc aussi nécessaire d'ajouter la génération dans la méthode OnValidate() :
void OnValidate() {
    if (lacunarity < 1) {
        lacunarity = 1;
    }
    if (octaves < 0) {
        octaves = 0;
    }
    falloffMap = FalloffGenerator.GenerateFalloffMap (mapChunkSize);
}Ensuite, dans la méthode GenerateMapData(), nous utilisons la nouvelle carte pour impacter les hauteurs :
MapData GenerateMapData(Vector2 centre) {
    float[,] noiseMap = Noise.GenerateNoiseMap (mapChunkSize, mapChunkSize, seed, noiseScale, octaves, persistance, lacunarity, centre + offset, normalizeMode);
    Color[] colourMap = new Color[mapChunkSize * mapChunkSize];
    for (int y = 0; y < mapChunkSize; y++) {
        for (int x = 0; x < mapChunkSize; x++) {
            if (useFalloff) {
                noiseMap [x, y] = Mathf.Clamp01(noiseMap [x, y] - falloffMap [x, y]);
            }
            float currentHeight = noiseMap [x, y];
            for (int i = 0; i < regions.Length; i++) {
                if (currentHeight >= regions [i].height) {
                    colourMap [y * mapChunkSize + x] = regions [i].colour;
                } else {
                    break;
                }
            }
        }
    }
    return new MapData (noiseMap, colourMap);
}VII. Amélioration de la carte▲
La première version de la carte réduit trop les valeurs. Pour corriger cela, la carte sera générée suivant l'équation :
kitxmlcodelatexdvp\frac {x^a} {x^a + (1 - x)^a}finkitxmlcodelatexdvpSoit, dans le code :
static float Evaluate(float value) {
    float a = 3;
    float b = 2.2f;
    return Mathf.Pow (value, a) / (Mathf.Pow (value, a) + Mathf.Pow (b - b * value, a));
}VIII. Commenter▲
Vous pouvez commenter et donner vos avis dans la discussion associée sur le forum.



