Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* =================================================================================================
- *
- * How did it work?
- * - gridObject is an array (Vector3) that contains all Coordinates of each buildings and walls
- * - gridElement is an array (int) that contains all ID for each building.
- * in this way we can decide on which side the building should face based on the nearest element
- * also we can check where the road are, and if or not we already have spawned the Economic-Building (also called Commercial)
- *
- * CITY ELEMENTS
- * 0 = NONE
- * 99 = Main Square
- * 82 = Wall Corner
- * 81 = Wall
- * 80 = Wall Gate!
- * 1 = Building
- * 2 = Decoration
- * 3 = Duke Palace
- * 4 = Barracks // have to be placed near the gate and close to the road.
- * -1 = vertical straight road
- * -2 = horizontal straight road
- * -3 = bend road ?
- *
- * Each cell HAVE TO BE 15x15 Unity's Unit!
- *
- * ============================================================================================= */
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
- public class TownGenerator : MonoBehaviour
- {
- private Vector3[,] gridNodes; // used to define the cells position
- private int[,] gridElements; // used to define all buildings
- [Range(5, 20)]
- public int townSize = 5;
- private int cellSize = 15; // DO NOT TOUCH IT! // Change this parameter will mean change or check all prefabs involved!
- [Space]
- [SerializeField] private GameObject mainSquare;
- [SerializeField] private GameObject xRoad;
- [SerializeField] private GameObject zRoad;
- [SerializeField] private GameObject bendRoad;
- [Space]
- [Tooltip("Houses have to be the last on the bottom the list")]
- [SerializeField] private GameObject[] commercialBuildings;
- [SerializeField] private GameObject[] houseBuildings;
- [Tooltip("0 = small town > higher value more big city")]
- [SerializeField] private GameObject[] dukePalaces;
- [SerializeField] private GameObject[] barracks;
- [SerializeField] private GameObject[] decorations;
- [SerializeField] private GameObject[] walls;
- [SerializeField] private GameObject[] wallGate; // this is a 3 Cell size, so 15 x 3 = 45!
- [SerializeField] private GameObject[] wallCorner;
- private GameObject gridObject;
- private int gridCenter = 0; // just 1 value 'cause the town is squared!
- private void Start()
- {
- townSize += 2;
- // Init arrays
- gridNodes = new Vector3[townSize, townSize]; // for the coords
- gridElements = new int[townSize, townSize]; // for the buildings to be placed
- // Create the GameObject that will contain the entire town.
- gridObject = new GameObject();
- gridObject.name = "Grid Object";
- gridObject.transform.parent = transform;
- // Create the GameObject that will contain the entire City Walls!
- GameObject cityWalls = new GameObject();
- cityWalls.name = "City Walls";
- cityWalls.transform.parent = gridObject.transform;
- gridNodes = new Vector3[townSize, townSize]; // init the Grid // This contain the building coordinates to spawn the building
- float halfCell = cellSize / 2;
- gridCenter = Mathf.CeilToInt((float)townSize / 2) - 1;
- // First we fill the Coordinate for each cell.
- for (int x = 0; x < townSize; x++) // the grid construction goes from bottom-left on the top (along Z axis)
- {
- for (int z = 0; z < townSize; z++)
- {
- gridNodes[x, z] = new Vector3((x * cellSize) + halfCell, 0f, (z * cellSize) + halfCell); // Save the center of each cell.
- }
- }
- #region ===== PLACING WALLS AND GATES ===========================================
- for (int x = 0; x < townSize; x++) // the grid construction goes from bottom-left on the top (along Z axis)
- {
- for (int z = 0; z < townSize; z++)
- {
- if (x == 0 || z == 0 || x == townSize - 1 || z == townSize - 1)
- {
- // Do I have to place the Gate?
- if (x == gridCenter)
- {
- if (z == 0) // We are at South
- {
- GameObject wall = Instantiate(wallGate[Random.Range(0, walls.Length - 1)], cityWalls.transform);
- wall.transform.position = gridNodes[x, z];
- wall.transform.rotation = Quaternion.Euler(0, 90, 0);
- wall.name = wall.name + ":" + x + "," + z;
- continue;
- }
- else
- {
- gridElements[x, z] = 80;
- GameObject wall = Instantiate(wallGate[Random.Range(0, walls.Length - 1)], cityWalls.transform);
- wall.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, 270, 0));
- wall.name = wall.name + ":" + x + "," + z;
- continue;
- }
- }
- else
- {
- gridElements[x, z] = 81;
- WallBuilder(x, z, cityWalls.transform);
- continue;
- }
- }
- }
- }
- #endregion
- #region ===== PROTOTYPING THE TOWN ==============================================
- bool isDucalPlaced = false;
- bool barracksPlaced = false;
- for (int x = 0; x < townSize; x++) // the grid construction goes from bottom-left on the top (along Z axis)
- {
- for (int z = 0; z < townSize; z++)
- {
- if (gridElements[x, z] >= 80) // This is used to avoid walls and gates cells ;-)
- continue;
- #region === THIS IS FOR DEBUG ===
- // SpawnCube(x, z);
- // continue; // This is for the debug if you are using SpawnCube method
- #endregion ======================
- // Main Square
- if (x == gridCenter && z == gridCenter)
- {
- gridElements[x, z] = 99;
- continue;
- }
- // One Time Run for the Duke's Palace
- if (isDucalPlaced == false)
- {
- // Select one of the 8 spot for the Dual Building
- int ducalSpot = Random.Range(1, 8);
- //Debug.Log(ducalSpot);
- switch (ducalSpot)
- {
- case 1:
- isDucalPlaced = true;
- gridElements[gridCenter - 1, gridCenter - 1] = 3; // Bottom Left
- if (gridElements[gridCenter - 2, gridCenter - 1] == 0)
- gridElements[gridCenter - 2, gridCenter - 1] = -2; //... add road chunk
- continue;
- case 2:
- isDucalPlaced = true;
- gridElements[gridCenter - 1, gridCenter] = 3; // Mid Left
- if (gridElements[gridCenter - 2, gridCenter] == 0)
- gridElements[gridCenter - 2, gridCenter] = -2; //... add road chunk
- continue;
- case 3:
- isDucalPlaced = true;
- gridElements[gridCenter - 1, gridCenter + 1] = 3; // Top Left
- if (gridElements[gridCenter - 2, gridCenter + 1] == 0)
- gridElements[gridCenter - 2, gridCenter + 1] = -2; //... add road chunk
- continue;
- case 4:
- isDucalPlaced = true;
- gridElements[gridCenter, gridCenter - 1] = 3; // Bottom Mid.
- continue;
- case 5:
- isDucalPlaced = true;
- gridElements[gridCenter, gridCenter + 1] = 3; // Top Mid.
- continue;
- case 6:
- isDucalPlaced = true;
- gridElements[gridCenter + 1, gridCenter - 1] = 3; // Bottom Right
- if (gridElements[gridCenter + 2, gridCenter - 1] == 0)
- gridElements[gridCenter + 2, gridCenter - 1] = -2; //... add road chunk
- continue;
- case 7:
- isDucalPlaced = true;
- gridElements[gridCenter + 1, gridCenter] = 3; // Mid Right
- if (gridElements[gridCenter + 2, gridCenter] == 0)
- gridElements[gridCenter + 2, gridCenter] = -2; //... add road chunk
- continue;
- case 8:
- isDucalPlaced = true;
- gridElements[gridCenter + 1, gridCenter + 1] = 3; // Top Right
- if (gridElements[gridCenter + 2, gridCenter + 1] == 0)
- gridElements[gridCenter + 2, gridCenter + 1] = -2; //... add road chunk
- continue;
- }
- }
- // Place the barracks
- if(barracksPlaced == false)
- {
- if (Utilities.RandomBool())
- gridElements[gridCenter - 1, 1] = 4;
- else
- gridElements[gridCenter + 1, townSize -2] = 4;
- }
- // Adding Roads
- if ((x == gridCenter && z > 0) || (x == gridCenter && z < townSize - 1))
- {
- if (gridElements[x, z] == 0)
- gridElements[x, z] = -1;
- continue;
- }
- // Nothing on the current cell, so let's place a building
- ///<TODO>Refine the block to choose better what spawn</TODO>
- if (gridElements[x, z] == 0)
- gridElements[x, z] = 1;
- }
- }
- #endregion
- SpawnBuildings();
- // Moving the Grid at 0,0,0
- gridObject.transform.position = new Vector3(gridObject.transform.position.x - ((float)townSize * cellSize) / 2, 0f, gridObject.transform.position.z - ((float)townSize * cellSize) / 2);
- }
- private void SpawnBuildings()
- {
- #region ===== Objects Parents ===================================================
- // Create the GameObject that will contain all Economic Buildings
- GameObject roadsObjs = new GameObject();
- roadsObjs.name = "Roads";
- roadsObjs.transform.parent = gridObject.transform;
- // Create the GameObject that will contain all Economic Buildings
- GameObject commBuilds = new GameObject();
- commBuilds.name = "Buildings";
- commBuilds.transform.parent = gridObject.transform;
- // Create the GameObject that will contain all city Decorations
- GameObject decoObjs = new GameObject();
- decoObjs.name = "Decorations";
- decoObjs.transform.parent = gridObject.transform;
- #endregion
- for (int x = 0; x < townSize; x++) // the grid construction goes from bottom-left on the top (along Z axis)
- {
- for (int z = 0; z < townSize; z++)
- {
- //Debug.Log("Spawning " + gridElements[x, z] + " at " + x + "," + z);
- switch (gridElements[x,z])
- {
- case 0:
- break;
- case 99:
- GameObject square = Instantiate(mainSquare, gridObject.transform);
- square.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, 270, 0));
- square.name = square.name + ":" + x + "," + z;
- continue;
- case 82:
- continue;
- case 81:
- continue;
- case 80:
- continue;
- case 1:
- GameObject builds = Instantiate(commercialBuildings[Random.Range(0, commercialBuildings.Length)], commBuilds.transform);
- builds.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, 270, 0));
- builds.name = builds.name + ":" + x + "," + z;
- continue;
- case 2:
- continue;
- case 3:
- GameObject dukePalace = Instantiate(dukePalaces[0], commBuilds.transform);
- dukePalace.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, FaceMainSquare(x,z), 0));
- dukePalace.name = dukePalace.name + ":" + x + "," + z;
- break;
- case 4:
- GameObject barraksObj = Instantiate(barracks[0], commBuilds.transform);
- barraksObj.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, FaceMainSquare(x,z), 0));
- barraksObj.name = barraksObj.name + ":" + x + "," + z;
- break;
- case -1: // ROADS
- GameObject roadVert = Instantiate(zRoad, roadsObjs.transform);
- roadVert.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, 0, 0));
- roadVert.name = roadVert.name + ":" + x + "," + z;
- continue;
- case -2:
- GameObject roadHor = Instantiate(zRoad, roadsObjs.transform);
- roadHor.transform.SetPositionAndRotation(gridNodes[x, z], Quaternion.Euler(0, 90, 0));
- roadHor.name = roadHor.name + ":" + x + "," + z;
- continue;
- case -3:
- continue;
- default:
- continue;
- }
- }
- }
- }
- private GameObject WallBuilder(int x, int z, Transform parent)
- {
- // Debug.Log(x + " " + z);
- GameObject wall;
- float angle = 0f;
- bool corner = false;
- if (x == 0 && z == 0) // Bottom Left
- {
- corner = true;
- angle = 90;
- }
- else if (x == 0 && z == townSize - 1) // Top Left
- {
- corner = true;
- angle = 180;
- }
- else if (x == townSize - 1 && z == 0) // Bottom Right
- {
- corner = true;
- angle = 0;
- }
- else if (x == townSize - 1 && z == townSize - 1) // Top Right
- {
- corner = true;
- angle = 270;
- }
- else if (x == 0 && z > 0) // Walls Left
- {
- corner = false;
- angle = 180;
- }
- else if (x == townSize -1 && z > townSize -1) // Walls Right
- {
- corner = false;
- angle = 180;
- }
- else if (x > 0 && z == townSize -1) // Walls North
- {
- corner = false;
- angle = 270;
- }
- else if (x > 0 && z == 0) // Walls South
- {
- corner = false;
- angle = 90;
- }
- // it's a corner
- if (corner)
- {
- gridElements[x, z] = 82;
- wall = Instantiate(wallCorner[Random.Range(0, wallCorner.Length - 1)], parent);
- wall.transform.position = gridNodes[x, z];
- wall.transform.rotation = Quaternion.Euler(0, angle, 0);
- }
- else
- {
- gridElements[x, z] = 82;
- wall = Instantiate(walls[Random.Range(0, walls.Length - 1)], parent);
- wall.transform.position = gridNodes[x, z];
- wall.transform.rotation = Quaternion.Euler(0, angle, 0);
- wall.name = wall.name + ":" + x +","+ z;
- }
- return wall;
- }
- /// <summary>
- /// Rotate the building to face the MainSquare
- /// </summary>
- /// <param name="x">Your X grid position</param>
- /// <param name="z">Your Z grid position</param>
- /// <returns></returns>
- private float FaceMainSquare(int x, int z)
- {
- if (x == gridCenter - 1 && z == gridCenter -1) // Bottom Left
- return 270;
- if (x == gridCenter - 1 && z == gridCenter) // Mid Left
- return 270;
- if (x == gridCenter - 1 && z == gridCenter +1) // Top Left
- return 270;
- if (x == gridCenter && z == gridCenter - 1) // Bottom Center
- return 0;
- if (x == gridCenter +1 && z == gridCenter + 1) // Top Center
- return 90;
- if (x == gridCenter + 1 && z == gridCenter - 1) // Bottom Right
- return 90;
- if (x == gridCenter + 1 && z == gridCenter) // Mid Right
- return 90;
- if (x == gridCenter + 1 && z == gridCenter + 1) // Top Right
- return 90;
- return 0;
- }
- private void SpawnCube(int x, int z)
- {
- GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
- cube.transform.localScale = new Vector3(cellSize, 2f, cellSize);
- cube.transform.position = gridNodes[x, z];
- cube.transform.position = new Vector3(cube.transform.position.x, cube.transform.position.y * .5f, cube.transform.position.z);
- cube.transform.parent = gridObject.transform;
- cube.transform.name = cube.name + " ("+ x + "," + z +")";
- }
- }
Add Comment
Please, Sign In to add comment