/// <summary> /// The start function /// </summary> private void Start() { // Set to new stack of tilebehvaior objects this.path = new Stack <TileBehavior>(); // Run algorithm and get pathfrom the start node that was clicked by the user List <Node> finalPath = AStar.RunAStar(GridManager.Instance.StartNode, GridManager.Instance.GoalNode); // Set the destination to the current position to prevent movement this.destination = this.transform.position; // If the path count is equal to 0...cant reach the goal if (finalPath.Count == 0) { return; } TileBehavior t; // Loop through the return list of nodes foreach (Node n in finalPath) { // Check if the node is in the dictionary if (GridManager.Instance.Tiles.TryGetValue(n, out t)) { // Push the node on to the stack this.path.Push(t); } } // Set the destination to the current position to prevent movement this.destination = this.transform.position; // If the path has nodes in it if (this.path.Count > 0) { // Pop the first tile behavior and set it to the current tile this.currentTile = this.path.Pop(); // Now set the current tile position to the destination this.destination = this.currentTile.transform.position; } // Subscribe and listen for the "Run" event EventManager.Subscribe("Run", this.CalcNewPath); }
/// <summary> /// The set up grid function. /// </summary> private void SetUpGrid() { // Offset for spacing tiles float offset = 0.5f; // Get the screens position in world Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(0, Screen.height)); // Bool reference bool walkable; // Initialize grid with 10, 10 this.grid = new Node[10, 10]; // Loop through the grid for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { // Instantiate a tile prefab GameObject go = Instantiate(this.tilePrefab); // Set its position to the world position with the appropriate offset go.transform.position = new Vector3(worldPos.x + i + 0.5f, worldPos.y - j + -0.5f, 0); // Set walkable to true or false walkable = (i % 10 == 0 || j % 10 == 0 || i == 10 - 1 || j == 10 - 1) ? false : true; // Create a node Node n = new Node(i, j, walkable); // Get the TileBehavior component TileBehavior tile = go.GetComponent <TileBehavior>(); // Set its node to the new created node tile.Node = n; // Add the node to the grid this.grid[i, j] = n; // Add the node and tile to the dictionary this.tiles.Add(n, tile); } } }
/// <summary> /// The update function /// </summary> private void Update() { // If the current position of the enemy is not the destination if (this.transform.position != this.destination) { // If the current Tile node has become unwalkable if (!this.currentTile.Node.IsWalkable) { // Calculate a new path and return this.CalcNewPath(); return; } // Move towards the destination at a speed of 2 * time.deltaTime this.transform.position = Vector3.MoveTowards( this.transform.position, this.destination, 2 * Time.deltaTime); } // If the object has reached its destination else { // If the the path count is greater than 0 if (path.Count > 0) { // Get the first object in the stack TileBehavior t = path.Pop(); // If the node is walkable if (t.Node.IsWalkable) { // Set the current tile to the previous tile as reference this.previousTile = this.currentTile; // Set the object to the current tile this.currentTile = t; // Set the current tiles position to the destination this.destination = this.currentTile.transform.position; } } } }
/// <summary> /// The calculate new path function. /// Gets the new AStar path /// </summary> private void CalcNewPath() { // Create new list of nodes for final path List <Node> finalPath = new List <Node>(); // Set the path to a new stack of tile behavior objects this.path = new Stack <TileBehavior>(); // If the current Tile is not equal to null if (this.currentTile != null) { // If the current tile node is not walkable - use the previous tile node else use the current tile node Node startNode = (!this.currentTile.Node.IsWalkable) ? this.previousTile.Node : this.currentTile.Node; // Run algorithm and get path using the proper starting tile finalPath = AStar.RunAStar(startNode, GridManager.Instance.GoalNode); TileBehavior t; // Loop through the nodes in the final path foreach (Node n in finalPath) { // If the dictionary contains it if (GridManager.Instance.Tiles.TryGetValue(n, out t)) { // Push it onto the stack this.path.Push(t); } } // If path count is greater than 0 if (this.path.Count > 0) { // Pop node off the stack and set it as the current tile this.currentTile = this.path.Pop(); // Set the destination to the current tile position this.destination = this.currentTile.transform.position; } } }
/// <summary> /// The update function. /// </summary> private void Update() { // Get the right mouse button if (Input.GetMouseButtonDown(0)) { RaycastHit hit; // Perform ray cast Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // If ray cast hit something if (Physics.Raycast(ray, out hit, 100.0f)) { // Check if it was a tile TileBehavior tile = hit.collider.GetComponent <TileBehavior>(); // If the start node is null if (this.startNode == null) { // If the tile is not null and the node is walkable if (tile != null && tile.Node.IsWalkable) { // Set the start node to that node this.startNode = tile.Node; // Change sprite renderer to green hit.collider.gameObject.GetComponent <SpriteRenderer>().material.color = Color.green; // Add the tile to the list to be reset this.tilesForReset.Add(tile); } } // Else if the goal node is null else if (this.goalNode == null) { // If the tile is not null and the node is walkable and the node is not the start node if (tile != null && tile.Node.IsWalkable && tile.Node != this.startNode) { // Set the node to the goal node this.goalNode = tile.Node; // Change sprite renderer to red hit.collider.gameObject.GetComponent <SpriteRenderer>().material.color = Color.red; // Add the tile to the list to be reset this.tilesForReset.Add(tile); } } } } // Get the right mouse button if (Input.GetMouseButtonDown(1)) { RaycastHit hit; // Perform ray cast Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // If ray cast hit something if (Physics.Raycast(ray, out hit, 100.0f)) { // If clicked on an enemy then just return if (hit.collider.GetComponent <Enemy>()) { return; } // Check if it was a tile TileBehavior tile = hit.collider.GetComponent <TileBehavior>(); // If the tile clicked on is the start node or goal node then just return if (tile.Node == this.startNode || tile.Node == this.goalNode) { return; } // Set the node to not walkable tile.Node.IsWalkable = false; // Change sprite renderer to blue hit.collider.gameObject.GetComponent <SpriteRenderer>().material.color = Color.blue; // Run the algorithm again because the moving objects path might need to be changed EventManager.Publish("Run"); // Add the tile to the list to be reset this.tilesForReset.Add(tile); } } }