Example #1
0
 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);
 }
Example #2
0
    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));
    }
Example #4
0
    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());
                }
            }
        }
Example #7
0
    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);
    }
Example #8
0
        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);
    }