/// <summary> /// Generate debug code. /// </summary> /// <param name="member"></param> /// <param name="value"></param> /// <param name="isSet"></param> /// <returns></returns> public static string GenerateDebugCode(MemberData member, string value, bool isSet = false) { if (!member.isAssigned) { return(null); } if (member.targetType != MemberData.TargetType.FlowNode && member.targetType != MemberData.TargetType.ValueNode && member.targetType != MemberData.TargetType.FlowInput) { return(null); } string data = setting.debugPreprocessor ? "\n#if UNITY_EDITOR" : ""; if (member.targetType == MemberData.TargetType.FlowNode) { data += GenerateInvokeCode(typeof(uNodeUtility), nameof(uNodeUtility.InvokeFlowTransition), "this", ParseValue(uNodeUtility.GetObjectID(graph)), ParseValue(uNodeUtility.GetObjectID(member.GetInstance() as UnityEngine.Object)), ParseValue(int.Parse(member.startName))).AddLineInFirst(); } else if (member.targetType == MemberData.TargetType.ValueNode) { data += GenerateInvokeCode(typeof(uNodeUtility), nameof(uNodeUtility.InvokeValueTransition), "this", ParseValue(uNodeUtility.GetObjectID(graph)), ParseValue(uNodeUtility.GetObjectID(member.GetInstance() as UnityEngine.Object)), ParseValue(int.Parse(member.startName)), value, ParseValue(isSet)).AddLineInFirst(); } else { throw new System.NotSupportedException("Target type is not supported to generate debug code"); } if (setting.debugPreprocessor) { data += "#endif".AddLineInFirst(); } return(data); }
public void SelectConnectedNode(Component from, bool allConnection = false, Action <NodeComponent> callbackAction = null) { if (from == null) { return; } if (from is BaseEventNode) { BaseEventNode method = from as BaseEventNode; var flows = method.GetFlows(); foreach (var n in flows) { if (n == null || n.GetTargetNode() == null) { continue; } if (!editorData.selectedNodes.Contains(n.GetTargetNode())) { editorData.selectedNodes.Add(n.GetTargetNode()); editorData.selected = editorData.selectedNodes; if (allConnection) { SelectConnectedNode(n.GetTargetNode(), allConnection, callbackAction); } SelectionChanged(); if (callbackAction != null) { callbackAction(n.GetTargetNode()); } } } } else if (from is Node) { Node node = from as Node; if (node as StateNode) { StateNode eventNode = node as StateNode; TransitionEvent[] TE = eventNode.GetTransitions(); foreach (TransitionEvent T in TE) { if (T.GetTargetNode() != null) { if (!editorData.selectedNodes.Contains(T.GetTargetNode())) { editorData.selectedNodes.Add(T.GetTargetNode()); editorData.selected = editorData.selectedNodes; if (allConnection) { SelectConnectedNode(T.GetTargetNode(), allConnection, callbackAction); } SelectionChanged(); if (callbackAction != null) { callbackAction(T.GetTargetNode()); } } } } } Func <object, bool> validation = delegate(object o) { if (o is MemberData) { MemberData member = o as MemberData; if (member.targetType == MemberData.TargetType.FlowNode || member.targetType == MemberData.TargetType.ValueNode) { Node n = member.GetInstance() as Node; if (member.isAssigned && member.GetInstance() is Node) { if (!editorData.selectedNodes.Contains(n)) { editorData.selectedNodes.Add(n); editorData.selected = editorData.selectedNodes; if (allConnection) { SelectConnectedNode(n, allConnection, callbackAction); } SelectionChanged(); if (callbackAction != null) { callbackAction(n); } } //return true; } } } return(false); }; AnalizerUtility.AnalizeObject(node, validation); } }
public void PasteNode(Vector3 position) { if (nodeToCopy == null || nodeToCopy.Count == 0) { return; } if (uNodeEditorUtility.IsPrefab(editorData.graph.gameObject)) { throw new Exception("Editing graph prefab dirrectly is not supported."); } uNodeEditorUtility.RegisterUndo(editorData.graph, "Paste Node"); uNodeRoot UNR = editorData.graph; float progress = 0; int loopIndex = 0; if (nodeToCopy.Count > 5) { EditorUtility.DisplayProgressBar("Loading", "", progress); } Vector2 center = Vector2.zero; int centerLength = 0; Dictionary <uNodeComponent, uNodeComponent> CopyedObjectMap = new Dictionary <uNodeComponent, uNodeComponent>(EqualityComparer <uNodeComponent> .Default); foreach (uNodeComponent comp in nodeToCopy) { if (comp == null || comp is EventNode && editorData.selectedGroup != null) { continue; } Node node = comp as Node; if (!CopyedObjectMap.ContainsKey(comp)) { uNodeComponent com = Object.Instantiate(comp); com.gameObject.name = com.gameObject.name.Replace("(Clone)", ""); if (editorData.selectedGroup == null) { if (editorData.selectedRoot) { com.transform.parent = editorData.selectedRoot.transform; } else { com.transform.parent = NodeEditorUtility.GetNodeRoot(UNR).transform; } } else { com.transform.parent = editorData.selectedGroup.transform; } int index = 0; string nm = com.gameObject.name.TrimEnd(numberChar); while (true) { bool flag = false; string gName = com.gameObject.name; foreach (Transform t in com.transform.parent) { if (t != com.transform) { if (t.gameObject.name.Equals(gName)) { flag = true; break; } } } if (flag) { com.gameObject.name = nm + index.ToString(); index++; continue; } break; } CopyedObjectMap.Add(comp, com); if (comp is IMacro || comp is ISuperNode) { var fields = EditorReflectionUtility.GetFields(comp.GetType()); foreach (var field in fields) { if (field.FieldType == typeof(List <Nodes.MacroPortNode>)) { var value = field.GetValueOptimized(comp) as List <Nodes.MacroPortNode>; if (value != null) { var sourceValue = field.GetValueOptimized(com) as List <Nodes.MacroPortNode>; for (int i = 0; i < value.Count; i++) { if (value[i] == null) { continue; } CopyedObjectMap.Add(value[i], sourceValue[i]); } } } } } } if (node != null) { center.x += node.editorRect.x; center.y += node.editorRect.y; centerLength++; } else { BaseEventNode met = comp as BaseEventNode; if (met != null) { center.x += met.editorRect.x; center.y += met.editorRect.y; centerLength++; } } loopIndex++; progress = (float)loopIndex / (float)nodeToCopy.Count; if (nodeToCopy.Count > 5) { EditorUtility.DisplayProgressBar("Loading", "", progress); } } progress = 0; center /= centerLength; HashSet <uNodeComponent> needReflectedComponent = new HashSet <uNodeComponent>(); uNodeRoot compEvent = null; foreach (uNodeComponent com in nodeToCopy) { uNodeComponent comp = null; if (CopyedObjectMap.ContainsKey(com)) { comp = CopyedObjectMap[com]; if (comp == null) { loopIndex++; progress = (float)loopIndex / (float)nodeToCopy.Count; if (nodeToCopy.Count > 5) { EditorUtility.DisplayProgressBar("Loading", "", progress); } continue; } if (comp as Node) { Node node = comp as Node; Func <object, bool> validation = delegate(object o) { if (o is MemberData) { MemberData member = o as MemberData; if (member.IsTargetingPinOrNode) { NodeComponent n = member.GetInstance() as NodeComponent; if (n && n is uNodeComponent) { if (CopyedObjectMap.ContainsKey(n)) { member.instance = CopyedObjectMap[n] as NodeComponent; n.owner = UNR; return(true); } else if (n.owner != UNR || n.transform.parent != node.transform.parent) { member.instance = null; n.owner = UNR; return(true); } //return true; } } } return(false); }; if (node as StateNode) { StateNode eventNode = node as StateNode; TransitionEvent[] TE = eventNode.GetTransitions(); foreach (TransitionEvent n in TE) { var tn = n.GetTargetNode(); if (tn == null) { continue; } if (CopyedObjectMap.ContainsKey(tn)) { n.target = MemberData.CreateConnection(CopyedObjectMap[tn] as Node, true); n.owner = UNR; } else if (n.owner != UNR || tn != null && tn.owner != UNR || tn != null && tn.transform.parent != node.transform.parent) { n.target = MemberData.none; n.owner = UNR; } } } else if (node is IMacro || node is ISuperNode) { var fields = EditorReflectionUtility.GetFields(comp.GetType()); foreach (var field in fields) { if (field.FieldType == typeof(List <Nodes.MacroPortNode>)) { var value = field.GetValueOptimized(comp) as List <Nodes.MacroPortNode>; if (value != null) { foreach (var v in value) { AnalizerUtility.AnalizeObject(v, validation); } } } } } AnalizerUtility.AnalizeObject(node, validation); node.editorRect = new Rect(node.editorRect.x - center.x + position.x, node.editorRect.y - center.y + position.y, node.editorRect.width, node.editorRect.height); if (node.owner != UNR) { node.owner = UNR; } } else if (comp is BaseEventNode) { BaseEventNode method = comp as BaseEventNode; var flows = method.GetFlows(); for (int i = 0; i < flows.Count; i++) { var tn = flows[i].GetTargetNode(); if (tn != null && CopyedObjectMap.ContainsKey(tn)) { flows[i] = new MemberData(CopyedObjectMap[flows[i].GetTargetNode()], MemberData.TargetType.FlowNode); } else if (method.owner != UNR) { flows[i] = MemberData.none; } } method.owner = UNR; method.editorRect = new Rect(method.editorRect.x - center.x + position.x, method.editorRect.y - center.y + position.y, method.editorRect.width, method.editorRect.height); } } loopIndex++; progress = (float)loopIndex / (float)nodeToCopy.Count; if (nodeToCopy.Count > 5) { EditorUtility.DisplayProgressBar("Loading", "", progress); } } if (nodeToCopy.Count > 5) { EditorUtility.ClearProgressBar(); } if (needReflectedComponent.Count > 0) { NodeEditorUtility.PerformReflectComponent(needReflectedComponent.ToList(), compEvent, UNR); } foreach (KeyValuePair <uNodeComponent, uNodeComponent> keys in CopyedObjectMap) { if (keys.Value != null) { Undo.RegisterCreatedObjectUndo(keys.Value.gameObject, "Paste Node"); } } //allCopyedEvent.Clear(); Refresh(); }
/// <summary> /// True if group node has instance variable. /// </summary> /// <param name="groupNode"></param> /// <returns></returns> public static bool NeedInstanceVariable <T>(T superNode) where T : ISuperNode { if (superNode != null) { var flows = new HashSet <NodeComponent>(); foreach (var n in superNode.nestedFlowNodes) { FindFlowConnectionAfterCoroutineNode(n, ref flows); } bool check = false; Func <object, bool> validation = null; validation = delegate(object obj) { if (obj is MemberData) { MemberData member = obj as MemberData; Node n = member.GetInstance() as Node; if (n != null) { if (n is IVariableSystem && n is T && n == superNode as UnityEngine.Object && (member.targetType == MemberData.TargetType.uNodeVariable || member.targetType == MemberData.TargetType.uNodeGroupVariable || member.targetType == MemberData.TargetType.uNodeLocalVariable)) { check = true; } else if (member.targetType == MemberData.TargetType.ValueNode) { AnalizerUtility.AnalizeObject(n, validation); } } } return(check); }; foreach (Node node in flows) { if (node == null) { continue; } AnalizerUtility.AnalizeObject(node, validation); if (check) { return(true); } } var allConnection = new HashSet <NodeComponent>(); foreach (var n in superNode.nestedFlowNodes) { FindAllNodeConnection(n, ref allConnection); } foreach (Node node in allConnection) { if (node == null) { continue; } AnalizerUtility.AnalizeObject(node, validation); if (check) { var nodes = GetFlowConnectedTo(node); if (nodes.Count > 0) { if (nodes.Any(n => !flows.Contains(n))) { return(true); } } if ((generatorData.ungroupedNode.Contains(node) || generatorData.portableActionInNode.Contains(node))) { return(true); } } } } return(false); }
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(); }