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); }
//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); } }
//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; }
IEnumerator ActionCamRoutine(Unit srcUnit, Vector3 tgtPos) { TurnControl.ActionCommenced(); actionCamInProgress = true; Vector3 rootPosOrigin = thisT.position; Quaternion rootRotOrigin = thisT.rotation; Vector3 posOrigin = camT.localPosition; float zoomOrigin = camT.localPosition.z; Vector3 centerPos = srcUnit.GetTargetT().position + (tgtPos - srcUnit.GetTargetT().position) * 0.35f; centerPos.y = thisT.position.y; Quaternion wantedRot = Quaternion.LookRotation(centerPos - srcUnit.GetTargetT().position); wantedRot *= Quaternion.Euler(10, 15, 0); wantedRot = Quaternion.Euler(wantedRot.eulerAngles.x, wantedRot.eulerAngles.y, 0); float dist = Vector3.Distance(centerPos, srcUnit.GetTargetT().position); float duration = 0; while (duration < 1) { thisT.rotation = Quaternion.Euler(thisT.rotation.eulerAngles.x, thisT.rotation.eulerAngles.y, 0); camT.localPosition = Vector3.Lerp(new Vector3(0, 0, zoomOrigin), new Vector3(0, 0, -dist - GridManager.GetTileSize() * 2), duration); thisT.position = Vector3.Lerp(rootPosOrigin, centerPos, duration); thisT.rotation = Quaternion.Lerp(rootRotOrigin, wantedRot, duration); duration += Time.deltaTime * 1f; yield return(null); } thisT.rotation = wantedRot; TurnControl.ActionCompleted(); yield return(null); while (!TurnControl.ClearToProceed()) { yield return(null); } TurnControl.ActionCommenced(); duration = 0; while (duration < 1) { thisT.rotation = Quaternion.Euler(thisT.rotation.eulerAngles.x, thisT.rotation.eulerAngles.y, 0); camT.localPosition = Vector3.Lerp(new Vector3(0, 0, -dist - GridManager.GetTileSize() * 2), new Vector3(0, 0, zoomOrigin), duration); thisT.position = Vector3.Lerp(centerPos, rootPosOrigin, duration); thisT.rotation = Quaternion.Lerp(wantedRot, rootRotOrigin, duration); duration += Time.deltaTime * 1f; yield return(null); } thisT.position = rootPosOrigin; thisT.rotation = rootRotOrigin; camT.localPosition = posOrigin; TurnControl.ActionCompleted(); actionCamInProgress = false; }
//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 void Init() { if (init) { return; } init = true; thisT = transform; Transform deploymentIndicator = null; Transform moveableIndicator = null; Transform hostileIndicator = null; Transform abRangeIndicator = null; Transform abTargetIndicator = null; if (GridManager.GetTileType() == _TileType.Hex) { deploymentIndicator = hexDeployment; moveableIndicator = hexMoveable; hostileIndicator = hexHostile; abRangeIndicator = hexAbRange; abTargetIndicator = hexAbTarget; cursorIndicatorF = (Transform)Instantiate(hexCursorF); cursorIndicatorH = (Transform)Instantiate(hexCursorH); selectIndicator = (Transform)Instantiate(hexSelected); } else if (GridManager.GetTileType() == _TileType.Square) { deploymentIndicator = sqDeployment; moveableIndicator = sqMoveable; hostileIndicator = sqHostile; abRangeIndicator = sqAbRange; abTargetIndicator = sqAbTarget; cursorIndicatorF = (Transform)Instantiate(sqCursorF); cursorIndicatorH = (Transform)Instantiate(sqCursorH); selectIndicator = (Transform)Instantiate(sqSelected); } cursorIndicatorF.parent = thisT; cursorIndicatorH.parent = thisT; selectIndicator.parent = thisT; for (int i = 0; i < 20; i++) { deploymentIndicatorList.Add((Transform)Instantiate(deploymentIndicator)); deploymentIndicatorList[i].gameObject.SetActive(false); deploymentIndicatorList[i].parent = thisT; } for (int i = 0; i < 20; i++) { moveableIndicatorList.Add((Transform)Instantiate(moveableIndicator)); moveableIndicatorList[i].gameObject.SetActive(false); moveableIndicatorList[i].parent = thisT; } for (int i = 0; i < 10; i++) { hostileIndicatorList.Add((Transform)Instantiate(hostileIndicator)); hostileIndicatorList[i].gameObject.SetActive(false); hostileIndicatorList[i].parent = thisT; } for (int i = 0; i < 20; i++) { abRangeIndicatorList.Add((Transform)Instantiate(abRangeIndicator)); abRangeIndicatorList[i].gameObject.SetActive(false); abRangeIndicatorList[i].parent = thisT; } for (int i = 0; i < 20; i++) { abTargetIndicatorList.Add((Transform)Instantiate(abTargetIndicator)); abTargetIndicatorList[i].gameObject.SetActive(false); abTargetIndicatorList[i].parent = thisT; } if (TurnControl.GetTurnMode() == _TurnMode.FactionPerTurn) { //create the moved indicator for (int i = 0; i < 10; i++) { movedIndicatorList.Add((Transform)Instantiate(movedIndicator)); movedIndicatorList[i].gameObject.SetActive(false); movedIndicatorList[i].parent = thisT; } } if (GameControl.EnableFogOfWar()) { Transform fogObj = null; if (GridManager.GetTileType() == _TileType.Hex) { fogObj = hexFogObj; } else if (GridManager.GetTileType() == _TileType.Square) { fogObj = sqFogObj; } List <Tile> tileList = GridManager.GetTileList(); for (int i = 0; i < tileList.Count; i++) { //if(!tileList[i].walkable) continue; tileList[i].SetFogOfWarObj((Transform)Instantiate(fogObj)); } } if (GameControl.EnableCover()) { float scaleOffset = GridManager.GetTileType() == _TileType.Hex ? 0.5f : 0.8f; float tileSize = GridManager.GetTileSize(); for (int i = 0; i < 5; i++) { coverOverlayHList.Add((Transform)Instantiate(coverOverlayH)); coverOverlayFList.Add((Transform)Instantiate(coverOverlayF)); coverOverlayHList[i].localScale *= tileSize * scaleOffset; coverOverlayHList[i].parent = thisT; coverOverlayHList[i].gameObject.SetActive(false); coverOverlayFList[i].localScale *= tileSize * scaleOffset; coverOverlayFList[i].parent = thisT; coverOverlayFList[i].gameObject.SetActive(false); } } }
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); }