/// <summary> /// Get the graph singleton instance /// </summary> /// <param name="graphSingleton"></param> /// <returns></returns> internal static uNodeRuntime GetRuntimeGraph(uNodeComponentSingleton graphSingleton) { uNodeRuntime instance; if (!graphSingletons.TryGetValue(graphSingleton, out instance) || instance == null) { var objs = GameObject.FindObjectsOfType <uNodeRuntime>(); instance = objs.FirstOrDefault(g => g.GraphName == graphSingleton.GraphName); if (instance == null) { GameObject mainObject = new GameObject($"[Singleton:{graphSingleton.GraphName}]"); if (graphSingleton.IsPersistence) { GameObject.DontDestroyOnLoad(mainObject); } uNodeRoot graph = UnityEngine.Object.Instantiate(graphSingleton); uNodeRuntime main = mainObject.AddComponent <uNodeRuntime>(); main.originalGraph = graphSingleton; main.Name = graphSingleton.GraphName; //This will ensure the uid is valid main.Variables = graph.Variables; main.RootObject = graph.RootObject; main.RootObject.transform.SetParent(mainObject.transform); AnalizerUtility.RetargetNodeOwner(graph, main, main.RootObject.GetComponentsInChildren <MonoBehaviour>(true)); main.Refresh(); UnityEngine.Object.Destroy(graph.gameObject); instance = main; graphSingletons[instance] = instance; } } return(instance); }
/// <summary> /// Save the runtime graph to a prefab /// </summary> /// <param name="runtimeGraph"></param> /// <param name="graphAsset"></param> public static void SaveRuntimeGraph(uNodeRuntime runtimeGraph) { if (!Application.isPlaying) { throw new System.Exception("Saving runtime graph can only be done in playmode"); } if (runtimeGraph.originalGraph == null) { throw new System.Exception("Cannot save runtime graph because the original graph was null / missing"); } var graph = runtimeGraph.originalGraph; if (!EditorUtility.IsPersistent(graph)) { throw new System.Exception("Cannot save graph to unpersistent asset"); } var prefabContent = PrefabUtility.LoadPrefabContents(AssetDatabase.GetAssetPath(graph)); var originalGraph = uNodeHelper.GetGraphComponent(prefabContent, graph.GraphName); if (originalGraph != null) { if (runtimeGraph.RootObject != null) { //Duplicate graph data var tempRoot = Object.Instantiate(runtimeGraph.RootObject); tempRoot.name = "Root"; //Move graph data to original graph tempRoot.transform.SetParent(originalGraph.transform); //Retarget graph data owner AnalizerUtility.RetargetNodeOwner(runtimeGraph, originalGraph, tempRoot.GetComponentsInChildren <MonoBehaviour>(true)); if (originalGraph.RootObject != null) { //Destroy old graph data Object.DestroyImmediate(originalGraph.RootObject); } //Update graph data to new originalGraph.RootObject = tempRoot; //Save the graph to prefab uNodeEditorUtility.SavePrefabAsset(prefabContent, graph); //GraphUtility.DestroyTempGraphObject(originalGraph.gameObject); //This will update the original graph GraphUtility.DestroyTempGraphObject(graph.gameObject); //Refresh uNode Editor window uNodeEditor.window?.Refresh(); } } else { Debug.LogError("Cannot save instanced graph because the cannot find original graph with id:" + graph.GraphName); } PrefabUtility.UnloadPrefabContents(prefabContent); }
public override uNodeRoot Convert(uNodeRoot graph) { var cls = Object.Instantiate(graph); var gameObject = new GameObject("Converted Graph"); var result = gameObject.AddComponent <uNodeRuntime>(); result.Name = cls.Name; result.Variables.Clear(); foreach (var v in cls.Variables) { result.Variables.Add(new VariableData(v)); } result.RootObject = cls.RootObject; if (result.RootObject != null) { result.RootObject.transform.SetParent(gameObject.transform); AnalizerUtility.RetargetNodeOwner(cls, result, result.RootObject.GetComponentsInChildren <MonoBehaviour>(true)); } Object.DestroyImmediate(cls.gameObject); result.Refresh(); ValidateGraph(result, supportAttribute: false, supportGeneric: false, supportModifier: false, supportNativeType: false, supportConstructor: false); return(result); }
public override uNodeRoot Convert(uNodeRoot graph) { var cls = Object.Instantiate(graph); var gameObject = new GameObject("Converted Graph"); var result = gameObject.AddComponent <uNodeClass>(); result.Name = cls.Name; result.Variables.Clear(); foreach (var v in cls.Variables) { result.Variables.Add(new VariableData(v)); } result.inheritFrom = new MemberData(cls.GetInheritType()); result.RootObject = cls.RootObject; if (result.RootObject != null) { result.RootObject.transform.SetParent(gameObject.transform); AnalizerUtility.RetargetNodeOwner(cls, result, result.RootObject.GetComponentsInChildren <MonoBehaviour>(true)); } Object.DestroyImmediate(cls.gameObject); result.Refresh(); return(result); }
public void InitMacroPort(IMacroPort port) { if (port == null) { return; } if (m_port == null) { m_port = port; } if (m_port == port) // Make sure to init macro only one times. { Refresh(); if (CodeGenerator.isGenerating) { foreach (VariableData variable in variables) { variable.modifier.SetPrivate(); CodeGenerator.AddVariable(variable); } m_generatedVariable = new List <VariableData>(); //Ensure to register default variable from macro graph var macroVariable = macroAsset.Variables; foreach (var variable in macroVariable) { if (!variables.Any(v => v.Name == variable.Name)) { var tmpVar = new VariableData(variable); tmpVar.modifier.SetPrivate(); CodeGenerator.AddVariable(tmpVar); m_generatedVariable.Add(tmpVar); } } } if (macroAsset != null) { if (CodeGenerator.isGenerating || Application.isPlaying) { if (runtimeMacro != null) { DestroyImmediate(runtimeMacro.gameObject); } runtimeMacro = uNodeUtility.TempManagement.CreateTempObject(macroAsset); var behaviors = runtimeMacro.RootObject.GetComponentsInChildren <MonoBehaviour>(true); AnalizerUtility.RetargetNodeOwner(runtimeMacro, owner, behaviors, (obj) => { MemberData member = obj as MemberData; if (member != null && member.targetType == MemberData.TargetType.uNodeVariable && GetVariableData(member.startName) != null) { member.RefactorUnityObject(new Object[] { runtimeMacro }, new Object[] { this }); } }); Dictionary <int, MacroPortNode> portMap = new Dictionary <int, MacroPortNode>(); foreach (var p in inputFlows) { if (p != null && p.linkedPort != null) { portMap[p.linkedPort.port.transform.GetSiblingIndex()] = p; } } foreach (var p in inputValues) { if (p != null && p.linkedPort != null) { portMap[p.linkedPort.port.transform.GetSiblingIndex()] = p; } } foreach (var p in outputFlows) { if (p != null && p.linkedPort != null) { portMap[p.linkedPort.port.transform.GetSiblingIndex()] = p; } } foreach (var p in outputValues) { if (p != null && p.linkedPort != null) { portMap[p.linkedPort.port.transform.GetSiblingIndex()] = p; } } foreach (Transform t in runtimeMacro.RootObject.transform) { var comp = t.GetComponent <Node>(); if (comp != null) { comp.parentComponent = this; var p = comp as MacroPortNode; MacroPortNode originP; if (portMap.TryGetValue(t.GetSiblingIndex(), out originP)) { switch (originP.kind) { case PortKind.FlowInput: case PortKind.ValueOutput: originP.target = new MemberData(p.target); break; case PortKind.FlowOutput: case PortKind.ValueInput: p.target = new MemberData(originP.target); break; } } } } runtimeMacro.SetLinkedOwner(owner); //Make sure all get/set property will be liked to actual owner. if (CodeGenerator.isGenerating) { foreach (var b in behaviors) { if (b is NodeComponent) { CodeGenerator.RegisterAsGroupedNode(b as NodeComponent); } } } } } } }
public override void OnClick(Node source, Vector2 mousePosition) { MacroNode node = source as MacroNode; string path = EditorUtility.SaveFilePanelInProject("Export to macro asset", "New Macro.prefab", "prefab", "Please enter a file name to save the macro to"); if (path.Length != 0) { Undo.RegisterFullObjectHierarchyUndo(node, ""); Undo.RegisterFullObjectHierarchyUndo(node.owner, ""); var tmpMacro = Object.Instantiate(node); GameObject go = new GameObject("New Macro"); var macro = go.AddComponent <uNodeMacro>(); macro.Variables.AddRange(tmpMacro.Variables); if (macro.RootObject == null) { macro.RootObject = new GameObject("Root"); macro.RootObject.transform.SetParent(macro.transform); } var behaviors = tmpMacro.GetComponentsInChildren <MonoBehaviour>(true); AnalizerUtility.RetargetNodeOwner(tmpMacro.owner, macro, behaviors, (obj) => { MemberData member = obj as MemberData; if (member != null && member.targetType == MemberData.TargetType.uNodeVariable && member.GetInstance() as Object == tmpMacro) { member.RefactorUnityObject(new Object[] { tmpMacro }, new Object[] { macro }); } }); for (int i = 0; i < tmpMacro.transform.childCount; i++) { tmpMacro.transform.GetChild(i).SetParent(macro.RootObject.transform); i--; } macro.Refresh(); #if UNITY_2018_3_OR_NEWER GameObject prefab = PrefabUtility.SaveAsPrefabAsset(go, path); #else GameObject prefab = PrefabUtility.CreatePrefab(path, go); #endif AssetDatabase.SaveAssets(); Object.DestroyImmediate(go); Object.DestroyImmediate(tmpMacro.gameObject); var macroAsset = prefab.GetComponent <uNodeMacro>(); NodeEditorUtility.AddNewNode(graph.editorData, null, null, mousePositionOnCanvas, (LinkedMacroNode n) => { n.macroAsset = macroAsset; n.editorRect = node.editorRect; NodeEditorUtility.AddNewObject(graph.editorData.graph, "pins", n.transform, (pin) => { n.pinObject = pin; n.Refresh(); RefactorUtility.RetargetNode(node, n); if (n.inputFlows.Count == node.inputFlows.Count) { for (int i = 0; i < n.inputFlows.Count; i++) { RefactorUtility.RetargetNode(node.inputFlows[i], n.inputFlows[i]); } } if (n.inputValues.Count == node.inputValues.Count) { for (int i = 0; i < n.inputValues.Count; i++) { n.inputValues[i].target = new MemberData(node.inputValues[i].target); } } if (n.outputFlows.Count == node.outputFlows.Count) { for (int i = 0; i < n.outputFlows.Count; i++) { n.outputFlows[i].target = new MemberData(node.outputFlows[i].target); } } if (n.outputValues.Count == node.outputValues.Count) { for (int i = 0; i < n.outputValues.Count; i++) { RefactorUtility.RetargetNode(node.outputValues[i], n.outputValues[i]); } } }); }); NodeEditorUtility.RemoveNode(graph.editorData, node); } graph.Refresh(); }