using System.Collections.Generic; using UnityEngine; public class LevelGenerator : MonoBehaviour { public List<GameObject> tileSets = new List<GameObject>(); public List<GameObject> tileRightConnectors = new List<GameObject>(); public List<GameObject> tileLeftConnectors = new List<GameObject>(); private List<GameObject> createdNormalTiles = new List<GameObject>(); private List<GameObject> createdConnectorTiles = new List<GameObject>(); private List<GameObject> createdBackgrounds = new List<GameObject>(); private List<GameObject> createdClouds = new List<GameObject>(); private List<GameObject> createdParticles = new List<GameObject>(); private GameObject createdSecretTile; List<GameObject> inactiveTileSets = new List<GameObject>(); List<GameObject> inactiveRightConnectorTileSets = new List<GameObject>(); List<GameObject> inactiveLeftConnectorTileSets = new List<GameObject>(); List<GameObject> inactiveBackgrounds = new List<GameObject>(); private GameObject envObjects; private GameObject deathWall; public GameObject backgroundPrefab; public GameObject cloudsPrefab; public GameObject particlesPrefab; public Material baseBackgroundMaterial; public Sprite baseBackgroundSprite; public Material backgroundVariationMaterial; public Sprite backgroundVariationSprite; public Material baseFadeBackgroundMaterial; public Sprite baseFadeBackgroundSprite; public Material backgroundFadeVariationMaterial; public Sprite backgroundFadeVariationSprite; public GameObject secretTilePrefab; private GameObject baseBackground; private GameObject playerObject; private int tileIteration = 0; private int tileCurrentHeight = 0; private int tileBuildHeight = 0; private bool secretTileUsed; private Color[] colors = new Color[] { new Color(0.7f, 0, 1, 1), //purple new Color(1, 0.5f, 0, 1), //orange new Color(0.85f, 0.7f, 0, 1), //gold new Color(1, 0.8f, 0.4f, 1), //sunOrange new Color(0.7f, 1, 0.21f, 1), //crimson new Color(0.54f, 0.23f, 0, 1), //brown new Color(0.66f, 0.66f, 0.66f, 1), //silver new Color(0.78f, 0.5f, 0.18f, 1), //bronze new Color(0.61f, 0.82f, 0.9f, 1), //diamond new Color(0.1f, 0.52f, 0.7f, 1), //dark blue new Color(0.83f, 0.4f, 0.65f, 1), //pink new Color(0.52f, 0.55f, 0.77f, 1), //light blue new Color(0.17f, 1, 0.4f, 1) //light green }; public List<GameObject> CreatedNormalTiles { get => createdNormalTiles; set => createdNormalTiles = value; } public List<GameObject> CreatedConnectorTiles { get => createdConnectorTiles; set => createdConnectorTiles = value; } public List<GameObject> CreatedBackgrounds { get => createdBackgrounds; set => createdBackgrounds = value; } public List<GameObject> CreatedClouds { get => createdClouds; set => createdClouds = value; } public List<GameObject> CreatedParticles { get => createdParticles; set => createdParticles = value; } private void Awake() { envObjects = GameObject.Find("Env Objects"); playerObject = ObjectManager.GetObject(0); } private void Start() { baseBackground = GUIManager.GetObject(0); deathWall = ObjectManager.GetObject(2); //ChangeBaseBackgroundColor(); //tiles will only need to be created once since the same tiles will be used for everything CreateTileSets(); BuildLevel(); } private void Update() { //if the player is above the tile build height, place more tiles if (!GUIManager.GetMainMenuCanvasState()) { bool playerState = playerObject.activeSelf; if (playerState) { int playerHeight = Mathf.RoundToInt(playerObject.transform.position.y + 3.5f); if (playerHeight >= tileBuildHeight) { BuildLevel(); } } else { int deathWallHeight = Mathf.RoundToInt(deathWall.transform.position.y + 35); if (deathWallHeight >= tileBuildHeight) { BuildLevel(); } } } } public void CreateTileSets() { try { //Make 2 copies of each tile set and then turn them off for (int i = 0; i < tileSets.Count; i++) { for (int y = 0; y < 2; y++) { createdNormalTiles.Add(Instantiate(tileSets[i] as GameObject, envObjects.transform)); createdNormalTiles[createdNormalTiles.Count - 1].SetActive(false); } } //Make 2 copies of all right and left connectors for (int i = 0; i < tileRightConnectors.Count; i++) { for (int y = 0; y < 2; y++) { createdConnectorTiles.Add(Instantiate(tileRightConnectors[i] as GameObject, envObjects.transform)); createdConnectorTiles[createdConnectorTiles.Count - 1].SetActive(false); } } for (int i = 0; i < tileRightConnectors.Count; i++) { for (int y = 0; y < 2; y++) { createdConnectorTiles.Add(Instantiate(tileLeftConnectors[i] as GameObject, envObjects.transform)); createdConnectorTiles[createdConnectorTiles.Count - 1].SetActive(false); } } //make 5 background objects for (int i = 0; i < 5; i++) { createdBackgrounds.Add(Instantiate(backgroundPrefab as GameObject, envObjects.transform)); createdBackgrounds[i].SetActive(false); } //make 1 copy of the secret tile createdSecretTile = Instantiate(secretTilePrefab as GameObject, envObjects.transform); createdSecretTile.SetActive(false); } catch (System.Exception e) { Debug.Log(e.StackTrace); } } public void SetTileObstaclesStates(bool newState) { foreach (GameObject normalTile in createdNormalTiles) { normalTile.GetComponent<TileControl>().SetObstaclesState(newState); } foreach (GameObject connectorTile in createdConnectorTiles) { connectorTile.GetComponent<TileControl>().SetObstaclesState(newState); } } public void BuildLevel() { try { GameObject targetTileSet; int tileXPos = -20; int tileYPos = 0; //find and add any inactive tiles to the list that have not been added foreach (GameObject tileSet in createdNormalTiles) { if (!tileSet.activeSelf && !inactiveTileSets.Contains(tileSet)) inactiveTileSets.Add(tileSet); } foreach (GameObject tileSet in createdConnectorTiles) { if (!tileSet.activeSelf && tileSet.CompareTag("Right Tile") && !inactiveRightConnectorTileSets.Contains(tileSet)) inactiveRightConnectorTileSets.Add(tileSet); if (!tileSet.activeSelf && tileSet.CompareTag("Left Tile") && !inactiveLeftConnectorTileSets.Contains(tileSet)) inactiveLeftConnectorTileSets.Add(tileSet); } foreach (GameObject background in createdBackgrounds) { if (!background.activeSelf && !inactiveBackgrounds.Contains(background)) inactiveBackgrounds.Add(background); } //raise the tile height to match the new height for the start of this set for (int i = 0; i < tileIteration; i++) { tileYPos += 40; } //if this is not the first itteration, added a new background and BG effects if (tileIteration > 0) { GameObject tempBackground = inactiveBackgrounds[Random.Range(0, inactiveBackgrounds.Count)]; GameObject tempClouds = Instantiate(cloudsPrefab as GameObject, envObjects.transform); GameObject tempParticles = Instantiate(particlesPrefab as GameObject, envObjects.transform); tempBackground.SetActive(true); tempBackground.transform.position = new Vector3(0, tileYPos + 40, 1); tempClouds.transform.position = tempBackground.transform.position; tempParticles.transform.position = new Vector3(0, tempBackground.transform.position.y - 40, 2); int randomColor = Random.Range(0, colors.Length); //NO LONGER NEEDED. NO BACKGROUND COLOR CHANGES. //tempBackground.GetComponent<SpriteRenderer>().material.color = colors[randomColor]; //foreach (Transform transform in tempBackground.GetComponentInChildren<Transform>()) //{ // transform.gameObject.GetComponent<SpriteRenderer>().material.color = colors[randomColor]; //} inactiveBackgrounds.Remove(tempBackground); createdClouds.Add(tempClouds); createdParticles.Add(tempParticles); } //place 12 different tiles into the set positions for (int i = 0; i < 12; i++) { //if in position to place a connector, choose if one should be placed if ((tileXPos == -20 || tileXPos == 0) && inactiveRightConnectorTileSets.Count > 0) { //if so, choose a connector from both the right and left sets and place them if (Random.Range(0, 2) == 1) { targetTileSet = inactiveRightConnectorTileSets[Random.Range(0, inactiveRightConnectorTileSets.Count)]; GameObject targetLeftConnector = inactiveLeftConnectorTileSets[Random.Range(0, inactiveLeftConnectorTileSets.Count)]; targetTileSet.SetActive(true); targetTileSet.transform.position = new Vector2(tileXPos, tileYPos); targetLeftConnector.SetActive(true); targetLeftConnector.transform.position = new Vector2(tileXPos + 20, tileYPos); SpawnItemsOnTileSet(targetTileSet); SpawnItemsOnTileSet(targetLeftConnector); inactiveRightConnectorTileSets.Remove(targetTileSet); inactiveLeftConnectorTileSets.Remove(targetLeftConnector); //increment the tile position to account for the 2 new tiles tileXPos += 40; if (tileXPos == 40) { tileXPos = -20; tileYPos += 20; } //increment i to account for the 2nd tile added i++; } else //if a connector is not going to be used, place a random normal tile { targetTileSet = inactiveTileSets[Random.Range(0, inactiveTileSets.Count)]; targetTileSet.SetActive(true); targetTileSet.transform.position = new Vector2(tileXPos, tileYPos); SpawnItemsOnTileSet(targetTileSet); inactiveTileSets.Remove(targetTileSet); tileXPos += 20; if (tileXPos == 40) { tileXPos = -20; tileYPos += 20; } } } else //if not in position for a right connector OR no connectors were available, create a normal tile { //choose if the secret tile will be used if at xPos 20 //check if the tile has already been used in the current run if (!secretTileUsed && tileXPos == 20 && tileBuildHeight >= 320) { int secretWallUseChance = Random.Range(0, 100); if (secretWallUseChance > 97) { targetTileSet = createdSecretTile; secretTileUsed = true; } else targetTileSet = inactiveTileSets[Random.Range(0, inactiveTileSets.Count)]; } else { targetTileSet = inactiveTileSets[Random.Range(0, inactiveTileSets.Count)]; } targetTileSet.SetActive(true); targetTileSet.transform.position = new Vector2(tileXPos, tileYPos); SpawnItemsOnTileSet(targetTileSet); inactiveTileSets.Remove(targetTileSet); tileXPos += 20; if (tileXPos == 40) { tileXPos = -20; tileYPos += 20; } } } tileIteration += 2; tileCurrentHeight += 80; tileBuildHeight = tileCurrentHeight - 20; } catch (System.Exception e) { Debug.LogError(e.StackTrace); } } public void SpawnItemsOnTileSet(GameObject tileSet) { try { tileSet.GetComponent<TileControl>().SpawnItems(); } catch (System.Exception e) { Debug.Log(e.StackTrace); } } public void ResetLevel() { for (int i = 0; i < createdNormalTiles.Count; i++) { ResetTileSet(createdNormalTiles[i]); } for (int i = 0; i < createdConnectorTiles.Count; i++) { ResetTileSet(createdConnectorTiles[i]); } ResetTileSet(createdSecretTile); for (int i = 0; i < createdBackgrounds.Count; i++) { createdBackgrounds[i].SetActive(false); } for (int i = 0; i < createdClouds.Count; i++) { GameObject[] tempRefs = createdClouds.ToArray(); Destroy(tempRefs[i]); } for (int i = 0; i < createdParticles.Count; i++) { GameObject[] tempRefs = createdParticles.ToArray(); Destroy(tempRefs[i]); } createdClouds.Clear(); createdParticles.Clear(); tileIteration = 0; tileCurrentHeight = 0; tileBuildHeight = 0; secretTileUsed = false; //ChangeBaseBackgroundColor(); } //public void ChangeBaseBackgroundColor() //{ // int randomColor = Random.Range(0, colors.Length); // baseBackground.GetComponent<SpriteRenderer>().material.color = colors[randomColor]; //} public void ChangeAllTilesBackgroundMaterials() { //called from unlock system to change the appearance of backgrounds for (int i = 0; i < createdBackgrounds.Count; i++) { createdBackgrounds[i].GetComponent<SpriteRenderer>().material = backgroundVariationMaterial; createdBackgrounds[i].GetComponent<SpriteRenderer>().sprite = backgroundVariationSprite; foreach (Transform item in CreatedBackgrounds[i].GetComponentInChildren<Transform>()) { if (item.name == "Bottom Fade") { item.GetComponent<SpriteRenderer>().material = backgroundFadeVariationMaterial; item.GetComponent<SpriteRenderer>().sprite = backgroundFadeVariationSprite; } } } baseBackground.GetComponent<SpriteRenderer>().material = backgroundVariationMaterial; baseBackground.GetComponent<SpriteRenderer>().sprite = backgroundVariationSprite; } public void RevertAllBackgroundMaterials() { //called when resetting unlocks to reset backgrounds to their default material. Color lastColor = baseBackground.GetComponent<SpriteRenderer>().material.color; for (int i = 0; i < createdBackgrounds.Count; i++) { createdBackgrounds[i].GetComponent<SpriteRenderer>().material = baseBackgroundMaterial; createdBackgrounds[i].GetComponent<SpriteRenderer>().material.color = lastColor; createdBackgrounds[i].GetComponent<SpriteRenderer>().sprite = baseBackgroundSprite; foreach (Transform item in CreatedBackgrounds[i].GetComponentInChildren<Transform>()) { if (item.name == "Bottom Fade") { item.GetComponent<SpriteRenderer>().material = baseFadeBackgroundMaterial; item.GetComponent<SpriteRenderer>().material.color = lastColor; item.GetComponent<SpriteRenderer>().sprite = baseFadeBackgroundSprite; } } } baseBackground.GetComponent<SpriteRenderer>().material = baseBackgroundMaterial; baseBackground.GetComponent<SpriteRenderer>().material.color = lastColor; baseBackground.GetComponent<SpriteRenderer>().sprite = baseBackgroundSprite; } private void ResetTileSet(GameObject tileToReset) { tileToReset.SetActive(false); tileToReset.GetComponent<TileControl>().RemoveItems(); foreach (Transform item in tileToReset.GetComponentsInChildren<Transform>()) { if (item.TryGetComponent(out BoxCollider2D boxColl)) if(boxColl.name == "Blocker Wall") boxColl.enabled = false; else boxColl.enabled = true; if (item.TryGetComponent(out SpriteRenderer targetSprite)) { Color currentSpriteColor = targetSprite.color; if (item.name == "Glow") targetSprite.color = new Color(currentSpriteColor.r, currentSpriteColor.g, currentSpriteColor.b, 0.1019608f); else if (item.name.Contains("Gradient")) targetSprite.color = new Color(currentSpriteColor.r, currentSpriteColor.g, currentSpriteColor.b, 0.07843138f); else targetSprite.color = new Color(currentSpriteColor.r, currentSpriteColor.g, currentSpriteColor.b, 1); if(item.name.Contains("Wall Piece")) item.gameObject.SetActive(false); } } } }