// Create path areas private void CreatePathAreas(TerrainStructure terrainStructure) { List <int> availableSegments = _graph.FindNodesWithData(new AreaSegment(AreaSegment.EAreaSegmentType.MainPath)).ToList(); availableSegments = availableSegments.Union(_graph.FindNodesWithData(new AreaSegment(AreaSegment.EAreaSegmentType.Start))).ToList(); List <AreaSettingsFactory> availableSettings = terrainStructure.BiomeSettings.PathAreas.ToList(); availableSettings.Sort(); while (availableSegments.Count > 0 && availableSettings.Count > 0) { AreaSettingsFactory settingsFactory = availableSettings.Last(); Dictionary <int, int> matches = _graph.MatchPattern(settingsFactory.GetPatternGraph()); if (matches == null) { availableSettings.Remove(settingsFactory); continue; } foreach (var match in matches) { availableSegments.Remove(match.Value); _graph.RemoveNode(match.Value); } Graph <AreaData> areaDataGraph = terrainStructure.GetAreaDataGraph(matches.Values); List <Vector2[]> clearPolygons = terrainStructure.GetPathPolygons(matches.Values); Vector2[] borderPolygon = terrainStructure.GetAreaSegmentsBorderPolygon(matches.Values); Areas.AddRange(settingsFactory.ProduceAreaSettings(areaDataGraph, clearPolygons, borderPolygon)); } }
public SceneryStructure(StoryStructure storyStructure, TerrainStructure terrainStructure) { _graph = new GrammarGraph <AreaSegment>(terrainStructure.AreaSegmentGraph); // Assign speacial areas CreateSpecialAreas(terrainStructure); // Assign paths to area settings CreatePathAreas(terrainStructure); // Assign boss area segments to area settings CreateBossAreas(terrainStructure); }
// Set alphamap texture based on biome configuration public static float[,,] GenerateAlphaMap(TerrainStructure terrainStructure) { var result = new float[terrainStructure.HeightMapResolution, terrainStructure.HeightMapResolution, terrainStructure.TextureCount]; var cellSize = terrainStructure.MapSize / terrainStructure.HeightMapResolution; for (int y = 0; y < terrainStructure.HeightMapResolution; y++) { for (int x = 0; x < terrainStructure.HeightMapResolution; x++) { KeyValuePair <int, float> sample = terrainStructure.SampleTexture(new Vector2(x * cellSize, y * cellSize)); result[y, x, sample.Key] = sample.Value; } } return(result); }
// Generate a heightmap given terrain structure and biome configuration public static float[,] GenerateHeightMap(TerrainStructure terrainStructure) { var result = new float[terrainStructure.HeightMapResolution, terrainStructure.HeightMapResolution]; var cellSize = terrainStructure.MapSize / terrainStructure.HeightMapResolution; var octavesOffset = new Vector2[terrainStructure.Octaves]; for (var i = 0; i < octavesOffset.Length; i++) { octavesOffset[i] = new Vector2(Random.Range(-100000f, 100000f), Random.Range(-100000f, 100000f)); } // Generate heightmap for (var y = 0; y < terrainStructure.HeightMapResolution; y++) { for (var x = 0; x < terrainStructure.HeightMapResolution; x++) { var biomeHeight = terrainStructure.SampleHeight(new Vector2(x * cellSize, y * cellSize)); var amplitude = 1f; var frequency = 1f; var noiseHeight = 0f; for (int i = 0; i < octavesOffset.Length; i++) { var sampleX = (x + octavesOffset[i].x) / terrainStructure.MapSize * frequency * (biomeHeight.Scale * cellSize); var sampleY = (y + octavesOffset[i].y) / terrainStructure.MapSize * frequency * (biomeHeight.Scale * cellSize); /* Noise between -1 and 1 */ noiseHeight += (Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1) * amplitude; amplitude *= biomeHeight.Persistence; frequency *= biomeHeight.Lacunarity; } float normalizedHeight = Mathf.InverseLerp(-1f, 1f, noiseHeight); float globalHeight = (biomeHeight.LocalMax - biomeHeight.LocalMin) * normalizedHeight + biomeHeight.LocalMin; result[y, x] = globalHeight; } } return(result); }
// Redraws preview in the scene editor public void GenerateLevel() { #if UNITY_EDITOR if (!GenerateOnPlay && Application.isPlaying) { return; } #endif Random.InitState(Seed); ClearDisplay(); MyStoryStructure = new StoryStructure(0, 1, MainPathNodeCount, SidePathCount, SidePathNodeCount, new CharacterEnemy[4]); MyTerrainStructure = new TerrainStructure(MyStoryStructure, AvailableBiomes, MapSize, HeightMapResolution, Octaves, VoronoiSamples, LloydRelaxation, HeightNoise, AlphaNoise, BorderBlockerOffset); MySceneryStructure = new SceneryStructure(MyStoryStructure, MyTerrainStructure); switch (DrawMode) { case DrawModeEnum.TerrainSkeleton: DrawTerrainSkeleton(); break; case DrawModeEnum.Terrain: DrawTerrain(); break; case DrawModeEnum.ScenerySkeleton: DrawScenerySkeleton(); break; case DrawModeEnum.Scenery: DrawTerrainAndScenery(); break; case DrawModeEnum.GameLevel: DrawCompleteLevel(); break; default: throw new ArgumentOutOfRangeException(); } }
public void Get_Terrain_Test() { //Arrange var terrainStructure = new TerrainStructure(); var terrainModels = new List <TerrainModel>() { new TerrainModel() { Type = TerrainType.Grass }, new TerrainModel() { Type = TerrainType.Road }, new TerrainModel() { Type = TerrainType.Rail }, new TerrainModel() { Type = TerrainType.Water } }; terrainStructure.Construct(terrainModels); //Act var actual = new List <TerrainType>(); for (int i = 0; i < 100000; i++) { actual.Add(terrainStructure.GetTerrain().Type); } //Assert CheckMaxRepetition(actual); }
public static GameObject DrawAreaSegments(TerrainStructure terrainStructure, string name = "AreaSegments") { GameObject result = new GameObject(name); var graph = terrainStructure.AreaSegmentGraph; // Draw all lines GameObject edges = new GameObject("Edges"); edges.transform.parent = result.transform; foreach (var edge in graph.GetAllEdges()) { Vector2 start = terrainStructure.GetAreaSegmentCenter(edge.x); Vector2 end = terrainStructure.GetAreaSegmentCenter(edge.y); Color color; switch ((AreaSegment.EAreaSegmentEdgeType)graph.GetEdgeValue(edge.x, edge.y)) { case AreaSegment.EAreaSegmentEdgeType.NonNavigable: color = Color.black; break; case AreaSegment.EAreaSegmentEdgeType.MainPath: color = Color.green; break; case AreaSegment.EAreaSegmentEdgeType.SidePath: color = Color.cyan; break; case AreaSegment.EAreaSegmentEdgeType.BossInnerPath: color = Color.red; break; case AreaSegment.EAreaSegmentEdgeType.SpecialInnerPath: color = Color.yellow; break; default: color = Color.gray; break; } GameObject line = DrawLine(new Vector3(start.x, 0, start.y), new Vector3(end.x, 0, end.y), 5, color); line.transform.parent = edges.transform; } // Draw all centers GameObject nodes = new GameObject("Nodes"); nodes.transform.parent = result.transform; foreach (var id in graph.GetAllNodeIDs()) { AreaSegment data = graph.GetNodeData(id); Vector2 center = terrainStructure.GetAreaSegmentCenter(id); Color color; switch (data.Type) { case AreaSegment.EAreaSegmentType.Empty: color = Color.white; break; case AreaSegment.EAreaSegmentType.Border: color = Color.black; break; case AreaSegment.EAreaSegmentType.Start: color = Color.blue; break; case AreaSegment.EAreaSegmentType.Boss: color = Color.red; break; case AreaSegment.EAreaSegmentType.Special: color = Color.yellow; break; case AreaSegment.EAreaSegmentType.MainPath: color = Color.green; break; case AreaSegment.EAreaSegmentType.SidePath: color = Color.cyan; break; default: throw new ArgumentOutOfRangeException(); } GameObject node = DrawSphere(new Vector3(center.x, 0, center.y), 20, color); node.name = "Node " + id + " - " + data.Type; node.transform.parent = nodes.transform; } return(result); }