void CreateGrid() { grid = new Tile_Online[gridX, gridY]; //"grid" is a new array of size gridX by gridY //this will store the nodes and test for "walkability" Vector3 bLCorner = transform.position - Vector3.right * gridSize.x / 2 - Vector3.forward * gridSize.y / 2; //The above code gets us the bottom-left corner of our tile/node //this is how we get the correct node (this is a VERY taxing alg.) for (int x = 0; x < gridX; x++) { for (int y = 0; y < gridY; y++) { Vector3 worldPoint = bLCorner + Vector3.right * (x * tileDiameter + tileRadius) + Vector3.forward * (y * tileDiameter + tileRadius); //"worldPoint" is the space a node will occupy relative to the world bool walkable = !(Physics.CheckSphere(worldPoint, tileRadius, noWalkMask)); //checks to see if the area nearby is walkable /*if(y >= 1 && x >= 1) * { * grid[x, y] = new Tile(walkable, worldPoint, x, y, grid[x-1, y-1]); * }else if(x )*/ //below code creates a new node/tile object with values grid[x, y] = new Tile_Online(walkable, worldPoint, x, y, null); //"walkable" and "worldPoint" are inserted into the constructor found in "Tile" } } }
//the following method comes from the 2nd site //the following method is used to ... public List <Tile_Online> GetNeighbors(Tile_Online tile) { List <Tile_Online> neighbors = new List <Tile_Online>(); //makes a list of nodes/the neighboring tiles //the code MUST be optimized //we are searching in a 3x3 block around a tile for smaller F(x) and H(x) values for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { //if x and y are 0, we're in the center of the tile/the current tile and not a neighbor if (x == 0 && y == 0) { continue; //this skips the iteration } //checkX & checkY are the node's x-y values + the value of x and y int checkX = tile.gridx + x; int checkY = tile.gridy + y; //if the checks are on the grid, add the tile to the list "neighbors" if ((checkX == 0 && checkX < gridSize.x) && (checkY == 0 && checkY < gridSize.y)) { neighbors.Add(grid[checkX, checkY]); } } } return(neighbors); }
//"StepBack" retraces the path the player follows from the final node to the start node void StepBack(Tile_Online startTile, Tile_Online endTile) { List <Tile_Online> path = new List <Tile_Online>(); Tile_Online current = endTile; /* while the current tile is not the starting tile, add the current tile to the list * and set "current" value to its parent, tracing the path backwards and putting it * into the list */ while (current != startTile) { path.Add(current); Debug.Log(path); if (path.Contains(current)) { Debug.Log("insert successful"); } current = current.parent; } path.Reverse(); //reverses the list to get the correct order of the path to traverse/traversed grid.AStarPath = path; //creates a gizmo to show where the path exists starPath = path; }
public Tile_Online parent; //public parent Tile of the current tile //"parent" contains the previos Tile the player was on //constructor for the tile object/script //sets the values of the public variables above //3rd and 4th var and space are from the 2nd site public Tile_Online(bool walk, Vector3 pos, int grid_xVal, int grid_yVal, Tile_Online _parent) { walkable = walk; worldPos = pos; //from 2nd site gridx = grid_xVal; gridy = grid_yVal; parent = _parent; }
private void PlopTowersToMap() { foreach (float[] towerInTile in OpponentConfig.userMapConfig) { string towerPath = "Prefabs/towers_Online/tower_" + towerInTile[2] + "/Tower"; Tile_Online tile = Tiles[new Point((int)towerInTile[0], (int)towerInTile[1])]; GameObject towerPrefab = Resources.Load <GameObject>(towerPath); tile.PlaceTower(towerPrefab, 0, towerInTile); } }
private void PlaceTile(string tileType, int x, int y, Vector3 origin) { bool walkable; int tileIndex = int.Parse(tileType); Tile_Online newTile = Instantiate(tilePrefabs[tileIndex]).GetComponent <Tile_Online>(); if (tileIndex % 2 == 1) { walkable = true; } else { walkable = false; } newTile.Setup(new Point(x, y), new Vector3(origin.x + TileWidth * x, origin.y - TileHeight * y, 0), walkable, map); }
//method gets the distance b/w the start and end nodes int GetDist(Tile_Online startTile, Tile_Online endTile) { int xDist = Mathf.Abs(startTile.gridx - endTile.gridx); //absolute val. of x-distance int yDist = Mathf.Abs(startTile.gridy - endTile.gridy); //absolute val. of y-distance //this calculates the distance (x and y) b/w the end tile and the start tile /*if(xDist > yDist) * { * return 14 * yDist + 10 * (xDist - yDist); * } * else * { * return 14 * xDist + 10 * (yDist - xDist); * }*/ if (xDist > yDist) { return(14 * yDist + 10 * (xDist - yDist)); } return(14 * xDist + 10 * (yDist - xDist)); }
//finds the shortest path along a grid void FindPath(Vector3 startPos, Vector3 targetPos) { Tile_Online startPoint = grid.TilefromWorldPoint(startPos); //grid point/tile where the player starts moving from Tile_Online targetPoint = grid.TilefromWorldPoint(targetPos); //goal point List <Tile_Online> unCalcTiles = new List <Tile_Online>(); //list of tiles with F = G + H values that have not been calculated HashSet <Tile_Online> calcTiles = new HashSet <Tile_Online>(); //list of tiles that have been traversed or have calculated F = G + H values unCalcTiles.Add(startPoint); //first tile to be calculated //Debug.Log("Open Nodes " + unCalcTiles); //while the list of uncalculated tiles is not empty:... while (unCalcTiles.Count > 0) { //find the tile in "unCalcTiles" with the lowest F-cost Tile_Online current = unCalcTiles[0]; //traverses through the list "unCalcTiles" //need to change this so the alg. is efficient for (int i = 1; i < unCalcTiles.Count; i++) { /*if the current tile's F(x) val is less than the next * "unCalcTiles'" value; or the current tile's and "unCalcTiles[i]'s" * F(X) equal each other and "unCalcTiles[i]'s" H(x) is less than the * current tile's H(x), make current tile "unCalcTile" */ if (unCalcTiles[i].FCost() < current.FCost() || unCalcTiles[i].FCost() == current.FCost() && unCalcTiles[i].H < current.H) { Debug.Log("appear"); current = unCalcTiles[i]; } } unCalcTiles.Remove(current); //remove the selected tile/tile we chose to move across calcTiles.Add(current); //add the tile we are using to the calculated Tile hash set //if the current tile is the target, exit the loop if (current == targetPoint) { StepBack(startPoint, targetPoint); return; } //for each Tile object in "grid" (a tile list), check if the tile "neighbor" is walkable or not foreach (Tile_Online neighbor in grid.GetNeighbors(current)) { /* if the tile/current tile in the loop (not the current tile for the player) is not walkable * or already calculated, skip a run and move to the next part of the loop*/ if (!neighbor.walkable || calcTiles.Contains(neighbor)) { continue; } int moveCostNeigh = current.G + GetDist(current, neighbor); //the cost of moving from the current tile to the neighboring tile //this is the new/current G-cost from the neighbor/when when we move to the neighbor node /* if the calculated move cost is less than the current neighbor's g-cost or the neighbor has * not been traversed/has not had its values calculated yet, ... */ if (moveCostNeigh < neighbor.G || !unCalcTiles.Contains(neighbor)) { neighbor.G = moveCostNeigh; //new G-cost of the neighbor tile neighbor.H = GetDist(neighbor, targetPoint); //used to get the new H-cost of the neighbor tile neighbor.parent = current; Debug.Log("current node: " + current); Debug.Log("parent of neighbor: " + neighbor.parent); //the parent of the neighboring tile is the current node we're on //this is b/c we have not traversed/moved the player yet /* if we have not calculated the distances of the neighbor tile yet, calculate it and mark it has * having been calculated*/ if (!unCalcTiles.Contains(neighbor)) { unCalcTiles.Add(neighbor); } } } } }