Created
February 10, 2024 17:09
-
-
Save unitycoder/13f12e938896444e9658c4b4a72f1c8d to your computer and use it in GitHub Desktop.
using Perlin noise to generate a 2D terrain map of tiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // https://www.youtube.com/watch?v=qNZ-0-7WuS8 | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| using UnityEngine; | |
| /* Danndx 2021 (youtube.com/danndx) | |
| From video: youtu.be/qNZ-0-7WuS8 | |
| thanks - delete me! :) */ | |
| public class SCR_PerlinNoiseMap : MonoBehaviour | |
| { | |
| Dictionary<int, GameObject> tileset; | |
| Dictionary<int, GameObject> tile_groups; | |
| public GameObject prefab_plains; | |
| public GameObject prefab_forest; | |
| public GameObject prefab_hills; | |
| public GameObject prefab_mountains; | |
| int map_width = 160; | |
| int map_height = 90; | |
| List<List<int>> noise_grid = new List<List<int>>(); | |
| List<List<GameObject>> tile_grid = new List<List<GameObject>>(); | |
| // recommend 4 to 20 | |
| float magnification = 7.0f; | |
| int x_offset = 0; // <- +> | |
| int y_offset = 0; // v- +^ | |
| void Start() | |
| { | |
| CreateTileset(); | |
| CreateTileGroups(); | |
| GenerateMap(); | |
| } | |
| void CreateTileset() | |
| { | |
| /** Collect and assign ID codes to the tile prefabs, for ease of access. | |
| Best ordered to match land elevation. **/ | |
| tileset = new Dictionary<int, GameObject>(); | |
| tileset.Add(0, prefab_plains); | |
| tileset.Add(1, prefab_forest); | |
| tileset.Add(2, prefab_hills); | |
| tileset.Add(3, prefab_mountains); | |
| } | |
| void CreateTileGroups() | |
| { | |
| /** Create empty gameobjects for grouping tiles of the same type, ie | |
| forest tiles **/ | |
| tile_groups = new Dictionary<int, GameObject>(); | |
| foreach(KeyValuePair<int, GameObject> prefab_pair in tileset) | |
| { | |
| GameObject tile_group = new GameObject(prefab_pair.Value.name); | |
| tile_group.transform.parent = gameObject.transform; | |
| tile_group.transform.localPosition = new Vector3(0, 0, 0); | |
| tile_groups.Add(prefab_pair.Key, tile_group); | |
| } | |
| } | |
| void GenerateMap() | |
| { | |
| /** Generate a 2D grid using the Perlin noise fuction, storing it as | |
| both raw ID values and tile gameobjects **/ | |
| for(int x = 0; x < map_width; x++) | |
| { | |
| noise_grid.Add(new List<int>()); | |
| tile_grid.Add(new List<GameObject>()); | |
| for(int y = 0; y < map_height; y++) | |
| { | |
| int tile_id = GetIdUsingPerlin(x, y); | |
| noise_grid[x].Add(tile_id); | |
| CreateTile(tile_id, x, y); | |
| } | |
| } | |
| } | |
| int GetIdUsingPerlin(int x, int y) | |
| { | |
| /** Using a grid coordinate input, generate a Perlin noise value to be | |
| converted into a tile ID code. Rescale the normalised Perlin value | |
| to the number of tiles available. **/ | |
| float raw_perlin = Mathf.PerlinNoise( | |
| (x - x_offset) / magnification, | |
| (y - y_offset) / magnification | |
| ); | |
| float clamp_perlin = Mathf.Clamp01(raw_perlin); // Thanks: youtu.be/qNZ-0-7WuS8&lc=UgyoLWkYZxyp1nNc4f94AaABAg | |
| float scaled_perlin = clamp_perlin * tileset.Count; | |
| // Replaced 4 with tileset.Count to make adding tiles easier | |
| if(scaled_perlin == tileset.Count) | |
| { | |
| scaled_perlin = (tileset.Count - 1); | |
| } | |
| return Mathf.FloorToInt(scaled_perlin); | |
| } | |
| void CreateTile(int tile_id, int x, int y) | |
| { | |
| /** Creates a new tile using the type id code, group it with common | |
| tiles, set it's position and store the gameobject. **/ | |
| GameObject tile_prefab = tileset[tile_id]; | |
| GameObject tile_group = tile_groups[tile_id]; | |
| GameObject tile = Instantiate(tile_prefab, tile_group.transform); | |
| tile.name = string.Format("tile_x{0}_y{1}", x, y); | |
| tile.transform.localPosition = new Vector3(x, y, 0); | |
| tile_grid[x].Add(tile); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment