/// <summary> /// Called at beginning of game. /// Generates a X_MAX x Z_MAX tile grid out of the tile gameobject /// </summary> public void GenerateGrid() { // Builds walls that encompass the playmat. BuildAWall(-1, Z_MAX, -1, 'z', toyBlock); // West wall BuildAWall(-1, Z_MAX, X_MAX, 'z', toyBlock); // East wall BuildAWall(0, X_MAX, -1, 'x', toyBlock); // South wall BuildAWall(-1, X_MAX + 1, Z_MAX, 'x', toyBlock); // North wall GenerateTiles(); GameGrid2DObject grid = ProcedurallyPlaceObstacles(toyBlock); PlaceResources(grid, fluff, plastic); //minionNavMeshSurface.BuildNavMesh(); // only bake after obstacles have been placed bakeNavMesh(); }
/// <summary> /// Places resources around the grid, making sure not to collide with existing objects. /// </summary> /// <param name="grid">reference to grid object for tile access</param> /// <param name="fluff">an array for holding fluff game objects</param> /// <param name="plastic">an array for holding plastic game objects</param> private void PlaceResources(GameGrid2DObject grid, GameObject[] fluff, GameObject[] plastic) { // Tear down any leftover resources hanging out in resourceFondler from previous runs resourceFondler.transform.DetachChildren(); List <GameObject> fluffs = new List <GameObject>(); List <GameObject> plastics = new List <GameObject>(); //int gridLoopCount = 0; // Keep looping around the grid until the max for each type of resource has been fulfilled while (fluffs.Count < maxFluff || plastics.Count < maxPlastic) { foreach (TileObject t in grid) { int placeChance = Random.Range(0, 100); // if current tile is "empty" and if percent chance of placement is fulfilled if (t.type == TileObject.TileType.TRAVERSABLE && placeChance < chanceOfResourceSpawn) { int coinFlip = Random.Range(0, 2); GameObject resource; // Flip a coin; either spawn a fluff or plastic resource if (coinFlip % 2 == 0 && fluffs.Count < maxFluff) { resource = Instantiate( fluff[Random.Range(0, 4)], new Vector3(t.location.x, 0.3f, t.location.y), Quaternion.identity); fluffs.Add(resource); // Set as child of resourceFondler resource.transform.parent = resourceFondler.transform; t.type = TileObject.TileType.RESOURCE; } else if (coinFlip % 2 == 1 && plastics.Count < maxPlastic) { resource = Instantiate( plastic[Random.Range(0, 4)], new Vector3(t.location.x, 0.3f, t.location.y), Quaternion.identity); plastics.Add(resource); // Set as child of resourceFondler resource.transform.parent = resourceFondler.transform; t.type = TileObject.TileType.RESOURCE; } } // No need to keep looping if max count is reached, just return if (fluffs.Count == maxFluff && plastics.Count == maxPlastic) { //Debug.Log("Returning early: fluff count: " + fluffs.Count + " plastic count: " + plastics.Count); return; } } //gridLoopCount++; } //Debug.Log("Returning at very end: fluff count: " + fluffs.Count + " plastic count: " + plastics.Count); //Debug.Log("Grid Loop Count: " + gridLoopCount); }
/// <summary> /// Places obstacle objects on the board, /// such that one can always traverse between the two bases on opposite corners of the board. /// Find some balance of the two paramters such that the board designs are generally favorable. /// These can be changed to your preference - you do you! /// Please note that this runs in O( |pathLandmarks|^2 ), /// and the lag really gets noticable around pathLandmarks = 50. /// </summary> /// <param name="obstacleTemplate">GameObject which should be instantiated as objects</param> private GameGrid2DObject ProcedurallyPlaceObstacles(GameObject[] obstacleTemplate) { // Tear down any leftover tiles hanging out in obstacleFondler from previous runs obstacleFondler.transform.DetachChildren(); // First, generate new grid GameGrid2DObject tempGrid = new GameGrid2DObject(new Coord2DObject(X_MAX, Z_MAX), pathWidth, pathLandmarks, BASE_WIDTH); // Then, iterate through that grid. // Every time you see a Tile whose type is NON_TRAVERSABLE, // instantiate a Wall object at that location, // and add it to ObstacleFondler foreach (TileObject t in tempGrid) { // Skip empty or traversable tiles if (t.type != TileObject.TileType.NON_TRAVERSABLE) { continue; } GameObject tempObstacle; int rotationChance = Random.Range(0, 3); // Create new obstacle and rotate randomly by either 0/90/180/270 degree angles on the y-axis switch (rotationChance) { case 0: tempObstacle = Instantiate( obstacleTemplate[Random.Range(0, obstacleTemplate.Length)], // use random template new Vector3(t.location.x, 0.5f, t.location.y), Quaternion.Euler(0, 0, 0)); // Set as child of obstacleFondler tempObstacle.transform.parent = obstacleFondler.transform; explodeBoard.AddPiece(tempObstacle); break; case 1: tempObstacle = Instantiate( obstacleTemplate[Random.Range(0, obstacleTemplate.Length)], // use random template new Vector3(t.location.x, 0.5f, t.location.y), Quaternion.Euler(0, 90, 0)); // Set as child of obstacleFondler tempObstacle.transform.parent = obstacleFondler.transform; explodeBoard.AddPiece(tempObstacle); break; case 2: tempObstacle = Instantiate( obstacleTemplate[Random.Range(0, obstacleTemplate.Length)], // use random template new Vector3(t.location.x, 0.5f, t.location.y), Quaternion.Euler(0, 180, 0)); // Set as child of obstacleFondler tempObstacle.transform.parent = obstacleFondler.transform; explodeBoard.AddPiece(tempObstacle); break; case 3: tempObstacle = Instantiate( obstacleTemplate[Random.Range(0, obstacleTemplate.Length)], // use random template new Vector3(t.location.x, 0.5f, t.location.y), Quaternion.Euler(0, 270, 0)); // Set as child of obstacleFondler tempObstacle.transform.parent = obstacleFondler.transform; explodeBoard.AddPiece(tempObstacle); break; default: Debug.LogError("rotationChance: " + rotationChance); break; } } return(tempGrid); }