public Vector2 position; // Position of the current node

    #endregion Fields

    #region Constructors

    // Default Constructor
    public EnemyNutrientNode()
    {
        this.fEstimatedCost = 0.0f;
        this.fTotalCost = 1.0f;
        this.bAccessible = false;
        this.parent = null;
    }
    public Vector2 position;                // Position of the current node
    #endregion

    // Default Constructor
    public EnemyNutrientNode()
    {
        this.fEstimatedCost = 0.0f;
        this.fTotalCost     = 1.0f;
        this.bAccessible    = false;
        this.parent         = null;
    }
    // Constructor
    public EnemyNutrientNode(Vector2 pos)
    {
        this.fEstimatedCost = 0.0f;
        this.fTotalCost = 1.0f;
        this.bAccessible = true;
        this.parent = null;

        this.position = pos;
    }
    // Constructor
    public EnemyNutrientNode(Vector2 pos)
    {
        this.fEstimatedCost = 0.0f;
        this.fTotalCost     = 1.0f;
        this.bAccessible    = true;
        this.parent         = null;

        this.position = pos;
    }
Example #5
0
    // Get the obstacles in the scene
    public void GetObstacles()
    {
        // Initialise the nodes
        nodes = new EnemyNutrientNode[nNumOfRows, nNumOfColumns];

        int index = 0;

        for (int i = 0; i < nNumOfRows; i++)
        {
            for (int j = 0; j < nNumOfColumns; j++)
            {
                Vector2           cellPos = GetNodeCenter(index);
                EnemyNutrientNode node    = new EnemyNutrientNode(cellPos);
                nodes[i, j] = node;

                index++;
            }
        }

        // Set the position for each obstacle
        if (obstacleList != null && obstacleList.Count > 0)
        {
            foreach (GameObject obstacle in obstacleList)
            {
                if (obstacle != null)
                {
                    if (IsInBounds(obstacle.transform.position))
                    {
                        int indexCell = GetGridIndex(obstacle.transform.position);
                        int column    = GetColumn(indexCell);
                        int row       = GetRow(indexCell);
                        int range     = (int)(obstacle.GetComponent <CircleCollider2D> ().bounds.size.x / fUniversalnodeSize);

                        // Assign unaccessible area
                        nodes[row, column].MarkAsUnaccessible();

                        /*
                         * for (int i = row - range; i < row + range; i++)
                         * {
                         *      for (int j = column - range; j < column + range; j++)
                         *      {
                         *              if (i >= 0 && i < nNumOfRows && j >= 0 && j < nNumOfColumns)
                         *              {
                         *                      if (nodes[i, j].bAccessible)
                         *                              nodes[i, j].MarkAsUnaccessible();
                         *              }
                         *      }
                         * }
                         */
                    }
                }
            }
        }
    }
Example #6
0
 // Check the neighbouring node. If it is accessible, add the neighbouring node to the neighbour list.
 void AssignNeighbour(int row, int column, ArrayList neighbors)
 {
     if (row >= 0 && column >= 0 && row < nNumOfRows && column < nNumOfColumns)
     {
         EnemyNutrientNode nodeToAdd = nodes[row, column];
         if (nodeToAdd.bAccessible)
         {
             neighbors.Add(nodeToAdd);
         }
     }
 }
Example #7
0
    // Get the real path by reversing the path found
    private static ArrayList CalculatePath(EnemyNutrientNode node)
    {
        ArrayList list = new ArrayList();

        while (node != null)
        {
            list.Add(node);
            node = node.parent;
        }
        list.Reverse();
        return(list);
    }
    void FindPath()
    {
        startPos = startObject.transform;
        endPos = goalObject.transform;

        // Initialize start and goal node
        startNode = new EnemyNutrientNode(MapManager.Instance.GetNodeCenter(MapManager.Instance.GetGridIndex((Vector2)startPos.position)));
        goalNode = new EnemyNutrientNode(MapManager.Instance.GetNodeCenter(MapManager.Instance.GetGridIndex((Vector2)endPos.position)));
        // Update the size and position of all obstacles in map
        MapManager.Instance.GetObstacles ();
        // Find a new path between the start and goal node
        pathArray = EnemyNutrientAStar.FindPath(startNode, goalNode);
    }
    void FindPath()
    {
        startPos = startObject.transform;
        endPos   = goalObject.transform;

        // Initialize start and goal node
        startNode = new EnemyNutrientNode(MapManager.Instance.GetNodeCenter(MapManager.Instance.GetGridIndex((Vector2)startPos.position)));
        goalNode  = new EnemyNutrientNode(MapManager.Instance.GetNodeCenter(MapManager.Instance.GetGridIndex((Vector2)endPos.position)));
        // Update the size and position of all obstacles in map
        MapManager.Instance.GetObstacles();
        // Find a new path between the start and goal node
        pathArray = EnemyNutrientAStar.FindPath(startNode, goalNode);
    }
Example #10
0
    // Get the  neighouring nodes in 4 cardinal directions
    public void GetNeighbours(EnemyNutrientNode node, ArrayList neighbours)
    {
        Vector2 neighbourPos  = node.position;
        int     neighborIndex = GetGridIndex(neighbourPos);

        int row    = GetRow(neighborIndex);
        int column = GetColumn(neighborIndex);

        // Top
        int leftNodeRow    = row + 1;
        int leftNodeColumn = column;

        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Bottom
        leftNodeRow    = row - 1;
        leftNodeColumn = column;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Left
        leftNodeRow    = row;
        leftNodeColumn = column - 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Right
        leftNodeRow    = row;
        leftNodeColumn = column + 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Top left
        leftNodeRow    = row + 1;
        leftNodeColumn = column - 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Top right
        leftNodeRow    = row + 1;
        leftNodeColumn = column + 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Bottom left
        leftNodeRow    = row - 1;
        leftNodeColumn = column - 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Bottom right
        leftNodeRow    = row - 1;
        leftNodeColumn = column + 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);
    }
    // Override the class CompareTo function for sorting
    // Applied when calling Sort.Sort from ArrayList
    // Compare using the estimated total cost between two nodes
    public int CompareTo(object obj)
    {
        EnemyNutrientNode node = (EnemyNutrientNode)obj;

        if (this.fEstimatedCost < node.fEstimatedCost)
        {
            return(-1);
        }
        if (this.fEstimatedCost > node.fEstimatedCost)
        {
            return(1);
        }

        return(0);
    }
 void Start()
 {
     // GetComponent on the gameObject
     thisRB             = GetComponent <Rigidbody2D> ();
     pathfindingManager = GetComponent <EMNutrientPathfindingManager> ();
     // Initialization
     currentNode  = null;
     nextNode     = null;
     fSpeed       = Random.Range(.4f, .8f);
     bIsAbsorbed  = false;
     fAbsorbSpeed = Random.Range(1f, 2f);
     fAbsorbTime  = 1f;
     // Not using A* by default
     bCanFindPath = false;
     // Call the PauseAStar function for initial movement
     StartCoroutine(PauseAStar());
 }
    // Draw the path found
    void OnDrawGizmos()
    {
        if (pathArray == null)
        {
            return;
        }

        if (pathArray.Count > 0)
        {
            int index = 1;
            foreach (EnemyNutrientNode node in pathArray)
            {
                if (index < pathArray.Count)
                {
                    EnemyNutrientNode nextNode = (EnemyNutrientNode)pathArray[index];
                    Debug.DrawLine(node.position, nextNode.position, Color.green);
                    index++;
                }
            }
            ;
        }
    }
 void Update()
 {
     // Destroy the nutrient if enemy main cell is invisible
     if (!EMHelper.Instance().IsEnemyVisible)
     {
         Destroy(this.gameObject);
     }
     // Absorb behaviour
     if (bIsAbsorbed)
     {
         Absorb();
     }
     else
     {
         // A* pathfinding
         if (bCanFindPath)
         {
             // Set the target to the next node
             if (pathfindingManager.pathArray != null)
             {
                 if (pathfindingManager.pathArray.Count > 1)
                 {
                     nextNode    = (EnemyNutrientNode)pathfindingManager.pathArray [1];
                     currentNode = nextNode;
                 }
             }
             else
             {
                 nextNode = null;
             }
             // Move to the target node
             if (currentNode != null)
             {
                 thisRB.velocity = (currentNode.position - (Vector2)this.gameObject.transform.position) * fSpeed;
             }
         }
     }
 }
Example #15
0
 // Add the node to the frontier and sort all nodes based on the estimated total cost
 public void Push(EnemyNutrientNode node)
 {
     this.nodes.Add(node);
     this.nodes.Sort();
 }
Example #16
0
 // Remove the node from the frontier and sort the rest based on the estimated total cost
 public void Remove(EnemyNutrientNode node)
 {
     this.nodes.Remove(node);
     this.nodes.Sort();
 }
 // Remove the node from the frontier and sort the rest based on the estimated total cost
 public void Remove(EnemyNutrientNode node)
 {
     this.nodes.Remove(node);
     this.nodes.Sort();
 }
    // Find the path between start node and goal node using AStar Algorithm
    public static ArrayList FindPath(EnemyNutrientNode start, EnemyNutrientNode goal)
    {
        // Start Finding the path
        frontier = new Frontier_ExploredSet ();						// Initialize the frontier
        exploredSet = new Frontier_ExploredSet ();					// Initialize the explored set
        frontier.Push(start);										// Add the start node to the frontier
        start.fTotalCost = 0.0f;									// Initialize the total cost for the start node
        start.fEstimatedCost = HeuristicEstimateCost(start, goal);	// Calculate the heuristic

        EnemyNutrientNode node = null;								// Initialize a node to use

        // While the frontier isnot empty
        while (frontier.Length != 0)
        {
            node = frontier.First();								// Take the first node in the frontier

            // If the node is the goal node, then the path is found
            // Instead of checking after adding the node to the explored set, we check it when it's first generated
            // The purpose is to save time from looking for a more optimal path
            if (node.position == goal.position)
            {
                return CalculatePath(node);
            }

            ArrayList neighbours = new ArrayList();
            MapManager.Instance.GetNeighbours(node, neighbours);

            #region CheckNeighbours

            // Get the Neighbours
            for (int i = 0; i < neighbours.Count; i++)
            {
                // Cost between neighbour nodes
                EnemyNutrientNode neighbourNode = (EnemyNutrientNode)neighbours[i];

                if (!exploredSet.Contains(neighbourNode))
                {
                    // Cost from current node to this neighbour node
                    float cost = HeuristicEstimateCost(node, neighbourNode);

                    // Total Cost So Far from start to this neighbour node
                    float totalCost = node.fTotalCost + cost;

                    // Estimated cost for neighbour node to the goal
                    float neighbourNodeEstCost = HeuristicEstimateCost(neighbourNode, goal);

                    // Assign neighbour node properties
                    neighbourNode.fTotalCost = totalCost;
                    neighbourNode.parent = node;
                    neighbourNode.fEstimatedCost = totalCost + neighbourNodeEstCost;

                    // Add the neighbour node to the frontier if not already existed in the frontier
                    if (!frontier.Contains(neighbourNode))
                    {
                        frontier.Push(neighbourNode);
                    }
                }
            }

            #endregion

            exploredSet.Push(node);									// Add the node to the explored set as it is expanded
            frontier.Remove(node);									// Remove the node from the frontier
        }

        // If finished looping and cannot find the goal then return null
        if (node.position != goal.position)
        {
            //Debug.LogError("Goal Not Found");
            //Debug.Log ("Last node position:" + node.position);
            //Debug.Log ("Goal node position:" + goal.position);
            return null;
        }

        // Calculate the path based on the final node
        return CalculatePath(node);
    }
 void Update()
 {
     // Destroy the nutrient if enemy main cell is invisible
     if (!EMHelper.Instance().IsEnemyVisible)
         Destroy (this.gameObject);
     // Absorb behaviour
     if (bIsAbsorbed)
         Absorb ();
     else
     {
         // A* pathfinding
         if (bCanFindPath) {
             // Set the target to the next node
             if (pathfindingManager.pathArray != null) {
                 if (pathfindingManager.pathArray.Count > 1) {
                     nextNode = (EnemyNutrientNode)pathfindingManager.pathArray [1];
                     currentNode = nextNode;
                 }
             } else
                 nextNode = null;
             // Move to the target node
             if (currentNode != null)
                 thisRB.velocity = (currentNode.position - (Vector2)this.gameObject.transform.position) * fSpeed;
         }
     }
 }
 void Start()
 {
     // GetComponent on the gameObject
     thisRB = GetComponent<Rigidbody2D> ();
     pathfindingManager = GetComponent<EMNutrientPathfindingManager> ();
     // Initialization
     currentNode = null;
     nextNode = null;
     fSpeed = Random.Range (.4f, .8f);
     bIsAbsorbed = false;
     fAbsorbSpeed = Random.Range (1f, 2f);
     fAbsorbTime = 1f;
     // Not using A* by default
     bCanFindPath = false;
     // Call the PauseAStar function for initial movement
     StartCoroutine (PauseAStar ());
 }
Example #21
0
    // Get the  neighouring nodes in 4 cardinal directions
    public void GetNeighbours(EnemyNutrientNode node, ArrayList neighbours)
    {
        Vector2 neighbourPos = node.position;
        int neighborIndex = GetGridIndex(neighbourPos);

        int row = GetRow(neighborIndex);
        int column = GetColumn(neighborIndex);

        // Top
        int leftNodeRow = row + 1;
        int leftNodeColumn = column;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Bottom
        leftNodeRow = row - 1;
        leftNodeColumn = column;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Left
        leftNodeRow = row;
        leftNodeColumn = column - 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Right
        leftNodeRow = row;
        leftNodeColumn = column + 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Top left
        leftNodeRow = row + 1;
        leftNodeColumn = column - 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Top right
        leftNodeRow = row + 1;
        leftNodeColumn = column + 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Bottom left
        leftNodeRow = row - 1;
        leftNodeColumn = column - 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);

        // Bottom right
        leftNodeRow = row - 1;
        leftNodeColumn = column + 1;
        AssignNeighbour(leftNodeRow, leftNodeColumn, neighbours);
    }
Example #22
0
    // Get the obstacles in the scene
    public void GetObstacles()
    {
        // Initialise the nodes
        nodes = new EnemyNutrientNode[nNumOfRows, nNumOfColumns];

        int index = 0;
        for (int i = 0; i < nNumOfRows; i++)
        {
            for (int j = 0; j < nNumOfColumns; j++)
            {
                Vector2 cellPos = GetNodeCenter(index);
                EnemyNutrientNode node = new EnemyNutrientNode(cellPos);
                nodes[i, j] = node;

                index++;
            }
        }

        // Set the position for each obstacle
        if (obstacleList != null && obstacleList.Count > 0)
        {
            foreach (GameObject obstacle in obstacleList)
            {
                if (obstacle != null)
                {
                    if (IsInBounds (obstacle.transform.position))
                    {
                        int indexCell = GetGridIndex(obstacle.transform.position);
                        int column = GetColumn(indexCell);
                        int row = GetRow(indexCell);
                        int range = (int)(obstacle.GetComponent<CircleCollider2D> ().bounds.size.x / fUniversalnodeSize);

                        // Assign unaccessible area
                        nodes[row, column].MarkAsUnaccessible();
                        /*
                        for (int i = row - range; i < row + range; i++)
                        {
                            for (int j = column - range; j < column + range; j++)
                            {
                                if (i >= 0 && i < nNumOfRows && j >= 0 && j < nNumOfColumns)
                                {
                                    if (nodes[i, j].bAccessible)
                                        nodes[i, j].MarkAsUnaccessible();
                                }
                            }
                        }
                        */
                    }
                }
            }
        }
    }
 // Get the real path by reversing the path found
 private static ArrayList CalculatePath(EnemyNutrientNode node)
 {
     ArrayList list = new ArrayList();
     while (node != null)
     {
         list.Add(node);
         node = node.parent;
     }
     list.Reverse();
     return list;
 }
Example #24
0
    // Calculate the estimated Heuristic cost to the goal node
    private static float HeuristicEstimateCost(EnemyNutrientNode currentNode, EnemyNutrientNode goalNode)
    {
        Vector2 vecCost = currentNode.position - goalNode.position;

        return(vecCost.magnitude);
    }
 // Add the node to the frontier and sort all nodes based on the estimated total cost
 public void Push(EnemyNutrientNode node)
 {
     this.nodes.Add(node);
     this.nodes.Sort();
 }
Example #26
0
    // Find the path between start node and goal node using AStar Algorithm
    public static ArrayList FindPath(EnemyNutrientNode start, EnemyNutrientNode goal)
    {
        // Start Finding the path
        frontier    = new Frontier_ExploredSet();                               // Initialize the frontier
        exploredSet = new Frontier_ExploredSet();                               // Initialize the explored set
        frontier.Push(start);                                                   // Add the start node to the frontier
        start.fTotalCost     = 0.0f;                                            // Initialize the total cost for the start node
        start.fEstimatedCost = HeuristicEstimateCost(start, goal);              // Calculate the heuristic

        EnemyNutrientNode node = null;                                          // Initialize a node to use

        // While the frontier isnot empty
        while (frontier.Length != 0)
        {
            node = frontier.First();                                                                            // Take the first node in the frontier

            // If the node is the goal node, then the path is found
            // Instead of checking after adding the node to the explored set, we check it when it's first generated
            // The purpose is to save time from looking for a more optimal path
            if (node.position == goal.position)
            {
                return(CalculatePath(node));
            }

            ArrayList neighbours = new ArrayList();
            MapManager.Instance.GetNeighbours(node, neighbours);

            #region CheckNeighbours

            // Get the Neighbours
            for (int i = 0; i < neighbours.Count; i++)
            {
                // Cost between neighbour nodes
                EnemyNutrientNode neighbourNode = (EnemyNutrientNode)neighbours[i];

                if (!exploredSet.Contains(neighbourNode))
                {
                    // Cost from current node to this neighbour node
                    float cost = HeuristicEstimateCost(node, neighbourNode);

                    // Total Cost So Far from start to this neighbour node
                    float totalCost = node.fTotalCost + cost;

                    // Estimated cost for neighbour node to the goal
                    float neighbourNodeEstCost = HeuristicEstimateCost(neighbourNode, goal);

                    // Assign neighbour node properties
                    neighbourNode.fTotalCost     = totalCost;
                    neighbourNode.parent         = node;
                    neighbourNode.fEstimatedCost = totalCost + neighbourNodeEstCost;

                    // Add the neighbour node to the frontier if not already existed in the frontier
                    if (!frontier.Contains(neighbourNode))
                    {
                        frontier.Push(neighbourNode);
                    }
                }
            }

            #endregion

            exploredSet.Push(node);                                                                             // Add the node to the explored set as it is expanded
            frontier.Remove(node);                                                                              // Remove the node from the frontier
        }

        // If finished looping and cannot find the goal then return null
        if (node.position != goal.position)
        {
            //Debug.LogError("Goal Not Found");
            //Debug.Log ("Last node position:" + node.position);
            //Debug.Log ("Goal node position:" + goal.position);
            return(null);
        }

        // Calculate the path based on the final node
        return(CalculatePath(node));
    }
 // Calculate the estimated Heuristic cost to the goal node
 private static float HeuristicEstimateCost(EnemyNutrientNode currentNode, EnemyNutrientNode goalNode)
 {
     Vector2 vecCost = currentNode.position - goalNode.position;
     return vecCost.magnitude;
 }