private void OnGUILogic() { _drawGraph = true; if (Selection.gameObjects.Count(g => g.GetComponent <UdonBehaviour>()) > 1) { _displayText = "Multi-object editing not supported"; _drawGraph = false; } else if (Selection.objects.Count(o => o != null && o is IUdonGraphDataProvider) > 1) // == typeof(UdonGraphProgramAsset) { _displayText = "Multi-object editing not supported"; _drawGraph = false; } IUdonGraphDataProvider udonGraphProgramAsset = (IUdonGraphDataProvider)Selection.objects.FirstOrDefault(g => g != null && g is IUdonGraphDataProvider); if (udonGraphProgramAsset == null) { GameObject behaviourObject = Selection.gameObjects.FirstOrDefault(g => g.GetComponent <UdonBehaviour>()); if (behaviourObject != null) { UdonBehaviour udonBehaviour = behaviourObject.GetComponent <UdonBehaviour>(); AbstractUdonProgramSource programSource = udonBehaviour.programSource; if (programSource is IUdonGraphDataProvider asUdonGraphProgramAsset) { udonGraphProgramAsset = asUdonGraphProgramAsset; } } } if (graph == null) { graph = CreateInstance <UdonGraph>(); } if (udonGraphProgramAsset != null) { if (graphGUI == null) { graphGUI = CreateInstance <UdonGraphGUI>(); graphGUI.graph = graph; } if (graph == null) { graph = CreateInstance <UdonGraph>(); graphGUI.graph = graph; } if (graph.graphProgramAsset == udonGraphProgramAsset) { if (graph.data != null) { return; } } graph.data = new UdonGraphData(udonGraphProgramAsset.GetGraphData()); graph.graphProgramAsset = udonGraphProgramAsset; graph.Reload(); graphGUI.CenterGraph(); } else { if (graph.graphProgramAsset != null) { return; } _displayText = "Create an Udon Graph Asset to begin."; _drawGraph = false; } }
private void OnGUILogic() { _drawGraph = true; if (Selection.gameObjects.Count(g => g.GetComponent <UdonBehaviour>()) > 1) { _displayText = "Multi-object editing not supported"; _drawGraph = false; } else if (Selection.objects.Count(o => o != null && o is IUdonGraphDataProvider) > 1) // == typeof(UdonGraphProgramAsset) { _displayText = "Multi-object editing not supported"; _drawGraph = false; } IUdonGraphDataProvider udonGraphProgramAsset = (IUdonGraphDataProvider)Selection.objects.FirstOrDefault(g => g != null && g is IUdonGraphDataProvider); if (udonGraphProgramAsset == null) { GameObject behaviourObject = Selection.gameObjects.FirstOrDefault(g => g.GetComponent <UdonBehaviour>()); if (behaviourObject != null) { UdonBehaviour udonBehaviour; var udonBehaviours = behaviourObject.GetComponents <UdonBehaviour>(); if (udonBehaviours.Length == 1 || lastClickedProgramSource == null) { udonBehaviour = udonBehaviours[0]; } else { udonBehaviour = udonBehaviours.FirstOrDefault(u => u.programSource == lastClickedProgramSource); if (udonBehaviour == null) { // the last clicked graph is not available on this object, reset it lastClickedProgramSource = null; udonBehaviour = udonBehaviours[0]; } } AbstractUdonProgramSource programSource = udonBehaviour.programSource; if (programSource is IUdonGraphDataProvider asUdonGraphProgramAsset) { udonGraphProgramAsset = asUdonGraphProgramAsset; } } } if (graph == null) { graph = CreateInstance <UdonGraph>(); } if (udonGraphProgramAsset != null) { if (graphGUI == null) { graphGUI = CreateInstance <UdonGraphGUI>(); graphGUI.graph = graph; } if (graph == null) { graph = CreateInstance <UdonGraph>(); graphGUI.graph = graph; } if (graph.graphProgramAsset == udonGraphProgramAsset) { if (graph.data != null) { return; } } titleContent = new GUIContent($"Udon - {udonGraphProgramAsset}"); graph.data = new UdonGraphData(udonGraphProgramAsset.GetGraphData()); graph.graphProgramAsset = udonGraphProgramAsset; graph.Reload(); graphGUI.CenterGraph(); } else { if (graph.graphProgramAsset != null) { return; } _displayText = "Create an Udon Graph Asset to begin."; _drawGraph = false; } }
public UdonNode CreateNode(UdonNodeData nodeData) { //Awful hack to fix regression in unity graph property type conversion { var prop = typeof(TypeConverter).GetField( "useCompatibleTypeConversion", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static ); prop.SetValue(this, true); } UdonNodeDefinition udonNodeDefinition = null; try { udonNodeDefinition = UdonEditorManager.Instance.GetNodeDefinition(nodeData.fullName); } catch { Debug.LogError($"Skipping missing node: {nodeData.fullName}"); return(null); } UdonNode node = CreateInstance <UdonNode>(); node.name = udonNodeDefinition.fullName; node.title = PrettyString(udonNodeDefinition.name).FriendlyNameify(); if (node.name.StartsWith("Event_") && node.name != "Event_Custom") { if (nodes.Any(n => n.name == node.name)) { Debug.LogWarning($"Can't create more than one {node.name} node, try managing your flow with a Block node instead!"); return(null); } } if (node.title == "Const_VRCUdonCommonInterfacesIUdonEventReceiver") { node.title = "UdonBehaviour"; } node.uid = nodeData.uid; node.position = new Rect(nodeData.position, Vector2.zero); if (udonNodeDefinition.flow) { if (!udonNodeDefinition.fullName.StartsWith("Event_")) { node.AddInputSlot(""); } node.AddOutputSlot(""); if (_specialFlows.Contains(udonNodeDefinition.fullName)) { node.AddOutputSlot(""); } if (udonNodeDefinition.fullName == "Block") { int connectedFlows = nodeData.flowUIDs.Count(f => !string.IsNullOrEmpty(f)); if (connectedFlows > 1) { for (int i = 0; i < connectedFlows - 1; i++) { node.AddOutputSlot(""); } } } } if (udonNodeDefinition.fullName == "SubGraph") { if (nodeData.nodeValues.Length > 0 && nodeData.nodeValues[0] != null) { IUdonGraphDataProvider graphDataProvider = (IUdonGraphDataProvider)nodeData.nodeValues[0].Deserialize(); if (graphDataProvider != null) { UdonGraphData subGraphData = graphDataProvider.GetGraphData(); bool doExit = false; foreach (UdonNodeData eventNode in subGraphData.EventNodes) { if (eventNode.fullName != "Event_Custom") { continue; } string customEventName = "customEvent"; if (eventNode.nodeValues.Length > 0 && eventNode.nodeValues[0] != null) { string eventName = (string)eventNode.nodeValues[0].Deserialize(); if (!string.IsNullOrEmpty(eventName)) { customEventName = eventName; } } node.AddInputSlot(customEventName); doExit = true; break; //TODO: support more than one custom event in a subgraph } if (doExit) { node.AddOutputSlot("Exit"); } } } } // Data Validation // bool modifiedData = false; for (int i = 0; i < nodeData.nodeValues.Length; i++) { if (udonNodeDefinition.inputs.Length <= i) { continue; } Type expectedType = udonNodeDefinition.inputs[i]; if (nodeData.nodeValues[i] == null) { continue; } object value = nodeData.nodeValues[i].Deserialize(); if (value == null) { continue; } if (!expectedType.IsInstanceOfType(value)) { nodeData.nodeValues[i] = SerializableObjectContainer.Serialize(null, expectedType); modifiedData = true; } } if (modifiedData) { ReSerializeData(); } //////////////////// foreach (Type input in udonNodeDefinition.inputs) { node.AddInputSlot(FriendlyTypeName(input), SlotTypeConverter(input, udonNodeDefinition.fullName)); } foreach (Type output in udonNodeDefinition.outputs) { node.AddOutputSlot(FriendlyTypeName(output), SlotTypeConverter(output, udonNodeDefinition.fullName)); } AddNode(node); return(node); }