public static float[,] GenerateNoiseMap(NoiseMapSettings noiseMapSettings) { var noiseMap = new float[noiseMapSettings.mapWidth, noiseMapSettings.mapHeight]; var prng = noiseMapSettings.useSeed ? new Random(noiseMapSettings.seed) : new Random(); var octaveOffsets = new Vector2[noiseMapSettings.octaves]; for (var i = 0; i < noiseMapSettings.octaves; i++) { var offsetX = prng.Next(MIN_OFFSET_VALUE, MAX_OFFSET_VALUE) + noiseMapSettings.mapOffset.x; var offsetY = prng.Next(MIN_OFFSET_VALUE, MAX_OFFSET_VALUE) + noiseMapSettings.mapOffset.y; octaveOffsets[i] = new Vector2(offsetX, offsetY); } var maxNoiseHeight = float.MinValue; var minNoiseHeight = float.MaxValue; var halfMapWidth = noiseMapSettings.mapWidth / 2f; var halfMapHeight = noiseMapSettings.mapHeight / 2f; for (var y = 0; y < noiseMapSettings.mapHeight; y++) { for (var x = 0; x < noiseMapSettings.mapWidth; x++) { var amplitude = 1f; var frequency = 1f; var noiseHeight = 0f; for (var i = 0; i < noiseMapSettings.octaves; i++) { var currentX = (x - halfMapWidth) / noiseMapSettings.scale * frequency + octaveOffsets[i].x; var currentY = (y - halfMapHeight) / noiseMapSettings.scale * frequency + octaveOffsets[i].y; var perlinValue = Mathf.PerlinNoise(currentX, currentY) * 2 - 1; noiseHeight += perlinValue * amplitude; amplitude *= noiseMapSettings.persistance; frequency *= noiseMapSettings.lacunarity; } if (noiseHeight > maxNoiseHeight) { maxNoiseHeight = noiseHeight; } if (noiseHeight < minNoiseHeight) { minNoiseHeight = noiseHeight; } noiseMap[x, y] = noiseHeight; } } for (var y = 0; y < noiseMapSettings.mapHeight; y++) { for (var x = 0; x < noiseMapSettings.mapWidth; x++) { noiseMap[x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, y]); } } return(noiseMap); }
public List <MapElement> SpawnMapElementsWithPerlinNoiseDistribution(GameObject objectToSpawn, int seed, Vector2 spawningHeightRange, float probability, float density, Transform parent, NoiseMapSettings noiseMapSettings, bool requireNavMesh) { return(mapGenerator.SpawnMapElementsWithPerlinNoiseDistribution(objectToSpawn, seed, spawningHeightRange, probability, density, parent, noiseMapSettings, requireNavMesh)); }
/// <summary> /// Spawns a group of MapElements in the map using a pseudo random perlin noise distribution. /// </summary> /// <param name="objectToSpawn">The map element's prefab to spawn</param> /// <param name="seed">The seed to use to generate the perlin noise</param> /// <param name="spawningHeightRange">In which area of the map this is wanted to spawn. -1 means the bottom of the sea. 1 means the highest points in the world. 0 is the shoreline.</param> /// <param name="probability">The probability of the object being spawned at any given spot (following the perlin noise distribution)</param> /// <param name="density">The density of the spawning. 1 meaning all the available spots where the probability says spawn should happen will be filled. 0 means none.</param> /// <param name="parent">The transform that must be the parent of the spawned MapElement</param> /// <param name="noiseMapSettings">The settings to be used for the perlin noise map</param> /// <param name="requireNavMesh">Must the locations where the MapElements will spawn require a valid NavMeshSurface?</param> public List <MapElement> SpawnMapElementsWithPerlinNoiseDistribution(GameObject objectToSpawn, int seed, Vector2 spawningHeightRange, float probability, float density, Transform parent, NoiseMapSettings noiseMapSettings, bool requireNavMesh) { List <MapElement> spawnedMapElements = new List <MapElement>(); RandomEssentials rng = new RandomEssentials(seed); float[,] noise = Noise.GenerateNoiseMap((int)mapManager.mapConfiguration.mapRadius * 2, (int)mapManager.mapConfiguration.mapRadius * 2, noiseMapSettings, Vector2.zero, seed); for (int x = 0; x < noise.GetLength(0); x++) { for (int y = 0; y < noise.GetLength(1); y++) { if (!(noise[x, y] >= 1 - probability)) { continue; } if (rng.GetRandomBool(1 - density)) { continue; } if (IsSpawnablePositionOnTerrain(new Vector2(x - mapManager.mapConfiguration.mapRadius, y - mapManager.mapConfiguration.mapRadius), spawningHeightRange, requireNavMesh, out Vector3 spawnablePosition)) { spawnedMapElements.Add(SpawnMapElement(objectToSpawn, spawnablePosition, Quaternion.identity, parent)); } } } return(spawnedMapElements); }