public List<Vector3> FindPath(GridmapCell start, GridmapCell end, bool checkValidity) { if (start == null || end == null) return new List<Vector3>(); if ((start.treeID != end.treeID) && checkValidity) return new List<Vector3>(); return PathingHelper.FindPath(start, end, this, checkValidity); }
private void SetSelected(Gridmap map) { RaycastHit hitinfo; if (Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hitinfo)) { selected = map.GetCellFromPoint(hitinfo.point); if (selected.state != GridmapCell.CellState.Buildable) selected = null; } }
/// <summary> /// Instantiate a structure from the array of buildable ones at a given location for the player. /// </summary> /// <param name="sIndex">the index into this builder's array of buildable structures to specify which structure.</param> /// <param name="cell">which cell on the map the structure will be built on</param> /// TODO: IMPLEMENT MULTI-CELL FOOTPRINTS FOR STRUCTURES /// <returns>true if the structure was built succesfully, otherwise false.</returns> public bool BuildStructure(int sIndex, GridmapCell cell) { if (cell.state != GridmapCell.CellState.Buildable) return false; try { GameStructure structure = Instantiate(StructuresBuilt[sIndex], cell.center, Quaternion.identity) as GameStructure; structure.owner = gameObject.GetComponent<GameEntity>().owner; cell.state = GridmapCell.CellState.Occupied; return true; } catch (System.Exception) { return false; } }
/// <summary> /// Sets the position of the TileBound object. /// </summary> /// <param name="position">The position of the tile which the object will be centered around</param> /// <returns>True if the position was valid or false if it was not.</returns> public bool SetPosition(Vector3 position) { GridmapCell center = map.GetCellFromPoint(position); GridmapCell[] cells = new GridmapCell[footprintX * footprintZ]; for (int x = 0; x < footprintX; x++) { for (int z = 0; z < footprintZ; z++) { GridmapCell n = map[x + center.x, z + center.z]; if (n == null || n.state != GridmapCell.CellState.Buildable) return false; cells[(x * footprintZ) + z] = n; } } //TODO: Fix for 1-sized footprints //for (int x = -(footprintX / 2) + 1 - (footprintX % 2); x < footprintX / 2; x++) //{ // for (int z = -(footprintZ / 2) + 1 - (footprintZ % 2); z < footprintZ / 2; z++) // { // Debug.Log("x:" + x + "\tz:" + z); // // TODO: cache map[x,z] maybe // if (map[x, z] == null || map[x, z].state == GridmapCell.CellState.Occupied) // return false; // else // { // cells[(x * footprintZ) + z] = map[x, z]; // } // } //} occupiedTiles = new GridmapCell[footprintX * footprintZ]; cells.CopyTo(occupiedTiles, 0); for (int i = 0; i < footprintX * footprintZ; i++) occupiedTiles[i].state = GridmapCell.CellState.Occupied; return true; }
private bool CellIsSmooth(GridmapCell c, Terrain t) { // grab 4-corners + center heights float ch = t.SampleHeight(c.center); float tl = t.SampleHeight(c.center + new Vector3(-cellWidth / 2.0f, 0, cellDepth / 2.0f)); float tr = t.SampleHeight(c.center + new Vector3(cellWidth / 2.0f, 0, cellDepth / 2.0f)); float bl = t.SampleHeight(c.center + new Vector3(-cellWidth / 2.0f, 0, -cellDepth / 2.0f)); float br = t.SampleHeight(c.center + new Vector3(cellWidth / 2.0f, 0, -cellDepth / 2.0f)); // check if center diff is too big: if (Mathf.Abs(ch - tl) > cliffHeight || Mathf.Abs(ch - tr) > cliffHeight || Mathf.Abs(ch - bl) > cliffHeight || Mathf.Abs(ch - br) > cliffHeight) return false; // check if top-left diff is too big: if (Mathf.Abs(tl - tr) > cliffHeight || Mathf.Abs(tl - bl) > cliffHeight) return false; // check if bot-right diff is too big: if (Mathf.Abs(br - tr) > cliffHeight || Mathf.Abs(br - bl) > cliffHeight) return false; return true; }
public AStarRecord(GridmapCell c, AStarRecord p, float cost) { if (c == null) throw new UnityException("Cannot create an AStarRecord with a null node."); cell = c; parent = p; linkCost = cost; totalCost = (parent != null) ? parent.totalCost + linkCost : linkCost; estimatedFinalCost = totalCost + (finalTarget - cell.center).magnitude; }
private static bool PlaceInCorrectList(GridmapCell cell, AStarRecord parent, float cost) { if (cell == null) return false; if (!cell.Valid && checkValiditiy) return false; AStarRecord olinstance = openList.FirstOrDefault(r => r.cell.Equals(cell)); if (olinstance != null) // it's on the open list. { if (olinstance.totalCost > parent.totalCost + cost) // this new path is shorter olinstance.Reparent(parent, cost); return true; } AStarRecord clinstance = closedList.FirstOrDefault(r => r.cell.Equals(cell)); if (clinstance != null) // it's in the closed list { return true; } // add it to the open list openList.Add(new AStarRecord(cell, parent, cost)); return true; }
public static List<Vector3> FindPath(GridmapCell start, GridmapCell end, Gridmap map, bool check) { List<Vector3> path = new List<Vector3>(); if (start == null || end == null) return path; openList.Clear(); closedList.Clear(); checkValiditiy = check; AStarRecord.finalTarget = end.center; openList.Add(new AStarRecord(start, null, 0)); while (openList.Count > 0) { AStarRecord current = openList[0]; if (current.cell.Equals(end)) break; bool up_ok = PlaceInCorrectList(map[current.cell.x, current.cell.z + 1], current, 1.0f); bool left_ok = PlaceInCorrectList(map[current.cell.x - 1, current.cell.z], current, 1.0f); bool right_ok = PlaceInCorrectList(map[current.cell.x + 1, current.cell.z], current, 1.0f); bool down_ok = PlaceInCorrectList(map[current.cell.x, current.cell.z - 1], current, 1.0f); if (up_ok && left_ok) PlaceInCorrectList(map[current.cell.x - 1, current.cell.z + 1], current, 1.4f); if (up_ok && right_ok) PlaceInCorrectList(map[current.cell.x + 1, current.cell.z + 1], current, 1.4f); if (down_ok && left_ok) PlaceInCorrectList(map[current.cell.x - 1, current.cell.z - 1], current, 1.4f); if (down_ok && right_ok) PlaceInCorrectList(map[current.cell.x + 1, current.cell.z - 1], current, 1.4f); closedList.Add(current); openList.RemoveAt(0); // TODO: Don't sort, just cache the index of the lowest cost (n instead of nlogn) openList.Sort((l1, l2) => l1.estimatedFinalCost.CompareTo(l2.estimatedFinalCost)); } if (openList.Count == 0) return path; // no path found. AStarRecord r = openList[0]; do { path.Add(r.cell.center); r = r.parent; } while (r != null && !r.cell.Equals(start)); path.Reverse(); return path; }
private void GenerateGrid_Terrain() { countx = (int)(gameObject.collider.bounds.size.x / cellWidth); countz = (int)(gameObject.collider.bounds.size.z / cellDepth); Terrain terrain = gameObject.GetComponent<Terrain>() as Terrain; cells = new GridmapCell[countx * countz]; for (int x = 0; x < countx; x++) { for (int z = 0; z < countz; z++) { cells[(x * countz) + z] = new GridmapCell(); cells[(x * countz) + z].Initialize(new Vector3(x * cellWidth, 0, z * cellDepth) + halfCellSize + gameObject.transform.position, cellWidth, cellDepth); cells[(x * countz) + z].center.y = terrain.SampleHeight(cells[(x * countz) + z].center); cells[(x * countz) + z].SetSceneVerts(terrain); cells[(x * countz) + z].Valid = CellIsSmooth(cells[(x * countz) + z], terrain); cells[(x * countz) + z].state = cells[(x * countz) + z].Valid ? GridmapCell.CellState.Buildable : GridmapCell.CellState.Unbuildable; cells[(x * countz) + z].x = x; cells[(x * countz) + z].z = z; } } }
// Use this for initialization void Start() { Messenger<GameEntity>.RegisterListener("GameEntityPressed", x => { selected = null; }); Messenger<Gridmap>.RegisterListener("MapPressed", SetSelected); }