Advertisement
GaelVanhalst

Bunny Annah Stones: Level generation

Jan 25th, 2016
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.80 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using Random = UnityEngine.Random;
  7.  
  8. public class GenerationScript : MonoBehaviour
  9. {
  10.     [SerializeField] private LevelScript _levelScript = null;
  11.     [SerializeField] private List<GeneratedObjects> _traps=new List<GeneratedObjects>();
  12.     [SerializeField]private List<GeneratedObjects> _powerUps = new List<GeneratedObjects>();
  13.  
  14.     private GameObject _trapsAndPowerups;
  15.     private int _amountTiles;
  16.     private bool _finishInOneTick = false;
  17.  
  18.     private const float TrapValueMin = 0.175f;
  19.     private const float TrapValueMax = 0.25f;
  20.     private const float PowerUpValue = 0.925f;
  21.     private float _trapValue = 0.0f;
  22.     private const float EmptyZone = 5.0f;
  23.     private const float HeightAnvil = 1.5f;
  24.     private const int AmountRowsGeneratedPerTick = 30;
  25.     void Awake ()
  26.     {
  27.         var amountTilesFloat = ((_levelScript.Radius*2)/_levelScript.WidthObject);
  28.         _amountTiles = (int)amountTilesFloat;
  29.         if (Mathf.Approximately(_amountTiles + 1, amountTilesFloat)) _amountTiles++;
  30.         NormalizeGeneratedObjects(_traps);
  31.         NormalizeGeneratedObjects(_powerUps);
  32.     }
  33.  
  34.     //Normalize chances on objects
  35.     void NormalizeGeneratedObjects(List<GeneratedObjects> generatedObjects)
  36.     {
  37.         float totalChance = 0;
  38.         for (int i = 0; i < generatedObjects.Count;)
  39.         {
  40.             if (generatedObjects[i].Chance <= 0) generatedObjects.RemoveAt(i);
  41.             else
  42.             {
  43.                 totalChance += generatedObjects[i].Chance;
  44.                 i++;
  45.             }
  46.         }
  47.         if (Mathf.Approximately(totalChance, 0))
  48.         {
  49.             Debug.LogError("List has a total chance of 0");
  50.         }
  51.         float chanceDivision = 1.000000f / totalChance;
  52.         for (int i = 0; i < generatedObjects.Count; i++)
  53.         {
  54.             var generatedObject = generatedObjects[i];
  55.             var newChance = generatedObject.Chance * chanceDivision;
  56.             generatedObject.Chance = newChance;
  57.             generatedObjects[i] = generatedObject;
  58.         }
  59.     }
  60.  
  61.     //Generate level
  62.     public void Generate(float trapChanceT)
  63.     {
  64.         _trapValue = Mathf.Lerp(TrapValueMin, TrapValueMax, trapChanceT);
  65.         StartCoroutine(GenerateUpdate());
  66.     }
  67.  
  68.     //Make that the level automaticly finishes next tick
  69.     public void ForceFinishNextTick()
  70.     {
  71.         _finishInOneTick = true;
  72.     }
  73.  
  74.     //Generation Update
  75.     private IEnumerator GenerateUpdate()
  76.     {
  77.         _finishInOneTick = false;
  78.         if (_trapsAndPowerups)
  79.         {
  80.             //Put previous traps and powerups back in their pools
  81.             var poolableItems = _trapsAndPowerups.GetComponentsInChildren<PoolableItem>();
  82.             var poolItemsCount = poolableItems.Count();
  83.             for (int i = 0; i < poolItemsCount; i++)
  84.             {
  85.                 if (!poolableItems[i].PutInPool())
  86.                 {
  87.                     Destroy(poolableItems[i].gameObject);
  88.                 }
  89.             }
  90.             Destroy(_trapsAndPowerups);
  91.         }
  92.  
  93.         //Generate new level
  94.         _trapsAndPowerups = new GameObject();
  95.         int amount = 0;
  96.  
  97.         var seed=new Vector2(Random.Range(0.0f,1000.0f), Random.Range(0.0f, 1000.0f));
  98.         for (int m = 0; m < PickAChestScript.ActivePickAChestScript.AmountOfLevels; m++)
  99.         {
  100.             float startHeight = 100*m;
  101.             float endHeight = PickAChestScript.ActivePickAChestScript.SizeTunnelPiece - EmptyZone;
  102.             for (float i = EmptyZone; i <= endHeight; i += HeightAnvil)
  103.             {
  104.                 //Limit amount of lines that get generated every tick to improve performance
  105.                 if (!_finishInOneTick)
  106.                 {
  107.                     amount++;
  108.                     if (amount > AmountRowsGeneratedPerTick)
  109.                     {
  110.                         yield return null;
  111.                         amount -= AmountRowsGeneratedPerTick;
  112.                     }
  113.                 }
  114.                 GenerateLine(-(i+ startHeight),seed);
  115.             }
  116.         }
  117.     }
  118.  
  119.     //Generate one line
  120.     void GenerateLine(float height,Vector2 seed)
  121.     {
  122.         var xStart = -_levelScript.Radius + _levelScript.WidthObject * 0.5f;
  123.         var xDelta = ((_levelScript.Radius * 2) / _amountTiles);
  124.  
  125.         for (int i = 0; i < _amountTiles; i++)
  126.         {
  127.             var position = new Vector3(xStart + xDelta * i, height, 0);
  128.  
  129.             //Get value to see if trap, powerup or empty
  130.             var value = Mathf.PerlinNoise(position.x+seed.x, position.y+seed.y);
  131.             if (value < _trapValue)
  132.             {
  133.                 //Get random trap
  134.                 var trap = SelectGeneratedObjects(_traps).MakePoolItem(position, Quaternion.identity);
  135.                 if (trap != null) trap.transform.parent = _trapsAndPowerups.transform;
  136.             }
  137.             else if (value > PowerUpValue)
  138.             {
  139.                 //Get random powerup
  140.                 var powerup = SelectGeneratedObjects(_powerUps).MakePoolItem(position, Quaternion.identity);
  141.                 if (powerup != null) powerup.transform.parent = _trapsAndPowerups.transform;
  142.             }
  143.         }
  144.     }
  145.  
  146.     //Get random object
  147.     private Pool SelectGeneratedObjects(List<GeneratedObjects> _generatedObjects)
  148.     {
  149.         var chance = Random.Range(0.0f, 1.0f);
  150.         for (int i = 0; i < _generatedObjects.Count; i++)
  151.         {
  152.             chance -= _generatedObjects[i].Chance;
  153.             if (chance <= 0) return _generatedObjects[i].Pool;
  154.         }
  155.         if (_generatedObjects.Count == 0) return null;
  156.         return _generatedObjects[_generatedObjects.Count - 1].Pool;
  157.     }
  158. }
  159.  
  160.  
  161. [Serializable]
  162. public struct GeneratedObjects
  163. {
  164.     public Pool Pool;
  165.     public float Chance;
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement