//Spawn collectables at new positions ensuring its a valid location the agent can move to. private void SpawnCollectable() { Vector3 spawnPoint = Vector3.zero; bool isValidPosition = false; for (int i = 0; i < collectablesToSpawn; i++) { spawnPoint = RandomPosition(); Node tmp = grid.NodeFromWorldPosition(spawnPoint); //Get a reference to the node at the spawn point. if (tmp.walkable != true) { while (!isValidPosition) { spawnPoint = RandomPosition(); tmp = grid.NodeFromWorldPosition(spawnPoint); if (tmp.walkable) { isValidPosition = true; agentCollectables[i].gameObject.SetActive(true); agentCollectables[i].transform.position = spawnPoint; } } } else { agentCollectables[i].gameObject.SetActive(true); agentCollectables[i].transform.position = spawnPoint; //Add(Instantiate(collectablePrefab, RandomPosition(), Quaternion.identity)); } } }
/// <summary> /// Finds a path using A* /// </summary> /// <param name="startPosition">The starting position of the agent.</param> /// <param name="targetPosition">The target position.</param> private void PathAStar(Vector3 startPosition, Vector3 targetPosition) { //Get both nodes from the given world positions, start and target. Node startNode = grid.NodeFromWorldPosition(startPosition); Node targetNode = grid.NodeFromWorldPosition(targetPosition); //Initialize open and closed set. List <Node> openSet = new List <Node>(); HashSet <Node> closedSet = new HashSet <Node>(); bool success = false; //First add starting node to the open set. openSet.Add(startNode); //Only loop while the open set has nodes. while (openSet.Count > 0) { Node curNode = openSet[0]; for (int i = 1; i < openSet.Count; i++) { if ((openSet[i].fCost < curNode.fCost || openSet[i].fCost == curNode.fCost) && openSet[i].hCost < curNode.hCost) { //If the fCost of the node in open set is less than the current node. curNode = openSet[i]; //Since the cost of that node is less, thats the node we want. (Shortest path) } } //Now that the current node is set to the node with the lowest fCost, remove it from open set and put in closed set. openSet.Remove(curNode); closedSet.Add(curNode); if (curNode == targetNode) { //If the current node is equal to the target node, we reached the destination. success = true; break; } //Get the neighbors of the current node. List <Node> neighbors = grid.GetNeighbors(curNode); //Loops through each of the current nodes neighbors. foreach (Node neighborNode in neighbors) { //if the neighbor is not walkable or the neighbor is in the closed set, skip to next neighbor. if (!neighborNode.walkable || closedSet.Contains(neighborNode)) { continue; } int newCost = curNode.gCost + GetManhattenDistance(neighborNode, targetNode); if (newCost < neighborNode.gCost || !openSet.Contains(neighborNode)) { //Assign new values to neighbor node. neighborNode.gCost = newCost; neighborNode.hCost = GetManhattenDistance(neighborNode, targetNode); neighborNode.parent = curNode; //If a neighboring node is not in the open set add it to be explored. if (!openSet.Contains(neighborNode)) { openSet.Add(neighborNode); } } } } Vector3[] pathPoints = new Vector3[0]; if (success) { pathPoints = GetPath(startNode, targetNode); } rm.FinishedProcessing(pathPoints, success); }