//get a direct distance, regardless of the walkable state public int GetDistance(Tile tile1, Tile tile2) { if (GridManager.GetTileType() == _TileType.Hex) { float x = Mathf.Abs(tile1.x - tile2.x); float y = Mathf.Abs(tile1.y - tile2.y); float z = Mathf.Abs(tile1.z - tile2.z); return((int)((x + y + z) / 2)); } else { float tileSize = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio(); Vector3 pos1 = tile1.GetPos(); Vector3 pos2 = tile2.GetPos(); int dx = (int)Mathf.Round(Mathf.Abs(pos1.x - pos2.x) / tileSize); int dz = (int)Mathf.Round(Mathf.Abs(pos1.z - pos2.z) / tileSize); if (GridManager.EnableDiagonalNeighbour()) { int min = Mathf.Min(dx, dz); int max = Mathf.Max(dx, dz); return(min + (max - min)); } return(dx + dz); } }
public static bool HasObstacle(Tile tile1, Tile tile2) { Vector3 pos1 = tile1.GetPos(); Vector3 pos2 = tile2.GetPos(); float dist = Vector3.Distance(pos2, pos1); Vector3 dir = (pos2 - pos1).normalized; Vector3 dirO = new Vector3(-dir.z, 0, dir.x).normalized; float posOffset = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * 0.4f; LayerMask mask = 1 << TBTK.GetLayerObstacleFullCover() | 1 << TBTK.GetLayerObstacleHalfCover(); if (Physics.Raycast(pos1, dir, dist, mask)) { return(true); } if (Physics.Raycast(pos1 + dirO * posOffset, dir, dist, mask)) { return(true); } if (Physics.Raycast(pos1 - dirO * posOffset, dir, dist, mask)) { return(true); } return(false); }
public void SetFogOfWarObj(Transform fogObjT) { fogOfWarObj = fogObjT.gameObject; fogOfWarObj.transform.position = transform.position; fogOfWarObj.transform.parent = transform.parent; fogOfWarObj.transform.localScale *= GridManager.GetGridToTileSizeRatio(); //fogOfWarObj.SetActive(!visible); }
//used in edit mode only public void AddWall(float angle, Tile neighbour, int wallType = 0) { if (neighbour == null) { return; } if (angle > 360) { angle -= 360; } if (IsWalled(angle)) { return; } float gridSize = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio(); if (type == _TileType.Square) { gridSize *= 2; } #if UNITY_EDITOR Transform wallT = (Transform)PrefabUtility.InstantiatePrefab(GridManager.GetWallObstacleT(wallType)); Undo.RecordObject(this, "Tile"); Undo.RecordObject(neighbour, "NeighbourTile"); Undo.RegisterCreatedObjectUndo(wallT.gameObject, "Wall"); #else Transform wallT = (Transform)Instantiate(GridManager.GetWallObstacleT(wallType)); #endif float wallTAngle = angle + 90; if (type == _TileType.Square) { wallTAngle = 360 - (angle - 90); } else if (type == _TileType.Hex) { wallTAngle = 360 - (angle - 90); } wallT.rotation = Quaternion.Euler(0, wallTAngle, 0); wallT.position = (GetPos() + neighbour.GetPos()) / 2; wallT.localScale *= gridSize; wallT.parent = transform; wallList.Add(new Wall(angle, wallT)); if ((angle += 180) >= 360) { angle -= 360; } neighbour.wallList.Add(new Wall(angle, wallT)); }
public static void InitCoverForTile(Tile tile) { List <Tile> neighbourList = tile.GetNeighbourList(); List <Cover> coverList = new List <Cover>(); for (int i = 0; i < tile.GetNeighbourList().Count; i++) { Vector3 dir = (neighbourList[i].GetPos() - tile.GetPos()).normalized; float dist = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * .75f; LayerMask mask = 1 << TBTK.GetLayerObstacleFullCover() | 1 << TBTK.GetLayerObstacleHalfCover(); RaycastHit hit; if (Physics.Raycast(tile.GetPos(), dir, out hit, dist, mask)) { Cover cover = new Cover(); cover.angle = Mathf.Round(Utilities.Vector2ToAngle(new Vector2(dir.x, dir.z))); if (GridManager.GetTileType() == _TileType.Square) //when diagonal neighbour is enabled, avoid adding cover to diagonal neighbour { if (cover.angle % 90 != 0) { continue; } } int layer = hit.transform.gameObject.layer; if (layer == TBTK.GetLayerObstacleFullCover()) { cover.type = _CoverType.Full; Debug.DrawLine(tile.GetPos(), tile.GetPos() + dir * dist, Color.red, 2); } else if (layer == TBTK.GetLayerObstacleHalfCover()) { cover.type = _CoverType.Half; Debug.DrawLine(tile.GetPos(), tile.GetPos() + dir * dist, Color.white, 2); } if (GridManager.GetTileType() == _TileType.Square) { cover.overlayPos = tile.GetPos() + dir * dist * 0.4f; } else if (GridManager.GetTileType() == _TileType.Hex) { cover.overlayPos = tile.GetPos() + dir * dist * 0.35f; } float angleY = cover.angle + 90; if (cover.angle == 30) { angleY = cover.angle + 30; } else if (cover.angle == 150) { angleY = cover.angle - 30; } else if (cover.angle == 210) { angleY = cover.angle + 30; } else if (cover.angle == 330) { angleY = cover.angle - 30; } cover.overlayRot = Quaternion.Euler(0, angleY, 0); coverList.Add(cover); } } tile.coverList = coverList; }
//search for a path, through walkable tile only //for normal movement, return the path in a list of hexTile public static List <Tile> SearchWalkableTile(Tile originTile, Tile destTile) { List <Tile> closeList = new List <Tile>(); List <Tile> openList = new List <Tile>(); Tile currentTile = originTile; float currentLowestF = Mathf.Infinity; int id = 0; int i = 0; while (true) { //if we have reach the destination if (currentTile == destTile) { break; } //move currentNode to closeList; closeList.Add(currentTile); currentTile.aStar.listState = TileAStar._AStarListState.Close; //loop through the neighbour of current loop, calculate score and stuff currentTile.aStar.ProcessWalkableNeighbour(destTile); //put all neighbour in openlist foreach (Tile neighbour in currentTile.aStar.GetNeighbourList(true)) { if (neighbour.aStar.listState == TileAStar._AStarListState.Unassigned || neighbour == destTile) { //~ //set the node state to open neighbour.aStar.listState = TileAStar._AStarListState.Open; openList.Add(neighbour); } } //clear the current node, before getting a new one, so we know if there isnt any suitable next node currentTile = null; currentLowestF = Mathf.Infinity; id = 0; for (i = 0; i < openList.Count; i++) { if (openList[i].aStar.scoreF < currentLowestF) { currentLowestF = openList[i].aStar.scoreF; currentTile = openList[i]; id = i; } } //if there's no node left in openlist, path doesnt exist if (currentTile == null) { break; } openList.RemoveAt(id); } if (currentTile == null) { float tileSize = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio(); currentLowestF = Mathf.Infinity; for (i = 0; i < closeList.Count; i++) { float dist = Vector3.Distance(destTile.GetPos(), closeList[i].GetPos()); if (dist < currentLowestF) { currentLowestF = dist; currentTile = closeList[i]; if (dist < tileSize * 1.5f) { break; } } } } List <Tile> path = new List <Tile>(); while (currentTile != null) { if (currentTile == originTile || currentTile == currentTile.aStar.parent) { break; } path.Add(currentTile); currentTile = currentTile.aStar.parent; } path = InvertTileArray(path); ResetGraph(destTile, openList, closeList); return(path); }
public static bool InLOS(Tile tile1, Tile tile2, float peekFactor, bool debugging = false) { Vector3 pos1 = tile1.GetPos(); Vector3 pos2 = tile2.GetPos(); if (peekFactor < 0) { peekFactor = GameControl.GetPeekFactor(); } float dist = Vector3.Distance(pos2, pos1); Vector3 dir = (pos2 - pos1).normalized; Vector3 dirO = new Vector3(-dir.z, 0, dir.x).normalized; float posOffset = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * peekFactor; LayerMask mask = 1 << TBTK.GetLayerObstacleFullCover(); // | 1<<LayerManager.GetLayerObstacleHalfCover(); bool flag = false; if (!LOSRaycast(pos1, dir, dist, mask, debugging)) { if (debugging) { flag = true; } else { return(true); } } if (posOffset == 0) { return(flag); } if (!LOSRaycast(pos1 + dirO * posOffset, dir, dist, mask, debugging)) { if (debugging) { flag = true; } else { return(true); } } if (!LOSRaycast(pos1 - dirO * posOffset, dir, dist, mask, debugging)) { if (debugging) { flag = true; } else { return(true); } } return(flag); }
public void AddObstacle(int obsType, float gridSize) { if (obstacleT != null) { if (obstacleT.gameObject.layer == TBTK.GetLayerObstacleHalfCover() && obsType == 1) { return; } if (obstacleT.gameObject.layer == TBTK.GetLayerObstacleFullCover() && obsType == 2) { return; } #if UNITY_EDITOR Undo.DestroyObjectImmediate(obstacleT.gameObject); #endif } if (wallList.Count > 0) { if (!Application.isPlaying) { Grid grid = GridManager.GetInstance().GetGrid(); while (wallList.Count > 0) { RemoveWall(wallList[0].angle, grid.GetNeighbourInDir(this, wallList[0].angle)); } } else { while (wallList.Count > 0) { RemoveWall(wallList[0].angle, GetNeighbourFromAngle(wallList[0].angle)); } } } //float gridSize=GridManager.GetTileSize(); #if UNITY_EDITOR Transform obsT = (Transform)PrefabUtility.InstantiatePrefab(GridManager.GetObstacleT(obsType)); Undo.RecordObject(this, "Tile"); Undo.RecordObject(GetComponent <Renderer>(), "TileRenderer"); Undo.RegisterCreatedObjectUndo(obsT.gameObject, "Obstacle"); #else Transform obsT = (Transform)Instantiate(GridManager.GetObstacleT(obsType)); #endif //~ float offsetY=0; //~ if(type==_TileType.Square){ //~ if(obsType==1)offsetY=obsT.localScale.z*gridSize/4; //~ if(obsType==2)offsetY=obsT.localScale.z*gridSize/2; //~ } //~ else if(type==_TileType.Hex) offsetY=obsT.localScale.z*gridSize/4; obsT.position = GetPos(); //+new Vector3(0, offsetY, 0); obsT.localScale *= gridSize * GridManager.GetGridToTileSizeRatio(); obsT.parent = transform; obstacleT = obsT; walkable = false; GetComponent <Renderer>().enabled = false; //SetState(_TileState.Default); }