private void ConnectSelectedNodes(GraphwayConnectionTypes connectionType) { GameObject[] selectedObjects = Selection.gameObjects; // Get node IDs of connected nodes GraphwayNode graphwayNodeA = selectedObjects[0].GetComponent <GraphwayNode>(); GraphwayNode graphwayNodeB = selectedObjects[1].GetComponent <GraphwayNode>(); int nodeIDA = graphwayNodeA.nodeID; int nodeIDB = graphwayNodeB.nodeID; // NOTE - Nodes are connected by smallest node ID to largest node ID // Create connection if (nodeIDA < nodeIDB) { CreateConnectedNodeObj(nodeIDA, nodeIDB, connectionType); } else { CreateConnectedNodeObj(nodeIDB, nodeIDA, connectionType); } // Mark scene as dirty to trigger 'Save Changes' prompt EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); }
private void CreateConnectedNodeObj(int nodeIDA, int nodeIDB, GraphwayConnectionTypes connectionType) { if (!NodesAreConnected(nodeIDA, nodeIDB)) { GraphwayNode graphwayNodeData = (GraphwayNode)target; Graphway graphway = GraphwayEditor.FindGraphwayParent(graphwayNodeData.transform); GameObject newConnection = new GameObject(); newConnection.name = nodeIDA.ToString() + "->" + nodeIDB.ToString(); newConnection.transform.parent = graphway.transform.Find("Connections").transform; newConnection.AddComponent <GraphwayConnection>().SetConnectionData(nodeIDA, nodeIDB, connectionType); // Register undo operation Undo.RegisterCreatedObjectUndo(newConnection, "Graphway Connection"); // Reorder connection hierarchy to keep things tidy ReorderConnections(); } }
public static void DrawGraph(Transform transform) { Graphway graphway = FindGraphwayParent(transform); if (graphway != null) { // Check integrity of Graphway structure CheckHierarchyIntegrity(graphway); // Enable node renderers EnableRenderers(graphway.transform); // Draw NODES foreach (Transform node in graphway.transform.Find("Nodes").transform) { node.GetComponent <Renderer>().sharedMaterial.color = graphway.nodeColor; node.localScale = new Vector3(graphway.nodeSize, graphway.nodeSize, graphway.nodeSize); CreateLabel(node.position, graphway.nodeSize, NODE_FONT_SIZE, graphway.nodeColor, node.name); } // Draw CONNECTION & SUBNODES foreach (Transform connection in graphway.transform.Find("Connections").transform) { // Get node IDs of connected nodes int nodeIDA = connection.GetComponent <GraphwayConnection>().nodeIDA; int nodeIDB = connection.GetComponent <GraphwayConnection>().nodeIDB; bool isDisabled = connection.GetComponent <GraphwayConnection>().disabled; GraphwayConnectionTypes connectionType = connection.GetComponent <GraphwayConnection>().connectionType; // Set positions of connected nodes Vector3 nodeAPosition = graphway.transform.Find("Nodes/" + nodeIDA).position; Vector3 nodeBPosition = graphway.transform.Find("Nodes/" + nodeIDB).position; Vector3 lastPosition = nodeAPosition; // Check if connection uses subnodes if (connection.childCount > 0) { foreach (Transform subnode in connection.transform) { // Create subnode subnode.GetComponent <Renderer>().sharedMaterial.color = graphway.subnodeColor; subnode.localScale = new Vector3(graphway.subnodeSize, graphway.subnodeSize, graphway.subnodeSize); CreateLabel(subnode.position, graphway.subnodeSize, SUBNODE_FONT_SIZE, graphway.subnodeColor, subnode.name); // Draw connection to first node or previous subnode Handles.color = (subnode.GetSiblingIndex() == 0 ? graphway.nodeColor : graphway.subnodeColor ); // Check if connection is unidirectional // If so draw an arrow to indicate direction of allowed movement if (connectionType == GraphwayConnectionTypes.UnidirectionalAToB) { Vector3 arrowPosition = (subnode.position + lastPosition) / 2; Vector3 relativePos = subnode.position - lastPosition; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } else if (connectionType == GraphwayConnectionTypes.UnidirectionalBToA) { Vector3 arrowPosition = (subnode.position + lastPosition) / 2; Vector3 relativePos = lastPosition - subnode.position; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } // Draw a line to complete the connection if (isDisabled) { Handles.DrawDottedLine(lastPosition, subnode.position, 4); } else { Handles.DrawLine(lastPosition, subnode.position); } // Step forward to next subnode/node lastPosition = subnode.position; } } // Draw connection to remaining node Handles.color = graphway.nodeColor; // Check if connection is unidirectional // If so display arrow showing which direction if (connectionType == GraphwayConnectionTypes.UnidirectionalAToB) { Vector3 arrowPosition = (nodeBPosition + lastPosition) / 2; Vector3 relativePos = nodeBPosition - lastPosition; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } else if (connectionType == GraphwayConnectionTypes.UnidirectionalBToA) { Vector3 arrowPosition = (nodeBPosition + lastPosition) / 2; Vector3 relativePos = lastPosition - nodeBPosition; Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up); Handles.ConeHandleCap(0, arrowPosition, rotation, graphway.arrowSize, EventType.Repaint); } // Draw a line to complete the connection if (isDisabled) { Handles.DrawDottedLine(lastPosition, nodeBPosition, 4); } else { Handles.DrawLine(lastPosition, nodeBPosition); } } } }
public int editorSubnodeCounter = 0; // Keep public so value is saved upon editor close public void SetConnectionData(int nodeIDA, int nodeIDB, GraphwayConnectionTypes connectionType) { this.nodeIDA = nodeIDA; this.nodeIDB = nodeIDB; this.connectionType = connectionType; }