public void GenerateDungeon(string _fileName) { if (!AssetDatabase.FindAssets($"{_fileName}", new[] { "Assets/Resources/FinalGraphs" }).Any()) { Debug.Log($"Caution! There is no graph with the name '{_fileName}' on the Resources/FinalGraphs folder"); return; } m_parent = new GameObject(); m_parent.name = "Dungeon " + _fileName; m_graphToLoad = Resources.Load <RoomInfoContainer>($"FinalGraphs/{_fileName}"); LoadRoomsInfo(); }
}//cargar info del grafico private void ExpandNonTerminalNodes()//expandir los nodos NO MARCADOS con isTerminal -> nodos Non-Terminal { if (m_graphView.nodes.ToList().Cast <RoomNode>().Where(x => x.isTerminal == false).Count() > 0) { foreach (RoomNode rn in m_graphView.nodes.ToList().Cast <RoomNode>().Where(x => x.isTerminal == false)) { if (rn.outputContainer.Q <Port>() == null) { m_resourcesRulesLoaded = Resources.LoadAll <RoomInfoContainer>("Rules").ToList(); //cargo todas las reglas disponibles if (m_resourcesRulesLoaded.Exists(x => x.name.Contains(rn.roomType))) //si existe una regla que contenga el nombre del nodo que quiero expandir; { RoomInfoContainer[] l_candidateRules = m_resourcesRulesLoaded.Where(x => x.name.Contains(rn.roomType)).ToArray(); //cojo las reglas que coincidan int l_randomRuleSelection = Random.Range(0, l_candidateRules.Length); //escojo una regla al azar RoomInfoContainer l_ruleToLoad = l_candidateRules[l_randomRuleSelection]; CreateExpandedNodes(l_ruleToLoad, rn); //expando el nodo dependiendo de la regla m_graphView.RemoveElement(rn); //elimino el nodo expandido para dejar sitio a los nuevos //elimino los edges que pertenezcan al nodo expandido foreach (Edge e in m_graphView.edges.ToList()) { if ((e.input.node as RoomNode) == rn) { m_graphView.RemoveElement(e); } } } else { Debug.Log($"The node '{rn.roomType}' you'r trying to expand doesn't have a rule specified"); } } else { Debug.Log("Non-terminal nodes must have 0 outputs (should be placed at the end of the graph)"); } } } else { Debug.Log("0 Nodes to expand found. Only non-terminal nodes can be expanded. You should dismark 'isTerminal' from any node to expand it"); } }
public void LoadGraph(string _fileName, bool isFinalGraph = false) { if (!isFinalGraph) { m_graphToLoadCache = Resources.Load <RoomInfoContainer>($"Rules/{_fileName}"); } else { m_graphToLoadCache = Resources.Load <RoomInfoContainer>($"FinalGraphs/{_fileName}"); } if (m_graphToLoadCache == null) { Debug.Log("Error, no existing Graph to load"); return; } ClearCurrentGraph(); CreateLoadedNodes(); ConnectLoadedNodes(); }
private void CreateExpandedNodes(RoomInfoContainer _graphToLoadCache, RoomNode roomToExpand) { List <RoomNode> l_newInstantiatedRoomsList = new List <RoomNode>(); foreach (RoomNodeData rData in _graphToLoadCache.m_roomNodeDataList) //para cada nodo en el nuevo grafico (la regla que acabo de cargar); { RoomNode l_tempRoom = m_graphView.CreateRoomNode(rData.nodeType, rData.isTerminal); //instancio el nodo l_newInstantiatedRoomsList.Add(l_tempRoom); //lo añado a la lista de "nuevas salas" l_tempRoom.roomID = rData.nodeID; //le asigno su ID m_graphView.AddElement(l_tempRoom); //añado el elemento al grafico //creo los puertos de entrada y salida que le tocan al nodo List <RoomNodeConnectionsData> l_tempOutRoomPorts = _graphToLoadCache.m_roomConnectionsDataList.Where(x => x.baseNodeId == rData.nodeID).ToList(); l_tempOutRoomPorts.ForEach(x => m_graphView.GenerateOutputPortsOnNode(l_tempRoom, x.basePortName)); List <RoomNodeConnectionsData> l_tempInputRoomPorts = _graphToLoadCache.m_roomConnectionsDataList.Where(x => x.targetNodeId == rData.nodeID).ToList(); l_tempInputRoomPorts.ForEach(x => m_graphView.GenerateInputPortsOnNode(l_tempRoom, x.targetPortName)); } for (int i = 0; i < l_newInstantiatedRoomsList.Count; i++)// para cada nodo que acabo de instanciar { //busco las conexiones que tiene List <RoomNodeConnectionsData> l_connectionDataCache = _graphToLoadCache.m_roomConnectionsDataList.Where(x => x.baseNodeId == l_newInstantiatedRoomsList[i].roomID).ToList(); for (int j = 0; j < l_connectionDataCache.Count; j++) { string l_targetNodeId = l_connectionDataCache[j].targetNodeId; //guardo el id del nodo target RoomNode l_targetRoom = l_newInstantiatedRoomsList.First(x => x.roomID == l_targetNodeId); //busco la sala que conicida con ese ID string l_targetPortName = l_connectionDataCache[j].targetPortName; //guardo el nombre del puerto target Port l_targetPortToConnect = m_graphView.ports.ToList().First(x => (x.node as RoomNode) == l_targetRoom && x.portName == l_targetPortName); //busco el puerto al que me tengo que conectar //si es un nodo 'begin', marco este nodo como el beginNodeInstantiated (en el begin node empieza la regla) -> sirve como referencia para saber donde empezar a conectar el puerto q quiero expandir if (l_newInstantiatedRoomsList[i].roomType == "begin") { m_beginNodeInstantiated = l_newInstantiatedRoomsList[i]; } //conecto el puerto del nodo [i] con el targetPort -> en este primer linkado asigno el tempEdge a una variable m_currentBeginNodeEdge //que luego me servira para encontrar el nodo conectado al nodo 'begin' LinkRoomPorts(l_newInstantiatedRoomsList[i].outputContainer[j].Q <Port>(), l_targetPortToConnect); //seteo su position basadome en la posicion del nodo expandido l_targetRoom.SetPosition(new Rect(_graphToLoadCache.m_roomNodeDataList.First(x => x.nodeID == l_targetRoom.roomID).position + roomToExpand.GetPosition().position, m_graphView.defaultNodeSize)); } //end for } //end of for loop //busco el puerto de entrada al que esta conectado la habitacion que quiero expandir Port l_basePort = m_graphView.edges.ToList().Find(x => (x.input.node as RoomNode) == roomToExpand).output; l_basePort.portColor = new Color(0, 0, 200);//blue //el puerto target será el que hemos marcado previamente al conectar los nodos de la regla que acabamos de cargar //el currentBeginNodeEdge es la conexion del nodo 'begin' -> cojemos el input, que es el puerto q pertenece al nodo 'begin' Port l_targetPort = m_currentBeginNodeEdge.input; l_targetPort.portColor = new Color(200, 0, 0); //red l_targetPort.portName = m_UtilitiesInstance.ReturnConnectionNameByReference(l_basePort.portName); //asignar el nuevo nombre del puerto dependiendo del puerto base conectado //elimino el nodo 'begin' -> solo sirve como referencia para saber donde conectar el nodo que queremos expandir m_graphView.RemoveElement(m_beginNodeInstantiated); //conecto los puertos LinkRoomPorts(l_basePort, l_targetPort); List <RoomNode> l_currentNodesOnGraph = m_graphView.nodes.ToList().Cast <RoomNode>().ToList(); //asignar nuevas id a cada nodo for (int i = 0; i < l_currentNodesOnGraph.Count; i++) { for (int j = 0; j < l_newInstantiatedRoomsList.Count(); j++) { if (l_currentNodesOnGraph[i] == l_newInstantiatedRoomsList[j]) { List <Edge> l_currentOutputRoomEdges = m_graphView.edges.ToList().Where(x => (x.output.node as RoomNode) == l_currentNodesOnGraph[i]).ToList(); List <Edge> l_currentInputRoomEdges = m_graphView.edges.ToList().Where(x => (x.input.node as RoomNode) == l_currentNodesOnGraph[i]).ToList(); string l_newRoomID = l_currentNodesOnGraph[i].roomID = System.Guid.NewGuid().ToString(); foreach (Edge e in l_currentOutputRoomEdges) { e.output.name = l_newRoomID; } foreach (Edge e in l_currentInputRoomEdges) { e.input.name = l_newRoomID; } } } } //end of for loop } //end expand nodes function
public void SaveGraph(string _fileName, bool isFinalGraph = false) { if (!m_roomsList.Any()) { Debug.Log("No nodes to save found"); return; } // si no hay rooms que guardar, no hacemos nada //evitar crear un nodo en el final graph que no exista en la lista de habitaciones if (isFinalGraph == true) { foreach (RoomNode roomNode in m_roomsList) { if (roomNode.roomType != "Start" && roomNode.roomType != "End" && !m_UtilitiesInstance.m_typesOfRoomsList.Exists(x => x.Contains(roomNode.roomType))) { Debug.Log($"Caution! The room type '{roomNode.roomType}' doesn't exist in the list of room prefabs. Change the node type or add a prefab to the dungeon generation list"); return; } } } Edge[] l_edgesConnected = m_edgesList.Where(x => x.output.node != null).ToArray(); foreach (Edge edge in l_edgesConnected) { if (!m_UtilitiesInstance.m_myConnectionsDictionary.ContainsKey(edge.output.portName)) { Debug.Log($"The connection name '{edge.output.portName}' doesn't appears in the Connections Dictionary (UtilitiesAndReferences Class). Please use a name from the Dictionary"); return; } } RoomInfoContainer l_nodeContainerData = ScriptableObject.CreateInstance <RoomInfoContainer>(); foreach (RoomNode r in m_roomsList)//guardamos cada nodo, su id, el tipo, y la posicion, { l_nodeContainerData.m_roomNodeDataList.Add(new RoomNodeData { nodeID = r.roomID, nodeType = r.roomType, position = r.GetPosition().position, isTerminal = r.isTerminal }); } for (int i = 0; i < l_edgesConnected.Length; i++) //para cada conexion del grafico, guardamos { RoomNode l_baseRoom = l_edgesConnected[i].output.node as RoomNode; //nodo de salida RoomNode l_targetRoom = l_edgesConnected[i].input.node as RoomNode; //nodo de entrada l_nodeContainerData.m_roomConnectionsDataList.Add(new RoomNodeConnectionsData { baseNodeId = l_baseRoom.roomID, targetNodeId = l_targetRoom.roomID, basePortName = l_edgesConnected[i].output.portName, targetPortName = m_UtilitiesInstance.ReturnConnectionNameByReference(l_edgesConnected[i].output.portName), } ); } if (!isFinalGraph) { if (!m_roomsList.Exists(x => x.roomType == "begin")) { Debug.Log("You need to create a 'begin'(NO capital 'b') node to save a Rule"); return; } else { if (m_roomsList.Find(x => x.roomType == "begin").outputContainer.childCount > 1) { Debug.Log("'begin' node must have only 1 output connection"); } else { AssetDatabase.CreateAsset(l_nodeContainerData, $"Assets/Resources/Rules/{_fileName}.asset");//generamos un asset con la informacion } } } else if (!m_roomsList.Exists(x => x.roomType == "Start")) { Debug.Log("You need to create a 'Start' (WITH capital 'S') node to save a FinalGraph"); return; } else { AssetDatabase.CreateAsset(l_nodeContainerData, $"Assets/Resources/FinalGraphs/{_fileName}.asset");//generamos un asset con la informacion } AssetDatabase.SaveAssets(); }