public void Initialise(BuildingGenerator bg) { gridGenerator = bg.gridGenerator; edgelength = gridGenerator.cellSize; generationAllowed = true; //Temporary cellCollider = gridGenerator.getCellCollider(); mainCam = Camera.main; camTransform = mainCam.gameObject.transform; groundCursor = GlobalInformation.groundCursor.transform; viewDistance = GlobalInformation.viewDistance; buildingGenerator = bg; localSeed = GlobalInformation.hash((int)transform.position.x ^ GlobalInformation.hash(GlobalInformation.worldSeed ^ (int)transform.position.z)); initialised = true; }
void Start() { Random.InitState(GlobalInformation.hash(GlobalInformation.worldSeed ^ gameObject.name.GetHashCode())); PerlinOffset = Random.Range(0, 100); cubeRotation = transform.rotation; transform.rotation = Quaternion.identity; cellCollider = new GameObject(); generators = GetComponentsInChildren <BuildingGenerator>(); ArrayList obstacles = new ArrayList(); foreach (Collider col in FindObjectsOfType <Collider>()) { if (!col.CompareTag("ignore")) { Debug.Log(col.name + " is added to obstacles by " + name); obstacles.Add(col); } } Debug.Log(name); //compute cellSize by computing maximum building dimensions if (automaticCellsize) { float biggestSize = 0; foreach (BuildingGenerator generator in generators) { foreach (buildingStep step in generator.steps) { if (step.isPolygon) { if (biggestSize < step.maxRadius * 2) { Debug.Log("step.maxRadius * 2 = " + step.maxRadius * 2); biggestSize = step.maxRadius * 2; } } else { if (biggestSize < Mathf.Sqrt(step.maxWidth * step.maxWidth + step.maxLength * step.maxLength) * 2) { Debug.Log(String.Format("Mathf.Sqrt({0}*{0}+{1}*{1}) = {2})*2", step.maxWidth, step.maxLength, Mathf.Sqrt(step.maxWidth * step.maxWidth + step.maxLength * step.maxLength) * 2)); biggestSize = Mathf.Sqrt(step.maxWidth * step.maxWidth + step.maxLength * step.maxLength) * 2; } } } } cellSize = Mathf.CeilToInt(biggestSize) + roadWidth / 4; } //--------------------------------------------------------- areaLength = GlobalInformation.get2DBounds(gameObject).x; areaWidth = GlobalInformation.get2DBounds(gameObject).y; //Generate cellgrid GameObject cellGridParent = new GameObject(); cellGridParent.name = "CellGrid" + name; cellGridParent.transform.parent = transform; cellGrid = generateCellGrid(cellGridParent.transform); //Generate streetGrid GameObject streetGridParent = new GameObject(); streetGridParent.name = "StreetGrid" + name; streetGridParent.transform.parent = transform; streetGrid = generateStreetGrid(streetGridParent.transform); //Delete Grid where Obstacles are found foreach (Collider col in obstacles) { RaycastHit hit; Ray ray; foreach (Transform obj in streetGridParent.GetComponentsInChildren <Transform>()) { //Check if obj is within obstacle try{ Vector3 offset = col.bounds.center - obj.position; ray = new Ray(obj.position, offset.normalized); if (!col.Raycast(ray, out hit, offset.magnitude * 1.1f)) { Debug.Log(obj.name + "will be destroyed"); Destroy(obj.gameObject); } } catch (Exception e) { Debug.LogWarning(e); } } foreach (Transform obj in cellGridParent.GetComponentsInChildren <Transform>()) { //Check if obj is within obstacle try{ Vector3 offset = col.bounds.center - obj.position; ray = new Ray(obj.position, offset.normalized); if (!col.Raycast(ray, out hit, offset.magnitude * 1.1f)) { Debug.Log(obj.name + "will be destroyed"); Destroy(obj.gameObject); } } catch (Exception e) { Debug.LogWarning(e); } } } //-------------------------------- foreach (Collider col in GetComponentsInChildren <Collider>()) { col.gameObject.tag = "ignore"; } gameObject.GetComponent <MeshRenderer>().enabled = false; transform.rotation = cubeRotation; }
Node[,] generateStreetGrid(Transform parent) { //Lay out grid of nodes Node[,] grid = new Node[(int)areaLength / cellSize, (int)areaWidth / cellSize]; for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { grid[i, j] = new Node(new Vector3( cellGrid[i, j].transform.position.x + cellSize / 2, 0, cellGrid[i, j].transform.position.z + cellSize / 2 )); } } //----------------------- Random.InitState(GlobalInformation.hash(GlobalInformation.worldSeed ^ gameObject.name.GetHashCode())); //Instantiate street Grid in random fashion--------- for (int i = 0; i < (int)areaLength / cellSize; i++) { for (int j = 0; j < (int)areaWidth / cellSize; j++) { //Instantiate street to the west if (Random.Range(0.0f, 1.0f) > streetDensity) { GameObject streetWest = Instantiate(street, new Vector3(grid[i, j].position.x, 0.1f, grid[i, j].position.z - cellSize / 2), street.transform.rotation); streetWest.AddComponent <Street>(); streetWest.name = "Street_x=" + grid[i, j].position.x + ", z=" + (grid[i, j].position.z - cellSize / 2); streetWest.transform.parent = parent; grid[i, j].roadEast = true; try { grid[i, j - 1].roadWest = true; } catch (Exception) { } } //Instantiate street to the south if (Random.Range(0.0f, 1.0f) > streetDensity) { GameObject streetSouth = Instantiate(street, new Vector3(grid[i, j].position.x - cellSize / 2, 0.1f, grid[i, j].position.z), street.transform.rotation); streetSouth.AddComponent <Street>(); streetSouth.name = "Street_x=" + (grid[i, j].position.x - cellSize / 2) + ", z=" + grid[i, j].position.z; streetSouth.transform.parent = parent; streetSouth.transform.Rotate(new Vector3(0, 90, 0)); grid[i, j].roadSouth = true; try { grid[i - 1, j].roadNorth = true; } catch (Exception) { } } } } //--------------------------------------------------- //Connect the streets-------------------------------- GameObject con = new GameObject(); foreach (Node n in grid) { if (n.roadNorth && n.roadSouth && n.roadEast && n.roadWest) //crossroad { con = crossRoad(n); } if (!n.roadNorth && n.roadSouth && n.roadEast && n.roadWest) //T-junction w/o North { con = tJunction(n); } if (n.roadNorth && n.roadSouth && !n.roadEast && n.roadWest) //T-junction w/o East { con = tJunction(n); } if (n.roadNorth && !n.roadSouth && n.roadEast && n.roadWest) //T-junction w/o South { con = tJunction(n); } if (n.roadNorth && n.roadSouth && n.roadEast && !n.roadWest) //T-junction w/o West { con = tJunction(n); } if (!n.roadNorth && !n.roadSouth && n.roadEast && n.roadWest) //Connect 2 horizontal streets { con = connectHorizontal(n); } if (n.roadNorth && n.roadSouth && !n.roadEast && !n.roadWest) //Connect 2 vertical streets { con = connectVertical(n); } if (n.roadNorth && !n.roadSouth && n.roadEast && !n.roadWest) //Corner N/E { con = corner(n); } if (!n.roadNorth && n.roadSouth && n.roadEast && !n.roadWest) //Corner E/S { con = corner(n); } if (!n.roadNorth && n.roadSouth && !n.roadEast && n.roadWest) //Corner S/W { con = corner(n); } if (n.roadNorth && !n.roadSouth && !n.roadEast && n.roadWest) //Corner W/N { con = corner(n); } if (n.roadNorth && !n.roadSouth && !n.roadEast && !n.roadWest) //end N { con = end(n); } if (!n.roadNorth && !n.roadSouth && n.roadEast && !n.roadWest) //end E { con = end(n); } if (!n.roadNorth && n.roadSouth && !n.roadEast && !n.roadWest) //end S { con = end(n); } if (!n.roadNorth && !n.roadSouth && !n.roadEast && n.roadWest) //end W { con = end(n); } //If node has got a gameobject try { con.GetComponent <Street>().setNode(n); n.inheritor = con; } catch (Exception) { } //add connection to street parent con.transform.parent = parent; } //--------------------------------------------------- //Set height of all streets------------------------------ float spawnHeight = 0; foreach (Node n in grid) { int i = 0; bool found = false; //Get height of terrain at every node while (!found) { RaycastHit hit; if (Physics.Raycast(new Vector3(n.position.x, i, n.position.z), transform.TransformDirection(-Vector3.up), out hit)) { if (hit.collider.gameObject == GlobalInformation.terrain) { if (hit.point.y > spawnHeight) { spawnHeight = hit.point.y + 0.1f; } found = true; } } i++; if (i > 100) { Debug.LogError("Something is wrong, is there terrain?"); found = true; } } } foreach (Transform child in parent.GetComponentsInChildren <Transform>()) { if (child.GetComponent <Street>()) { child.position = new Vector3(child.position.x, spawnHeight + 0.1f, child.position.z); } } //------------------------------------------------------ return(grid); }