//sort through the closed list to find the final path void FindPath() { finalPathQueue.Enqueue(closed[pathEnd].ReturningMainNode()); SCR_NodeClass CurrentParent = closed[pathEnd].ReturningParentNode(); while (CurrentParent != null) { var currentPosition = ParentSearch(CurrentParent); if (closed[currentPosition].ReturningParentNode() == null) { break; } finalPathQueue.Enqueue(closed[currentPosition].ReturningMainNode()); CurrentParent = closed[currentPosition].ReturningParentNode(); } int PathSize = finalPathQueue.Count; for (int i = 0; i < PathSize; i++) { finalMapPathway.Add(finalPathQueue.Dequeue()); } finalPathQueue.Clear(); }
private void OnSceneGUI() { for (int i = 0; i < nodes.ReturnListSize(); i++) { SCR_NodeClass currentNode = nodes.ReturnNodeAtIndex(i); List <STR_ID> currentNeighbours = currentNode.ReturnNeighbours(); Transform nodePos = currentNode.returnID().body.transform; GUIStyle style = new GUIStyle(); style.normal.textColor = Color.white; Handles.Label(nodePos.position, nodePos.gameObject.name, style); Color currentColour = Color.blue; RoomType currentRoomType = currentNode.ReturnRoomType(); if (currentRoomType == RoomType.PrimaryRoom || currentRoomType == RoomType.InitialFightRoom || currentRoomType == RoomType.KeyRoom) { currentColour = new Color(1.0f, 0.64f, 0.0f, 1.0f); } else if (currentRoomType == RoomType.SecondaryPathway) { currentColour = Color.gray; } else if (currentRoomType == RoomType.StartRoom || currentRoomType == RoomType.EndRoom) { currentColour = Color.black; } else if (currentRoomType == RoomType.LootRoom) { currentColour = Color.blue; } else if (currentRoomType == RoomType.BlockedRoute) { currentColour = Color.red; } else if (currentRoomType == RoomType.UpgradeRoom) { currentColour = Color.yellow; } else if (currentRoomType == RoomType.ChallangeRoom) { currentColour = Color.magenta; } else if (currentRoomType == RoomType.smoothingPath) { currentColour = Color.white; } Handles.color = currentColour; Handles.DrawSolidDisc(nodePos.position, Vector3.up, nodes.nodeRadius); Handles.color = Color.blue; for (int j = 0; j < currentNeighbours.Count; j++) { Transform neighbourPos = currentNeighbours[j].body.transform; Handles.DrawLine(nodePos.position, neighbourPos.position); } } }
//will add any potential neighbouring nodes to the potential path list if they haven't already, will check to see if the path has reached the goal void CalculateNeighbours() { List <STR_ID> neighbours = currentNode.ReturnNeighbours(); for (int i = 0; i < neighbours.Count; i++) { SCR_NodeClass neighbourNode = nodeManager.ReturnNode(neighbours[i]); STR_ID currentNeighbourID = neighbourNode.returnID(); STR_ID currentNodeID = currentNode.returnID(); if (currentNodeID.Compare(currentNeighbourID) == false) { if (listOfNodes.Contains(neighbourNode)) { if (neighbourNode.ReturnRoomType() != RoomType.BlockedRoute) { var current = new CalculatePath(neighbourNode, currentNode); if (neighbourNode.ReturnRoomType() == RoomType.InitialFightRoom || neighbourNode.ReturnRoomType() == RoomType.ChallangeRoom) { if (!finalPathPoints.Contains(neighbourNode)) { closed.Add(current); } } if ((!open.Contains(current)) && (!closed.Contains(current))) { if (CheckOpenList(currentNodeID, currentNeighbourID) == false && CheckClosedList(currentNodeID, currentNeighbourID) == false) { open.Add(current); } } } } } } closed.Add(open[currentPos]); Vector3 endPos = goal.returnID().body.transform.position; STR_ID currentID = currentNode.returnID(); Vector3 currentPosition = currentNode.returnID().body.transform.position; if (currentNode == goal) { pathfound = true; pathEnd = closed.Count - 1; } open.Remove(open[currentPos]); }
//return a node within the map structure, requires a node ID public SCR_NodeClass ReturnNode(STR_ID nodeID) { SCR_NodeClass node = new SCR_NodeClass(); for (int i = 0; i < nodes.Count; i++) { if (nodeID.Compare(nodes[i].returnID())) { node = nodes[i]; } } return(node); }
//search through the closed list to find a nodes parent node int ParentSearch(SCR_NodeClass Parent) { int pos = 0; for (int i = 0; i < closed.Count; i++) { if (closed[i].ReturningMainNode() == Parent) { pos = i; break; } } return(pos); }
//Will select the next point to review within the map void CalculatePoint() { float Fcost = 10000000.0f; Vector3 startPos = start.returnID().body.transform.position; Vector3 endPos = goal.returnID().body.transform.position; for (int i = 0; i < open.Count; i++) { STR_ID currentID = open[i].ReturningMainNode().returnID(); var CurrentFCost = CalculateCost(currentID.body.transform.position, startPos) + CalculateCost(currentID.body.transform.position, endPos); if (CurrentFCost < Fcost) { Fcost = CurrentFCost; currentNode = open[i].ReturningMainNode(); currentPos = i; } } }
//Main Pathfinding function, will be called to generate the path and will return the final path public List <SCR_NodeClass> FindingPath(SCR_NodeClass startPoint, SCR_NodeClass endPoint, List <SCR_NodeClass> nodeSelection) { listOfNodes = new List <SCR_NodeClass>(); listOfNodes = nodeSelection; pathfound = false; finalMapPathway = new List <SCR_NodeClass>(); open = new List <CalculatePath>(); closed = new List <CalculatePath>(); nodeManager = GetComponent <SCR_NodeManager>(); start = startPoint; goal = endPoint; open.Add(new CalculatePath(startPoint, null)); GeneratePath(); FindPath(); open.Clear(); closed.Clear(); return(finalMapPathway); }
//remove a node from the list, requires a node ID public void RemoveNode(STR_ID nodeID) { for (int i = 0; i < nodes.Count; i++) { SCR_NodeClass currentNode = nodes[i]; List <STR_ID> currentNeighbours = currentNode.ReturnNeighbours(); if (nodeID.Compare(currentNode.returnID())) { nodes.RemoveAt(i); } for (int j = 0; j < currentNeighbours.Count; j++) { if (nodeID.Compare(currentNeighbours[j])) { nodes[i].RemoveNeighbour(j); } } } }
public CalculatePath(SCR_NodeClass Position, SCR_NodeClass Parent) { mainNode = Position; previousNode = Parent; }
//Add a node to the current Map, requires a New node class public void AddNode(SCR_NodeClass newNode) { nodes.Add(newNode); }
//Create a random path through the map structure public void CreatePath() { List <SCR_NodeClass> potentialMainPathCollection = new List <SCR_NodeClass>(); List <SCR_NodeClass> sorteedMainPathRooms = new List <SCR_NodeClass>(); List <SCR_NodeClass> keyRoomAreas = new List <SCR_NodeClass>(); List <SCR_NodeClass> lootRooms = new List <SCR_NodeClass>(); List <SCR_NodeClass> upgradeRooms = new List <SCR_NodeClass>(); List <SCR_NodeClass> challangeRooms = new List <SCR_NodeClass>(); finalMapPath = new List <SCR_NodeClass>(); SCR_NodeClass startNode = new SCR_NodeClass(), endNode = new SCR_NodeClass(); int numberOfPointsToBeSelected = AmountOfMapPathPoints; for (int i = 0; i < nodes.Count; i++) { SCR_NodeClass currentNode = nodes[i]; if (currentNode.ReturnRoomType() == RoomType.PrimaryRoom || currentNode.ReturnRoomType() == RoomType.InitialFightRoom) { potentialMainPathCollection.Add(currentNode); } else if (currentNode.ReturnRoomType() == RoomType.KeyRoom) { keyRoomAreas.Add(currentNode); numberOfPointsToBeSelected--; } else if (currentNode.ReturnRoomType() == RoomType.StartRoom) { startNode = currentNode; } else if (currentNode.ReturnRoomType() == RoomType.EndRoom) { endNode = currentNode; } else if (currentNode.ReturnRoomType() == RoomType.LootRoom) { lootRooms.Add(currentNode); } else if (currentNode.ReturnRoomType() == RoomType.UpgradeRoom) { upgradeRooms.Add(currentNode); } else if (currentNode.ReturnRoomType() == RoomType.ChallangeRoom) { challangeRooms.Add(currentNode); } } potentialMainPathCollection.Insert(0, startNode); potentialMainPathCollection.Insert(potentialMainPathCollection.Count, endNode); finalMapPath.Add(potentialMainPathCollection[0]); for (int i = 0; i < keyRoomAreas.Count; i++) { finalMapPath.Add(keyRoomAreas[i]); } int pointsAdded = 0; bool startPointSelected = false; while (startPointSelected == false) { int rng = Random.Range(1, potentialMainPathCollection.Count - 1); if (potentialMainPathCollection[rng].ReturnRoomType() == RoomType.InitialFightRoom) { finalMapPath.Add(potentialMainPathCollection[rng]); pointsAdded++; startPointSelected = true; } } while (pointsAdded < numberOfPointsToBeSelected) { int rng = Random.Range(1, potentialMainPathCollection.Count - 1); if (potentialMainPathCollection[rng].ReturnRoomType() != RoomType.InitialFightRoom) { if (!finalMapPath.Contains(potentialMainPathCollection[rng])) { finalMapPath.Add(potentialMainPathCollection[rng]); pointsAdded++; } } } sorteedMainPathRooms.Add(finalMapPath[0]); for (int i = 1; i < finalMapPath.Count; i++) { Vector3 start = finalMapPath[i - 1].returnID().body.transform.position; int currentPoint = 0; float distance = 1000000.0f; for (int j = 1; j < finalMapPath.Count; j++) { Vector3 next = finalMapPath[j].returnID().body.transform.position; if ((next - start).magnitude < distance) { if (!sorteedMainPathRooms.Contains(finalMapPath[j])) { currentPoint = j; distance = (next - start).magnitude; } } } SCR_NodeClass current = finalMapPath[currentPoint]; sorteedMainPathRooms.Add(current); } finalMapPath = sorteedMainPathRooms; finalMapPath.Add(potentialMainPathCollection[potentialMainPathCollection.Count - 1]); SCR_PathFinder pathfinder = GetComponent <SCR_PathFinder>(); pathfinder.finalPathPoints = finalMapPath; List <SCR_NodeClass> pathCalculated = new List <SCR_NodeClass>(); pathCalculated.Add(finalMapPath[0]); for (int i = 0; i < finalMapPath.Count - 1; i++) { List <SCR_NodeClass> temp = pathfinder.FindingPath(finalMapPath[i], finalMapPath[i + 1], nodes); for (int j = 0; j < temp.Count; j++) { pathCalculated.Add(temp[j]); } } for (int i = 0; i < pathCalculated.Count; i++) { if (!finalMapPath.Contains(pathCalculated[i])) { finalMapPath.Add(pathCalculated[i]); } } ////CONNECT THE LOOT ROOMS List <SCR_NodeClass> selectedLootRooms = new List <SCR_NodeClass>(); while (selectedLootRooms.Count < amountOfLootRooms) { int rng = Random.Range(0, lootRooms.Count - 1); if (!selectedLootRooms.Contains(lootRooms[rng])) { selectedLootRooms.Add(lootRooms[rng]); } } for (int i = 0; i < selectedLootRooms.Count; i++) { SCR_NodeClass closestNode = new SCR_NodeClass(); float closestDistance = 1000000.0f; int currentNodeSelected = 0; Vector3 currentPoint = selectedLootRooms[i].returnID().body.transform.position; for (int j = 0; j < finalMapPath.Count; j++) { Vector3 currentNodesPosition = finalMapPath[j].returnID().body.transform.position; float nodeDistance = (currentNodesPosition - currentPoint).magnitude; if (nodeDistance < closestDistance) { closestDistance = nodeDistance; currentNodeSelected = j; } } List <SCR_NodeClass> lootPathCalculated = new List <SCR_NodeClass>(); lootPathCalculated = pathfinder.FindingPath(selectedLootRooms[i], finalMapPath[currentNodeSelected], nodes); for (int z = 0; z < lootPathCalculated.Count; z++) { finalMapPath.Add(lootPathCalculated[z]); } finalMapPath.Add(selectedLootRooms[i]); if (selectedLootRooms[i].specialRoomTriggers != null) { SCR_SpecialRoomTriggers triggerScript = selectedLootRooms[i].specialRoomTriggers; StartCoroutine(triggerScript.CloseGateway(0.1f, false)); } } ////CONNECT THE UPGRADE ROOMS for (int i = 0; i < upgradeRooms.Count; i++) { SCR_NodeClass closestNode = new SCR_NodeClass(); float closestDistance = 1000000.0f; int currentNodeSelected = 0; Vector3 currentPoint = upgradeRooms[i].returnID().body.transform.position; for (int j = 0; j < finalMapPath.Count; j++) { Vector3 currentNodesPosition = finalMapPath[j].returnID().body.transform.position; float nodeDistance = (currentNodesPosition - currentPoint).magnitude; if (nodeDistance < closestDistance) { closestDistance = nodeDistance; currentNodeSelected = j; } } List <SCR_NodeClass> upgradePathCalculated = new List <SCR_NodeClass>(); upgradePathCalculated = pathfinder.FindingPath(upgradeRooms[i], finalMapPath[currentNodeSelected], nodes); for (int z = 0; z < upgradePathCalculated.Count; z++) { finalMapPath.Add(upgradePathCalculated[z]); } finalMapPath.Add(upgradeRooms[i]); if (upgradeRooms[i].specialRoomTriggers != null) { SCR_SpecialRoomTriggers triggerScript = upgradeRooms[i].specialRoomTriggers; StartCoroutine(triggerScript.CloseGateway(0.1f, false)); } } ///select the challange rooms /// List <SCR_NodeClass> selectedChallangeRooms = new List <SCR_NodeClass>(); while (selectedChallangeRooms.Count < amountOfChallangeRooms) { int rng = Random.Range(0, challangeRooms.Count - 1); if (!selectedChallangeRooms.Contains(challangeRooms[rng])) { selectedChallangeRooms.Add(challangeRooms[rng]); } } for (int i = 0; i < selectedChallangeRooms.Count; i++) { SCR_NodeClass closestNode = new SCR_NodeClass(); float closestDistance = 1000000.0f; int currentNodeSelected = 0; Vector3 currentPoint = selectedChallangeRooms[i].returnID().body.transform.position; for (int j = 0; j < finalMapPath.Count; j++) { Vector3 currentNodesPosition = finalMapPath[j].returnID().body.transform.position; float nodeDistance = (currentNodesPosition - currentPoint).magnitude; if (nodeDistance < closestDistance) { closestDistance = nodeDistance; currentNodeSelected = j; } } List <SCR_NodeClass> challangePathCalculated = new List <SCR_NodeClass>(); challangePathCalculated = pathfinder.FindingPath(selectedChallangeRooms[i], finalMapPath[currentNodeSelected], nodes); for (int z = 0; z < challangePathCalculated.Count; z++) { finalMapPath.Add(challangePathCalculated[z]); } finalMapPath.Add(selectedChallangeRooms[i]); } ///FIND A CAMERA PATH WAY CameraPoints = new List <SCR_NodeClass>(); CameraPoints = pathfinder.FindingPath(startNode, endNode, finalMapPath); CameraPoints.Add(startNode); ///set a wall for (int i = 0; i < nodes.Count; i++) { SCR_NodeClass currentNode = nodes[i]; currentNode.closeEntryPoints(false); currentNode.checkObject(type); } for (int i = 0; i < nodes.Count; i++) { SCR_NodeClass currentNode = nodes[i]; if (currentNode.roomManager != null) { if (!finalMapPath.Contains(currentNode)) { currentNode.closeEntryPoints(true); currentNode.roomManager.CloseWalls(); } else { currentNode.closeEntryPoints(true); currentNode.roomManager.OpenWalls(); currentNode.roomManager.SpawnRoom(); } } else { if (!finalMapPath.Contains(currentNode)) { currentNode.closeEntryPoints(true); } else { if (currentNode.specialRoomTriggers != null) { StartCoroutine(currentNode.specialRoomTriggers.CloseGateway(1.0f, false)); } } } } //// set the emission of lamp bois for (int i = 0; i < nodes.Count; i++) { SCR_NodeClass currentNode = nodes[i]; if (!finalMapPath.Contains(currentNode)) { List <GameObject> currentLamposts = currentNode.ReturnLocalLamposts(); for (int j = 0; j < currentLamposts.Count; j++) { if (currentLamposts[j].GetComponent <SCR_LevelMaterials>()) { SCR_LevelMaterials current = currentLamposts[j].GetComponent <SCR_LevelMaterials>(); current.setObjectNonEmissive(); } } currentLamposts.Clear(); List <GameObject> currentBuildings = currentNode.ReturnLocalBuildings(); for (int j = 0; j < currentBuildings.Count; j++) { if (currentBuildings[j].GetComponent <SCR_LevelMaterials>()) { SCR_LevelMaterials current = currentBuildings[j].GetComponent <SCR_LevelMaterials>(); current.setObjectNonEmissive(); } } currentBuildings.Clear(); } } //change the material of the gates if (blockedRouteGateMaterial) { for (int i = 0; i < nodes.Count; i++) { SCR_NodeClass currentNode = nodes[i]; if (!finalMapPath.Contains(currentNode)) { List <GameObject> currentGates = currentNode.ReturnNodeGates(); for (int j = 0; j < currentGates.Count; j++) { if (currentGates[j]) { for (int z = 0; z < currentGates[j].transform.childCount; z++) { if (currentGates[j].transform.GetChild(z).GetComponent <MeshRenderer>() != null) { MeshRenderer currentGatesRenderer = currentGates[j].transform.GetChild(z).GetComponent <MeshRenderer>(); Material[] currentGateMaterials = new Material[currentGatesRenderer.materials.Length]; for (int x = 0; x < currentGateMaterials.Length; x++) { currentGateMaterials[x] = blockedRouteGateMaterial; } currentGatesRenderer.materials = currentGateMaterials; } } } } } } } }
//draws handles within the map private void OnSceneGUI() { for (int i = 0; i < nodeManager.ReturnListSize(); i++) { finalPathSelection = nodeManager.ReturnCameraNodes(); SCR_NodeClass currentNode = nodeManager.ReturnNodeAtIndex(i); List <STR_ID> currentNeighbours = currentNode.ReturnNeighbours(); Transform nodePos = currentNode.returnID().body.transform; Handles.Label(nodePos.position, nodePos.gameObject.name); Color currentColour = Color.blue; RoomType currentRoomType = currentNode.ReturnRoomType(); if (currentRoomType == RoomType.PrimaryRoom || currentRoomType == RoomType.InitialFightRoom || currentRoomType == RoomType.KeyRoom) { if (finalPathSelection.Contains(currentNode)) { currentColour = Color.green; } else { currentColour = Color.black; } } else if (currentRoomType == RoomType.SecondaryPathway) { currentColour = Color.gray; } else if (currentRoomType == RoomType.StartRoom || currentRoomType == RoomType.EndRoom) { currentColour = Color.black; } else if (currentRoomType == RoomType.LootRoom) { currentColour = Color.blue; } else if (currentRoomType == RoomType.BlockedRoute) { currentColour = Color.red; } else if (currentRoomType == RoomType.UpgradeRoom) { currentColour = Color.yellow; } else if (currentRoomType == RoomType.ChallangeRoom) { currentColour = Color.magenta; } else if (currentRoomType == RoomType.smoothingPath) { currentColour = Color.white; } Handles.color = currentColour; Handles.DrawSolidDisc(nodePos.position, Vector3.up, nodeManager.nodeRadius); for (int j = 0; j < currentNeighbours.Count; j++) { Transform neighbourPos = currentNeighbours[j].body.transform; currentColour = Color.blue; SCR_NodeClass NeighbourNode = nodeManager.ReturnNode(currentNeighbours[j]); if (finalPathSelection.Contains(NeighbourNode) && finalPathSelection.Contains(currentNode)) { currentColour = Color.green; } Handles.color = currentColour; Handles.DrawLine(nodePos.position, neighbourPos.position); } } }