// Placement private void Update() { // Does a raycast. If it is touching a platform or morphbot, it will use a function to snap the raycastHit.point to a grid and move the hover MorphBot there. // If the raycast does not collide with a platform/MorphBot OR the gridsnapped location is OUTSIDE of the array, the hover MorphBot will disappear. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out raycastHit, maxRaycastDistance, gameLayers)) { Vector3 location = functions.Vector3ToGrid(raycastHit); if (rulesets.WithinArray(Vector3Int.RoundToInt(location))) { if (morphBotHover.activeSelf == false) { morphBotHover.SetActive(true); } morphBotHover.transform.position = location; } else { if (morphBotHover.activeSelf != false) { morphBotHover.SetActive(false); } } } else { if (morphBotHover.activeSelf != false) { morphBotHover.SetActive(false); } } // If the mouse is touching a platform or MorphBot, a non-hover opaque MorphBot will be placed in the location and named accordingly. // The grid at that location will also be updated to unwalkable because there is now a block there. This helps with the pathfinding algorithm. if (Input.GetMouseButtonDown(0)) { RaycastHit raycastHit; Ray placementRay = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out raycastHit, maxRaycastDistance, gameLayers)) { Vector3Int location = functions.Vector3ToGrid(raycastHit); if (rulesets.WithinArray(location)) { GameObject morphBot = Instantiate(morphBotRef, location, Quaternion.identity); morphBot.transform.SetParent(morphBotsPar.transform); morphBot.name = "MorphBot(" + location.x + ", " + location.y + ", " + location.z + ")"; main.grid[location.x, location.y, location.z].walkable = false; } } } }
// Selection & pathfinding private void Update() { // Uses the "selection" script that already highlights a MorphBot to a different color (dark purple in this case) which shows where the mouse is pointing. // Once the user presses LMB and a MorphBot is not moving, the "selection" script is disabled, thus freezing the current MorphBot that we are staring at (which is highlighted purple). // This same MorphBot is then set to currentMorphBot and used for pathfinding. // ONLY WORKS IF FACING A MORPHBOT if (Input.GetMouseButtonDown(0) && isPathfinding == false) { if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out raycastHit, maxDistance, gameLayers) && raycastHit.transform.gameObject.layer == 9) { selection.enabled = true; if (raycastHit.transform.gameObject == currentMorphBot && currentMorphBot != null) { currentMorphBot = null; } else { currentMorphBot = raycastHit.transform.gameObject; selection.hoverMorphBot.GetComponent <MeshRenderer>().material = selection.defaultMat; selection.hoverMorphBot = currentMorphBot; selection.hoverMorphBot.GetComponent <MeshRenderer>().material = selection.hover; selection.enabled = false; } } } // Stars pathfinding only if a block is selected and we are not pathfinding if (Input.GetKeyDown(translate) && currentMorphBot != null && isPathfinding == false) { if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out raycastHit, maxDistance, gameLayers)) { Vector3Int endLocation = functions.Vector3ToGrid(raycastHit); if (rulesets.WithinArray(endLocation)) { // Sets isPathfinding to true, disabling many features until a block is not moving (or does not find a path). isPathfinding = true; Vector3Int pos = Vector3Int.RoundToInt(currentMorphBot.transform.position); main.grid[pos.x, pos.y, pos.z].walkable = true; // References pathfinding and starts the moving process in the Pathfinding script. pathfinding.FindPath(Vector3Int.RoundToInt(currentMorphBot.transform.position), endLocation); } } } }
// A pathfinding function used by A* to find neighbors (empty places in the grid the block can move to) // It must abide by the MorphBots' physical limitations (e.g no floating in the air, must always be touching two blocks in the direction that it is traveling) // References other pathfinding functions below such as EmptyCheck // Neighbors cannot be diagonal public List <Node> GetNeighbors(Node currentNode) { List <Node> Neighbors = new List <Node>(); int x = currentNode.position.x; int y = currentNode.position.y; int z = currentNode.position.z; if (rulesets.WithinArray(currentNode.position + Vector3Int.right) && main.grid[x + 1, y, z].walkable == true) { if (EmptyCheckX(true, currentNode.position)) { Neighbors.Add(main.grid[x + 1, y, z]); } } if (rulesets.WithinArray(currentNode.position + Vector3Int.left) && main.grid[x - 1, y, z].walkable == true) { if (EmptyCheckX(false, currentNode.position)) { Neighbors.Add(main.grid[x - 1, y, z]); } } if (rulesets.WithinArray(currentNode.position + Vector3Int.RoundToInt(Vector3.forward)) && main.grid[x, y, z + 1].walkable == true) { if (EmptyCheckZ(true, currentNode.position)) { Neighbors.Add(main.grid[x, y, z + 1]); } } if (rulesets.WithinArray(currentNode.position + Vector3Int.RoundToInt(Vector3.back)) && main.grid[x, y, z - 1].walkable == true) { if (EmptyCheckZ(false, currentNode.position)) { Neighbors.Add(main.grid[x, y, z - 1]); } } if (rulesets.WithinArray(currentNode.position + Vector3Int.up) && main.grid[x, y + 1, z].walkable == true) { if (EmptyCheckY(true, currentNode.position)) { Neighbors.Add(main.grid[x, y + 1, z]); } } if (rulesets.WithinArray(currentNode.position + Vector3Int.down) && main.grid[x, y - 1, z].walkable == true) { if (EmptyCheckY(false, currentNode.position)) { Neighbors.Add(main.grid[x, y - 1, z]); } } return(Neighbors); }