/// <summary>
    /// Internal function that implements the path-finding algorithm.
    /// </summary>
    /// <param name="grid">Grid to search.</param>
    /// <param name="startPos">Starting position.</param>
    /// <param name="targetPos">Ending position.</param>
    /// <param name="distance">The type of distance, Euclidean or Manhattan.</param>
    /// <param name="ignorePrices">If true, will ignore tile price (how much it "cost" to walk on).</param>
    /// <returns>List of grid nodes that represent the path to walk.</returns>
    private static List <Node> _ImpFindPath(PathfindGrid grid, Point startPos, Point targetPos, DistanceType distance = DistanceType.Euclidean, bool ignorePrices = false)
    {
        Node startNode  = grid.nodes[startPos.x, startPos.y];
        Node targetNode = grid.nodes[targetPos.x, targetPos.y];

        List <Node>    openSet   = new List <Node>();
        HashSet <Node> closedSet = new HashSet <Node>();

        openSet.Add(startNode);

        while (openSet.Count > 0)
        {
            Node currentNode = openSet[0];
            for (int i = 1; i < openSet.Count; i++)
            {
                if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)
                {
                    currentNode = openSet[i];
                }
            }

            openSet.Remove(currentNode);
            closedSet.Add(currentNode);

            if (currentNode == targetNode)
            {
                return(RetracePath(grid, startNode, targetNode));
            }

            foreach (Node neighbour in grid.GetNeighbours(currentNode, distance))
            {
                if (!neighbour.walkable || closedSet.Contains(neighbour))
                {
                    continue;
                }

                int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) * (ignorePrices ? 1 : (int)(10.0f * neighbour.price));
                if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                {
                    neighbour.gCost  = newMovementCostToNeighbour;
                    neighbour.hCost  = GetDistance(neighbour, targetNode);
                    neighbour.parent = currentNode;

                    if (!openSet.Contains(neighbour))
                    {
                        openSet.Add(neighbour);
                    }
                }
            }
        }

        return(null);
    }
    /// <summary>
    /// Retrace path between two points.
    /// </summary>
    /// <param name="grid">Grid to work on.</param>
    /// <param name="startNode">Starting node.</param>
    /// <param name="endNode">Ending (target) node.</param>
    /// <returns>Retraced path between nodes.</returns>
    private static List <Node> RetracePath(PathfindGrid grid, Node startNode, Node endNode)
    {
        List <Node> path        = new List <Node>();
        Node        currentNode = endNode;

        while (currentNode != startNode)
        {
            path.Add(currentNode);
            currentNode = currentNode.parent;
        }
        path.Reverse();
        return(path);
    }
    private void Init()
    {
        if (_animalPrefabsList.Length != _initialNumberOfAnimals.Length)
        {
            Debug.LogError("Lists must be the same size");
        }

        _grid = FindObjectOfType <PathfindGrid>();
        if (_grid == null)
        {
            Debug.LogError("Scene needs a PathfindGrid object");
        }
    }
    private void Awake()
    {
        _grid = FindObjectOfType <PathfindGrid>();
        if (_grid == null)
        {
            Debug.LogError("scene needs a pathfindgrid object");
        }

        _mapGen = FindObjectOfType <MapGenerator>();
        if (_grid == null)
        {
            Debug.LogError("scene needs a Map generator object");
        }
    }
    /// <summary>
    /// Find a path between two points.
    /// </summary>
    /// <param name="grid">Grid to search.</param>
    /// <param name="startPos">Starting position.</param>
    /// <param name="targetPos">Ending position.</param>
    /// <param name="distance">The type of distance, Euclidean or Manhattan.</param>
    /// <param name="ignorePrices">If true, will ignore tile price (how much it "cost" to walk on).</param>
    /// <returns>List of points that represent the path to walk.</returns>
    public static List <Point> FindPath(PathfindGrid grid, Point startPos, Point targetPos, DistanceType distance = DistanceType.Euclidean, bool ignorePrices = false)
    {
        // find path
        List <Node> nodes_path = _ImpFindPath(grid, startPos, targetPos, distance, ignorePrices);

        // convert to a list of points and return
        List <Point> ret = new List <Point>();

        if (nodes_path != null)
        {
            foreach (Node node in nodes_path)
            {
                ret.Add(new Point(node.gridX, node.gridY));
            }
        }
        return(ret);
    }
    private void Init()
    {
        _grid = FindObjectOfType <PathfindGrid>();
        if (_grid == null)
        {
            Debug.LogError("Scene needs a PathfindGrid object");
        }

        _statsManager = FindObjectOfType <StatisticsManager>();
        if (_statsManager == null)
        {
            Debug.LogError("Scene needs a StatisticsManager object");
        }

        Coroutine growingPlants = StartCoroutine(ChanceToGrowPlant());

        _runningCoroutines.Add(growingPlants);
    }
    // Use this for initialization
    void Start()
    {
        InvokeRepeating("CalculatePath", 0f, 0.1f);
        InvokeRepeating("TryAttackPlayer", 0f, 0.5f);

        targetPlayer = GameObject.FindGameObjectWithTag("Player");
        walls        = GameObject.FindGameObjectWithTag("WallsTilemap").GetComponent <Tilemap>();
        gameLogic    = GameObject.FindObjectOfType <GameLogic> ();
        animator     = GetComponent <Animator> ();

        BoundsInt bounds = walls.cellBounds;

        Tile[] allTiles = walls.GetTiles <Tile> ();
        bool[,] wallsArray = new bool[bounds.size.x, bounds.size.y];

        for (int x = 0; x < bounds.size.x; x++)
        {
            for (int y = 0; y < bounds.size.y; y++)
            {
                Tile tile = allTiles [x + y * bounds.size.x];

                if (tile != null)
                {
                    //Debug.Log("x:" + x + " y:" + y + " tile:" + tile.name + " ct:" + tile.colliderType);
                    if (tile.colliderType == Tile.ColliderType.None)
                    {
                        wallsArray[x, y] = true;
                    }
                    else if (tile.colliderType == Tile.ColliderType.Sprite)
                    {
                        wallsArray[x, y] = false;
                    }
                }
                else
                {
                    //Debug.Log("x:" + x + " y:" + y + " tile: (null)");
                }
            }
        }

        pathfindingGrid = new PathfindGrid(wallsArray);
    }
Exemple #8
0
 private void Awake()
 {
     _grid           = GetComponent <PathfindGrid>();
     _requestManager = GetComponent <PathRequestManager>();
 }