private void LayoutSlots(UdonNodeDefinition udonNodeDefinition, UdonNode node, int connectedFlowCount) { //Layout Flow Slots 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 = connectedFlowCount; if (connectedFlows > 1) { for (int i = 0; i < connectedFlows - 1; i++) { node.AddOutputSlot(""); } } } } //Layout InOut Slots for (int index = 0; index < udonNodeDefinition.Inputs.Count; index++) { UdonNodeParameter input = udonNodeDefinition.Inputs[index]; string label = ""; if (udonNodeDefinition.Inputs.Count > index && index >= 0) { label = udonNodeDefinition.Inputs[index].name; } if (label == "IUdonEventReceiver") { label = "UdonBehaviour"; } label = label.FriendlyNameify(); Slot slot = node.AddInputSlot(FriendlyTypeName(input.type), SlotTypeConverter(input.type, udonNodeDefinition.fullName)); slot.title = label; } foreach (UdonNodeParameter output in udonNodeDefinition.Outputs) { node.AddOutputSlot(FriendlyTypeName(output.type), SlotTypeConverter(output.type, udonNodeDefinition.fullName)); } }
public void Reload() { if (this == null) { DestroyImmediate(this); return; } Reloading = true; // ReSharper disable once DelegateSubtraction Undo.undoRedoPerformed -= OnUndoRedo; //Remove old handler if present to prevent duplicates, doesn't cause errors if not present Undo.undoRedoPerformed += OnUndoRedo; nodes.Clear(); edges.Clear(); IEnumerable <UdonNodeDefinition> definitions = UdonEditorManager.Instance.GetNodeDefinitions(); if (definitions == null || definitions.Count() < 100) { throw new NullReferenceException("Udon NodeDefinitions have failed to load, aborting graph load."); } for (int i = data.nodes.Count - 1; i >= 0; i--) { UdonNodeData node = data.nodes[i]; UdonNode udonNode = CreateNode(node); if (udonNode != null) { continue; } Debug.Log($"Removing null node '{node.fullName}'"); data.nodes.RemoveAt(i); } foreach (Node node in nodes) { UdonNode udonNode = (UdonNode)node; udonNode.PopulateEdges(); } Reloading = false; ReSerializeData(); }
public void UpdateNodePosition(UdonNode node) { data.FindNode(node.uid).position = node.position.position; ReSerializeData(); }
private bool TrySetupNode(UdonNodeDefinition udonNodeDefinition, Vector2?position, out UdonNode node, ref UdonNodeData nodeData) { DoPropHack(); if (!TryCreateNodeInstance(out node)) { return(false); } if (nodeData == null) { nodeData = data.AddNode(udonNodeDefinition.fullName); } node.uid = nodeData.uid; return(true); void DoPropHack() { //Awful hack to fix regression in unity graph property type conversion { FieldInfo prop = typeof(TypeConverter).GetField( "useCompatibleTypeConversion", BindingFlags.NonPublic | BindingFlags.Static ); if (prop != null) { prop.SetValue(this, true); } } } bool TryCreateNodeInstance(out UdonNode outNode) { outNode = CreateInstance <UdonNode>(); outNode.name = udonNodeDefinition.fullName; outNode.title = PrettyString(udonNodeDefinition.name).FriendlyNameify(); outNode.position = position == null ? new Rect(Vector2.zero, Vector2.zero) : new Rect(position.Value, Vector2.zero); string nodeName = outNode.name; if (nodeName.StartsWith("Event_") && (nodeName != "Event_Custom" || graphProgramAsset.GetType() == typeof(UdonSubGraphAsset))) { if (nodes.Any(n => n.name == nodeName)) { Debug.LogWarning( $"Can't create more than one {nodeName} node, try managing your flow with a Block node instead!"); return(false); } } if (nodeName.StartsWith("Event_") && (nodeName != "Event_Custom" && graphProgramAsset.GetType() == typeof(UdonSubGraphAsset))) { Debug.LogWarning($"SubGraphs can't use built-in events, pipe in your event from the parent graph instead!"); return(false); } if (outNode.title == "Const_VRCUdonCommonInterfacesIUdonEventReceiver") { outNode.title = "UdonBehaviour"; } return(true); } }