SoundKiller777

Simple Unity Cave Generator

Jun 30th, 2020
1,225
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6. public class MapGenerator : MonoBehaviour
  7. {
  8.     #region Editor Exposed Data
  9.     [SerializeField, Header("Settings")]
  10.     private int width = 128;
  11.     [SerializeField]
  12.     private int height = 128;
  13.     [SerializeField, Range(0,100)]
  14.     private int randomFillPercent = 77;
  15.     [SerializeField, ColorUsageAttribute(true, true)]
  16.     private Color floorColor = new Color(5.25f, 0, 0, 1);
  17.     [SerializeField, ColorUsageAttribute(true, true)]
  18.     private Color wallColor = Color.black;
  19.  
  20.     [SerializeField, Header("RNG Settings")]
  21.     private string seed = "QWERTY";
  22.     [SerializeField]
  23.     private bool useRandomSeed = false;
  24.  
  25.     [SerializeField, Header("RNG Fill Settings")]
  26.     private float rngFillRate = 0.001f;
  27.  
  28.     [SerializeField, Header("Smoothing Settings")]
  29.     private float smoothingRate = 0.001f;
  30.     [SerializeField]
  31.     private float smoothingIterations = 4;
  32.     #endregion
  33.  
  34.     #region Public Data
  35.  
  36.     #endregion
  37.  
  38.     #region Private Data
  39.     private int[,] _map;
  40.  
  41.     private Renderer _renderer = null;
  42.     private Texture2D _texture = null;
  43.  
  44.     private System.Random _prng = null;
  45.  
  46.     private ProgressDisplay _progressDisplay = null;
  47.     #endregion
  48.  
  49.     // Awaken my minions...
  50.     void Awake()
  51.     {
  52.         _renderer = GetComponent<Renderer>();
  53.  
  54.         _progressDisplay = GameObject.FindGameObjectsWithTag("ProgressDisplay")[0].GetComponent<ProgressDisplay>();
  55.         if (_progressDisplay == null)
  56.         {
  57.             Debug.LogError("Error:: Cannot find STAGE DISPLAY gameobject");
  58.         }
  59.     }
  60.  
  61.     // Start all the things...
  62.     void Start()
  63.     {        
  64.         _texture = new Texture2D(width, height);
  65.  
  66.         _renderer.material.EnableKeyword("_EMISSION");
  67.         _renderer.material.SetTexture("_EmissionMap", _texture);
  68.         _renderer.material.SetColor("_EmissionColor", floorColor);
  69.        
  70.         _renderer.material.SetTexture("_BaseMap", _texture);
  71.  
  72.         GenerateMap();
  73.  
  74.         floorColor.r = 4.75f;
  75.     }
  76.  
  77.     private void GenerateMap()
  78.     {
  79.         // Init map array
  80.         _map = new int[width, height];
  81.  
  82.         RandomFillMap();
  83.     }
  84.  
  85.     private void RandomFillMap()
  86.     {
  87.         #region Setup RNG
  88.         if (useRandomSeed)
  89.         {
  90.             seed = Time.time.ToString();
  91.         }
  92.  
  93.         _prng = new System.Random(seed.GetHashCode());
  94.         #endregion
  95.  
  96.         StartCoroutine(RandomFillMap_Step());
  97.     }
  98.  
  99.     private IEnumerator RandomFillMap_Step()
  100.     {
  101.         for (int x = 0; x < width; x++)
  102.         {
  103.             for (int y = 0; y < height; y++)
  104.             {
  105.                 if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
  106.                 {
  107.                     _map[x, y] = 1;
  108.                 }
  109.                 else
  110.                 {
  111.                     _map[x, y] = _prng.Next(0, 100) < randomFillPercent ? 1 : 0;
  112.                 }
  113.             }
  114.  
  115.             UpdateMap();
  116.             yield return new WaitForSeconds(rngFillRate);
  117.         }
  118.  
  119.         yield return new WaitForSeconds(2);
  120.  
  121.         _progressDisplay.AdvanceStage();
  122.         SmoothMap();
  123.     }
  124.  
  125.     private void SmoothMap()
  126.     {
  127.         StartCoroutine(SmoothMap_Step());
  128.     }
  129.  
  130.     IEnumerator SmoothMap_Step()
  131.     {
  132.         for (int i = 0; i < smoothingIterations; i++)
  133.         {
  134.             for (int x = 0; x < width; x++)
  135.             {
  136.                 for (int y = 0; y < height; y++)
  137.                 {
  138.                     int neighbourWallTiles = GetSurroundingWallTiles(x, y);
  139.  
  140.                     if (neighbourWallTiles > 4)
  141.                         _map[x, y] = 1;
  142.                     else if (neighbourWallTiles < 4)
  143.                         _map[x, y] = 0;
  144.                 }
  145.  
  146.                 UpdateMap();
  147.                 yield return new WaitForSeconds(smoothingRate);
  148.             }
  149.  
  150.             UpdateMap();
  151.             yield return new WaitForSeconds(1);
  152.         }
  153.  
  154.         yield return new WaitForSeconds(1);
  155.         _progressDisplay.AdvanceStage(true);
  156.     }
  157.  
  158.     private int GetSurroundingWallTiles(int iGridX, int iGridY)
  159.     {
  160.         int wallCount = 0;
  161.         for (int neighbourX = iGridX - 1; neighbourX <= iGridX + 1; neighbourX++)
  162.         {
  163.             for (int neighbourY = iGridY - 1; neighbourY <= iGridY + 1; neighbourY++)
  164.             {
  165.                 if (neighbourX >= 0 && neighbourX < width && neighbourY >= 0 && neighbourY < height)
  166.                 {
  167.                     if (neighbourX != iGridX || neighbourY != iGridY)
  168.                     {
  169.                         wallCount += _map[neighbourX, neighbourY];
  170.                     }
  171.                 }
  172.                 else
  173.                 {
  174.                     wallCount++;
  175.                 }
  176.             }
  177.         }
  178.  
  179.         return wallCount;
  180.     }
  181.  
  182.     // Update all the things
  183.     void Update()
  184.     {
  185.         // Spin the plane
  186.         transform.Rotate(Vector3.up * Time.deltaTime * 20);
  187.  
  188.         UpdateMap();
  189.  
  190.         floorColor.r = Mathf.Lerp(floorColor.r, 5.25f, 0.0025f);
  191.     }
  192.  
  193.     void UpdateMap()
  194.     {
  195.         for (int y = 0; y < _texture.height; y++)
  196.         {
  197.             for (int x = 0; x < _texture.height; x++)
  198.             {
  199.                 Color color = _map[x, y] == 0 ? floorColor : wallColor;
  200.                 _texture.SetPixel(x, y, color);
  201.             }
  202.         }
  203.         _texture.Apply();
  204.  
  205.         _renderer.material.EnableKeyword("_EMISSION");
  206.         _renderer.material.SetTexture("_EmissionMap", _texture);
  207.         _renderer.material.SetColor("_EmissionColor", floorColor);
  208.     }
  209. }
RAW Paste Data