public void DoStuff() { guo = new GraphUpdateObject(Fsm.GetOwnerDefaultTarget(target).collider.bounds); startNode = AstarPath.active.GetNearest(Start.Value).node; endNode = AstarPath.active.GetNearest(End.Value).node; PathIsPossible.Value = GraphUpdateUtilities.UpdateGraphsNoBlock(guo, startNode, endNode, true); }
private GameObject CheckValidTower(GameObject tower) { // check if the list is empty (no spawnpoint nodes) if (WaveManager.Instance.SpawnLocations != null && _destination != null) { List <GraphNode> g = new List <GraphNode>(); // gets the bounding volume of the towers renderer to make rough approximations about the tower's location var towerBox = new GraphUpdateObject(tower.GetComponent <BoxCollider2D>().bounds); // making the destination node var goalNode = AstarPath.active.GetNearest(_destination.transform.position).node; g.Add(goalNode); // Making spawnpoints nodes and check them to see if there's a path available foreach (GameObject s in WaveManager.Instance.SpawnLocations) { var spawnPointNode = AstarPath.active.GetNearest(s.transform.position).node; g.Add(spawnPointNode); } if (!GraphUpdateUtilities.UpdateGraphsNoBlock(towerBox, g, false)) { Destroy(tower); return(null); } } else { Debug.Log("NO SPAWNS"); } return(tower); }
/// <summary> /// Check whether the passed Tower will block the path between spawn and target tiles for the enemies. /// Uses Pathfinding.GraphUpdateUtilities.UpdateGraphsNoBlock(...) to do so, which first updates the graph and then checks if all nodes are still reachable from each other. /// If the path is blocked, the effect by the new tower on the graph is reverted. /// https://arongranberg.com/astar/docs/graphupdates.html#blocking for more information. /// </summary> /// <param name="newTower">New tower, player wants to place.</param> /// <returns>True if path would be blocked by the new tower, false otherwise.</returns> public static bool IsGraphNotBlocked(GameObject newTower) { var guo = new GraphUpdateObject(newTower.GetComponent <BoxCollider2D>().bounds); var spawnNode = AstarPath.active.GetNearest(LevelManager.TileDict[new Point(0, 0)].transform.position).node; var targetNode = AstarPath.active.GetNearest(randomTargetTile.transform.position).node; return(GraphUpdateUtilities.UpdateGraphsNoBlock(guo, spawnNode, targetNode, false)); }
public bool CanPlaceObject(GameObject gameObject) { var guo = new GraphUpdateObject(gameObject.GetComponentInChildren <Collider>().bounds); var start = AstarPath.active.GetNearest(GameObject.FindWithTag("SpawnStart").transform.position).node; var end = AstarPath.active.GetNearest(GameObject.FindWithTag("SpawnEnd").transform.position).node; return(GraphUpdateUtilities.UpdateGraphsNoBlock(guo, start, end, false)); }
/// <summary> /// Возвращает ближайшие координаты цели к искателю /// </summary> public static TargetPositionPair GetNearestTargetPositionToSeeker(Vector3 seekerPos, Transform target, out bool isPathPossible) { isPathPossible = false; TargetPositionPair nearetTargetPositionPair = default(TargetPositionPair); float halfNodeSize = GameManager.NodeSize * 0.5f; Node seekerNode = AstarPath.active.GetNearest(seekerPos); NodeAndDistance[] nodeAndDistanceArray = null; Vector3 nodePos; if (target.IsUnit()) { //так как юниты пока-что небольшие(менее 1 ноды), то сетка не используется Vector3 targetPos = target.position; Node nearestNode = AstarPath.active.GetNearest(targetPos, NNConstraint.Default); if (nearestNode != null) { FixBugWith_IsPathPossible(ref seekerNode, seekerPos); if (GraphUpdateUtilities.IsPathPossible(seekerNode, nearestNode)) { isPathPossible = true; nearetTargetPositionPair.FollowPosition = targetPos; nearetTargetPositionPair.NearestBoundaryNodePosition = targetPos; } } } else //если цель - строение { Node[] nodes = target.GetComponent <BuildingGrid>().GetBoundaryNodesClone(); SortNodesByDistance(nodes, out nodeAndDistanceArray, seekerPos); //Поиск ближайшей ноды, до которой существует путь. for (int i = 0; i < nodeAndDistanceArray.Length; i++) { nodePos = nodeAndDistanceArray[i].Node.position.ToVector3(); Vector3 dir = (seekerPos - nodePos).normalized * halfNodeSize;//направление и половина расстояния до граничной ноды Node externalBoundaryNode = AstarPath.active.GetNearest(nodePos + dir, NNConstraint.Default); if (externalBoundaryNode != null) { FixBugWith_IsPathPossible(ref seekerNode, seekerPos); if (GraphUpdateUtilities.IsPathPossible(seekerNode, externalBoundaryNode)) { isPathPossible = true; nearetTargetPositionPair.FollowPosition = nodePos + dir; nearetTargetPositionPair.NearestBoundaryNodePosition = nodePos; break;//выход из цикла, т.к. путь к ноде существует, а ноды отсортированы в порядке близости к цели и поиск пути до более отдаленных нод бессмысленен. } } } } return(nearetTargetPositionPair); }
IEnumerator PositionBlocksPath() { yield return(null); Physics.SyncTransforms(); var guo = new GraphUpdateObject(Bounds); foreach (var path in _paths) { if (!GraphUpdateUtilities.UpdateGraphsNoBlock(guo, path.PathAsAStarNodes, true)) { _isValid = false; _constructionTiles.ForEach(tile => tile.SetInvalid()); } } }
public bool validatePlacement(Vector3 iPosition) { //SpriteRenderer sprite = PlacementPrototype.GetComponent<SpriteRenderer>(); PathingChecker.SetActive(true); PathingChecker.transform.position = new Vector3(iPosition.x, iPosition.y, iPosition.z); // Check all Unit positions for collision. var guo = new GraphUpdateObject(PathingChecker.GetComponent <Collider>().bounds); foreach (Unit unit in EntityManager.GetTowers()) { Bounds bounds = unit.gameObject.GetComponent <Collider>().bounds; if (PathingChecker.GetComponent <Collider>().bounds.Intersects(bounds)) { //sprite.material.SetColor("_Color", new Color(1, 0, 0, 0.5f)); PathingChecker.SetActive(false); return(false); } } // Make sure all runners can get to the goal. List <GraphNode> nodes = new List <GraphNode>(); nodes.Add(_spawnPoint); nodes.Add(_goalPoint); foreach (Runner runner in EntityManager.GetRunners()) { nodes.Add(AstarPath.active.GetNearest(runner.transform.position).node); } if (!GraphUpdateUtilities.UpdateGraphsNoBlock(guo, nodes, true)) { //sprite.material.SetColor("_Color", new Color(1, 1, 0, 0.5f)); PathingChecker.SetActive(false); return(false); } //sprite.material.SetColor("_Color", new Color(0, 1, 0, 0.5f)); PathingChecker.SetActive(false); return(true); }
public bool CheckBlockPath(Transform placeHolder) { if (placeHolder == null) { return(false); } var guo = new GraphUpdateObject(placeHolder.GetComponent <BoxCollider2D>().bounds); //List<GraphNode> nodeList = new List<GraphNode>(); for (int i = 0; i < roads.Length; i++) { if (!GraphUpdateUtilities.UpdateGraphsNoBlock(guo, AstarPath.active.GetNearest(roads[i].transform.GetChild(0).position).node, AstarPath.active.GetNearest(roads[i].transform.GetChild(1).position).node, false)) { return(false); } } return(true); }
/* Проверка (GraphUpdateUtilities.IsPathPossible(seekerNode, externalBoundaryNode)) - не совсем правильна(см. реализацию IsPathPossible функции)- вместо этого правильней было бы юзать AstarPath.StartPath(); * К тому же из-за IsPathPossible() есть баг - юнит не может найти цель, если попадает в непроходимую ноду. *В дальнейшем желательно переделать эту функции так, чтобы возвращала сразу и цель и ближайший путь, если они существуют. *Также при поиске ближайшей ноды правильней было бы проверять длину путей до каждой ноды и выбрать ближний путь, но это довольно затратно: * http://arongranberg.com/astar/docs/_multi_target_free_8cs-example.php * http://www.arongranberg.com/astar/docs/_multi_target_path_example_8cs-example.php */ /// <summary> /// [Для передвижных юнитов] Поиск ближашей цели и ближайшей ноды цели к юниту; одновременно проверяется существование пути. /// </summary> public static Transform FindNearestTarget(Vector3 seekerPos, float searchRadius, LayerMask targetLayerMask, out TargetPositionPair targetPositionPair) { Collider[] targets = Physics.OverlapSphere(seekerPos, searchRadius, targetLayerMask); TargetPositionPair nearetTargetPositionPair = default(TargetPositionPair); Transform nearestTarget = null; if (targets.Length != 0) { float halfNodeSize = GameManager.NodeSize * 0.5f; Node seekerNode = AstarPath.active.GetNearest(seekerPos); float minDistSqr = float.MaxValue; //инициализация переменной для проверки дистанции до цели NodeAndDistance[] nodeAndDistanceArray = null; Vector3 nodePos; foreach (Collider coll in targets) { if (coll.IsUnit()) { //так как юниты пока-что небольшие(менее 1 ноды), то сетка не используется Vector3 targetPos = coll.transform.position; float distSqr = (targetPos - seekerPos).sqrMagnitude;//Vector3.Distance(seekerPos, targetPos); if (distSqr < minDistSqr) { Node nearestNode = AstarPath.active.GetNearest(targetPos, NNConstraint.Default); if (nearestNode != null) { //исправление бага, связанного c IsPathPossible - если юнит вдруг находится в непроходимой точке и не движется. FixBugWith_IsPathPossible(ref seekerNode, seekerPos); if (GraphUpdateUtilities.IsPathPossible(seekerNode, nearestNode)) { minDistSqr = distSqr; nearestTarget = coll.transform; nearetTargetPositionPair.FollowPosition = targetPos; nearetTargetPositionPair.NearestBoundaryNodePosition = targetPos; } } } } else //если цель - строение { Node[] nodes = coll.GetComponent <BuildingGrid>().GetBoundaryNodesClone(); SortNodesByDistance(nodes, out nodeAndDistanceArray, seekerPos); //Поиск ближайшей ноды, до которой существует путь. for (int i = 0; i < nodeAndDistanceArray.Length; i++) { if (nodeAndDistanceArray[i].DistanceSqr < minDistSqr) { nodePos = nodeAndDistanceArray[i].Node.position.ToVector3(); Vector3 dir = (seekerPos - nodePos).normalized * halfNodeSize;//направление и половина расстояния до граничной ноды Node externalBoundaryNode = AstarPath.active.GetNearest(nodePos + dir, NNConstraint.Default); if (externalBoundaryNode != null) { //исправление бага, связанного c IsPathPossible - если юнит вдруг находится в непроходимой точке и не движется. FixBugWith_IsPathPossible(ref seekerNode, seekerPos); if (GraphUpdateUtilities.IsPathPossible(seekerNode, externalBoundaryNode)) { minDistSqr = nodeAndDistanceArray[i].DistanceSqr; nearestTarget = coll.transform; nearetTargetPositionPair.FollowPosition = nodePos + dir; nearetTargetPositionPair.NearestBoundaryNodePosition = nodePos; break;//выход из цикла, т.к. путь к ноде существует, а ноды отсортированы в порядке близости к цели и поиск пути до более отдаленных нод бессмысленен. } } } } } } } targetPositionPair = nearetTargetPositionPair; return(nearestTarget); }