private void Initialize(UnityEngine.Object target) { data = new RefactorData(); GameObject gameObject = target as GameObject; if (target is Component) { gameObject = (target as Component).gameObject; } if (gameObject != null) { var scripts = gameObject.GetComponentsInChildren <MonoBehaviour>(true); Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null) { FindMissingMember(member, false); } return(false); }; Array.ForEach(scripts, script => { data.missingTarget.Add(script); AnalizerUtility.AnalizeObject(script, scriptValidation); }); } }
/// <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); }
private void Initialize() { data = new RefactorData(); var graphPrefabs = uNodeEditorUtility.FindPrefabsOfType <uNodeRoot>(); foreach (var prefab in graphPrefabs) { var gameObject = prefab; if (GraphUtility.HasTempGraphObject(prefab)) { gameObject = GraphUtility.GetTempGraphObject(prefab); } var scripts = gameObject.GetComponentsInChildren <MonoBehaviour>(true); Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null) { FindMissingMember(member, false); } return(false); }; Array.ForEach(scripts, script => { data.missingTarget.Add(script); AnalizerUtility.AnalizeObject(script, scriptValidation); }); } }
/// <summary> /// True if instance variable from node has used in flow nodes. /// </summary> /// <param name="from"></param> /// <param name="field"></param> /// <param name="index"></param> /// <param name="flows"></param> /// <returns></returns> public static bool NeedInstanceVariable(Node from, FieldInfo field, int index, IList <Node> flows) { if (from && flows != null && flows.Count > 0) { var allConnection = GetAllNode(from.transform.parent); var allFlows = new HashSet <NodeComponent>(); foreach (var flow in flows) { if (flow == null) { continue; } FindAllNodeConnection(flow, ref allFlows); } bool check = false; Func <object, bool> validation = null; validation = delegate(object obj) { if (obj is MemberData) { MemberData member = obj as MemberData; if (member.isAssigned) { Node n = member.GetTargetNode(); if (n) { int tes; if (member.targetType == MemberData.TargetType.NodeFieldElement && n == from && int.TryParse(member.startName.Split('#')[1], out tes) && tes == index && member.startName.Split('#')[0] == field.Name) { check = true; } else if (member.targetType == MemberData.TargetType.ValueNode) { AnalizerUtility.AnalizeObject(n, validation); } } } } return(check); }; foreach (Node node in allConnection) { if (node == null || !isInUngrouped && IsGroupedNode(from) /*&& allFlows.Contains(node)*/) { continue; } AnalizerUtility.AnalizeObject(node, validation); if (check) { var nodes = GetFlowConnectedTo(node); if (nodes.Count > 0) { return(nodes.Any(n => !allFlows.Contains(n))); } } } } return(false); }
/// <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 static HashSet <NodeComponent> GetConnections(NodeComponent node) { HashSet <NodeComponent> allNodes; if (generatorData.nodeConnectionsMap.TryGetValue(node, out allNodes)) { return(allNodes); } allNodes = new HashSet <NodeComponent>(); if (node is StateNode) { StateNode eventNode = node as StateNode; TransitionEvent[] TE = eventNode.GetTransitions(); foreach (TransitionEvent transition in TE) { var tNode = transition.GetTargetNode(); if (tNode != null) { allNodes.Add(tNode); } } } else if (node is BaseEventNode) { BaseEventNode stateEvent = node as BaseEventNode; foreach (var member in stateEvent.GetFlows()) { var tNode = member.GetTargetNode(); if (tNode != null) { allNodes.Add(tNode); } } } Func <object, bool> validation = delegate(object obj) { if (obj is MemberData) { MemberData member = obj as MemberData; if (member != null && member.IsTargetingPinOrNode) { allNodes.Add(member.GetTargetNode()); } } return(false); }; AnalizerUtility.AnalizeObject(node, validation); generatorData.nodeConnectionsMap[node] = allNodes; return(allNodes); }
void OnGUI() { scrollPos = EditorGUILayout.BeginScrollView(scrollPos); for (int i = 0; i < data.missingMembers.Count; i++) { var mMember = data.missingMembers[i]; EditorGUILayout.LabelField("Type: " + mMember.type.PrettyName(true)); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(mMember.name); mMember.value = EditorGUILayout.TextField(mMember.value); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndScrollView(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Start Refactor")) { bool flag = false; Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null) { flag = FindMissingMember(member, true) || flag; } return(false); }; foreach (var target in data.missingTarget) { AnalizerUtility.AnalizeObject(target, scriptValidation); if (flag) { flag = false; uNodeGUIUtility.GUIChanged(target); if (EditorUtility.IsPersistent(target)) { uNodeEditorUtility.MarkDirty(target); } } } uNodeEditor.ClearGraphCache(); uNodeEditor.window?.Refresh(true); Close(); } }
public static void RetargetValueNode(Node source, Node destination) { List <uNodeComponent> nodes = new List <uNodeComponent>(); foreach (Transform t in source.transform.parent) { var comp = t.GetComponent <uNodeComponent>(); if (comp != null) { if (comp is StateNode) { var state = comp as StateNode; var transitions = state.GetTransitions(); foreach (var tr in transitions) { nodes.Add(tr); } } nodes.Add(comp); } } Func <object, bool> validation = delegate(object o) { if (o is MemberData) { MemberData member = o as MemberData; if (member.targetType == MemberData.TargetType.ValueNode) { Node n = member.GetTargetNode(); if (n != null && n == source) { member.RefactorUnityObject(new Object[] { source }, new Object[] { destination }); //return true; } } } return(false); }; foreach (var n in nodes) { AnalizerUtility.AnalizeObject(n, validation); } }
private static void ConnectNode(NodeComponent node) { if (node != null && !generatorData.connectedNode.Contains(node)) { generatorData.connectedNode.Add(node); var nodes = GetConnections(node); if (nodes != null) { foreach (NodeComponent n in nodes) { if (n) { ConnectNode(n); } } } if (node is ISuperNode) { ISuperNode superNode = node as ISuperNode; foreach (var n in superNode.nestedFlowNodes) { if (n != null) { ConnectNode(n); } } } Func <object, bool> validation = delegate(object obj) { if (obj is MemberData) { MemberData member = obj as MemberData; if (member.IsTargetingPinOrNode) { ConnectNode(member.GetTargetNode()); } } return(false); }; AnalizerUtility.AnalizeObject(node, validation); } }
/// <summary> /// Get flow nodes from node. /// </summary> /// <param name="node"></param> /// <returns></returns> public static HashSet <NodeComponent> GetFlowConnection(NodeComponent node) { HashSet <NodeComponent> allNodes; if (generatorData.flowNodeConnectionsMap.TryGetValue(node, out allNodes)) { return(allNodes); } allNodes = new HashSet <NodeComponent>(); if (node is StateNode) { StateNode eventNode = node as StateNode; TransitionEvent[] TE = eventNode.GetTransitions(); foreach (TransitionEvent transition in TE) { if (transition.GetTargetNode() != null && !allNodes.Contains(transition.GetTargetNode())) { allNodes.Add(transition.GetTargetNode()); } } } Func <object, bool> validation = delegate(object obj) { if (obj is MemberData) { MemberData member = obj as MemberData; if (member != null && member.isAssigned && (member.targetType == MemberData.TargetType.FlowNode || member.targetType == MemberData.TargetType.FlowInput) && !allNodes.Contains(member.GetTargetNode())) { allNodes.Add(member.GetTargetNode()); } } return(false); }; AnalizerUtility.AnalizeObject(node, validation); generatorData.flowNodeConnectionsMap[node] = allNodes; return(allNodes); }
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 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 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); }
private static void RefactorFunction(uNodeFunction function, string name, Type returnType, Type[] paramTypes) { var graph = function.owner; Undo.SetCurrentGroupName("Refactor Function: " + function.Name); HashSet <GameObject> referencedGraphs = new HashSet <GameObject>(); if (graph != null) { RuntimeMethod runtime = null; if (graph is IIndependentGraph) { if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); if (prefab != null) { var oriGraph = prefab.GetComponent <uNodeRoot>(); if (oriGraph != null) { var methods = ReflectionUtils.GetRuntimeType(oriGraph).GetMethods(); foreach (var m in methods) { if (m is RuntimeMethod && m.Name == name) { var parameters = m.GetParameters(); if (parameters.Length == paramTypes.Length) { if (runtime == null) { runtime = m as RuntimeMethod; } bool isValid = true; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType != paramTypes[i]) { isValid = false; break; } } if (isValid) { runtime = m as RuntimeMethod; } } } } } } } else { var methods = ReflectionUtils.GetRuntimeType(graph).GetMethods(); foreach (var m in methods) { if (m is RuntimeGraphMethod runtimeMethod && runtimeMethod.target == function) { runtime = runtimeMethod; break; } } } } MemberInfo nativeMember = null; if (graph.GeneratedTypeName.ToType(false) != null) { var type = graph.GeneratedTypeName.ToType(false); if (paramTypes.Length == 0 && function.GenericParameters.Count == 0) { nativeMember = type.GetMethod(name, MemberData.flags); } var members = type.GetMember(name, MemberData.flags); if (members != null) { var genericLength = function.GenericParameters.Count; foreach (var m in members) { if (m is MethodInfo method) { var mParam = method.GetParameters(); var mGeneric = method.GetGenericArguments(); if (paramTypes.Length == mParam.Length && mGeneric.Length == genericLength) { bool valid = true; for (int i = 0; i < mParam.Length; i++) { if (mParam[i].ParameterType != paramTypes[i]) { valid = false; break; } } if (valid) { nativeMember = method; break; } } } } } } var graphPrefabs = uNodeEditorUtility.FindPrefabsOfType <uNodeRoot>(); foreach (var prefab in graphPrefabs) { var gameObject = prefab; GameObject prefabContent = null; if (GraphUtility.HasTempGraphObject(prefab)) { gameObject = GraphUtility.GetTempGraphObject(prefab); } else if (uNodeEditorUtility.IsPrefab(prefab)) { prefabContent = PrefabUtility.LoadPrefabContents(AssetDatabase.GetAssetPath(prefab)); gameObject = prefabContent; } var scripts = gameObject.GetComponentsInChildren <MonoBehaviour>(true); bool hasUndo = false; Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null && member.startType is RuntimeType) { var members = member.GetMembers(false); if (members != null) { for (int i = 0; i < members.Length; i++) { var m = members[i]; if (member.namePath.Length > i + 1) { if (m == runtime || m == nativeMember) { if (!hasUndo && prefabContent == null) { uNodeEditorUtility.RegisterFullHierarchyUndo(gameObject); hasUndo = true; } var path = member.namePath; path[i + 1] = function.Name; member.name = string.Join(".", path); { var items = member.Items; if (items.Length > i) { var mVal = MemberData.CreateFromMember(runtime); items[i] = mVal.Items[0]; member.SetItems(items); } } if (m == nativeMember) { referencedGraphs.Add(prefab); } return(true); } } } } } return(false); }; if (runtime != null) { bool hasChanged = false; Array.ForEach(scripts, script => { bool flag = AnalizerUtility.AnalizeObject(script, scriptValidation); if (flag) { hasChanged = true; hasUndo = false; uNodeGUIUtility.GUIChanged(script); uNodeEditorUtility.MarkDirty(script); } }); if (hasChanged) { if (gameObject != prefab) { uNodeEditorUtility.RegisterFullHierarchyUndo(prefab); if (prefabContent == null) { //Save the temporary graph GraphUtility.AutoSaveGraph(gameObject); } else { //Save the prefab contents and unload it uNodeEditorUtility.SavePrefabAsset(gameObject, prefab); } } uNodeEditorUtility.MarkDirty(prefab); } } if (prefabContent != null) { PrefabUtility.UnloadPrefabContents(prefabContent); } } } uNodeEditorUtility.RegisterFullHierarchyUndo(graph.gameObject); graph.Refresh(); Func <object, bool> validation = delegate(object OBJ) { return(CallbackRefactorFunction(OBJ, function, name, paramTypes)); }; Array.ForEach(graph.nodes, item => AnalizerUtility.AnalizeObject(item, validation)); if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); uNodeEditorUtility.RegisterFullHierarchyUndo(prefab); GraphUtility.AutoSaveGraph(graph.gameObject); } uNodeEditor.ClearGraphCache(); uNodeEditor.window?.Refresh(true); DoCompileReferences(graph, referencedGraphs); }
public static void RefactorProperty(uNodeProperty property, string name) { name = uNodeUtility.AutoCorrectName(name); var graph = property.owner; bool hasVariable = false; if (graph.Properties != null && graph.Properties.Count > 0) { foreach (var V in graph.Properties) { if (V.Name == name) { hasVariable = true; break; } } } if (graph.Variables != null && graph.Variables.Count > 0) { foreach (var V in graph.Variables) { if (V.Name == name) { hasVariable = true; break; } } } if (hasVariable) { return; } Undo.SetCurrentGroupName("Rename Property: " + property.Name); HashSet <GameObject> referencedGraphs = new HashSet <GameObject>(); if (graph != null) { RuntimeProperty runtime = null; if (graph is IIndependentGraph) { if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); if (prefab != null) { var oriGraph = prefab.GetComponent <uNodeRoot>(); if (oriGraph != null) { runtime = ReflectionUtils.GetRuntimeType(oriGraph).GetProperty(property.Name) as RuntimeProperty; } } } else { runtime = ReflectionUtils.GetRuntimeType(graph).GetProperty(property.Name) as RuntimeProperty; } } PropertyInfo nativeMember = null; if (graph.GeneratedTypeName.ToType(false) != null) { var type = graph.GeneratedTypeName.ToType(false); nativeMember = type.GetProperty(property.Name, MemberData.flags); } var graphPrefabs = uNodeEditorUtility.FindPrefabsOfType <uNodeRoot>(); foreach (var prefab in graphPrefabs) { var gameObject = prefab; GameObject prefabContent = null; if (GraphUtility.HasTempGraphObject(prefab)) { gameObject = GraphUtility.GetTempGraphObject(prefab); } else if (uNodeEditorUtility.IsPrefab(prefab)) { prefabContent = PrefabUtility.LoadPrefabContents(AssetDatabase.GetAssetPath(prefab)); gameObject = prefabContent; } var scripts = gameObject.GetComponentsInChildren <MonoBehaviour>(true); bool hasUndo = false; Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null && member.startType is RuntimeType) { var members = member.GetMembers(false); if (members != null) { for (int i = 0; i < members.Length; i++) { var m = members[i]; if (member.namePath.Length > i + 1) { if (m == runtime || m == nativeMember) { if (!hasUndo && prefabContent == null) { uNodeEditorUtility.RegisterFullHierarchyUndo(gameObject); hasUndo = true; } var path = member.namePath; path[i + 1] = name; member.name = string.Join(".", path); if (m == nativeMember) { referencedGraphs.Add(prefab); } return(true); } } } } } return(false); }; if (runtime != null || nativeMember != null) { bool hasChanged = false; Array.ForEach(scripts, script => { bool flag = AnalizerUtility.AnalizeObject(script, scriptValidation); if (flag) { hasChanged = true; hasUndo = false; uNodeGUIUtility.GUIChanged(script); uNodeEditorUtility.MarkDirty(script); } }); if (hasChanged) { if (gameObject != prefab) { uNodeEditorUtility.RegisterFullHierarchyUndo(prefab); if (prefabContent == null) { //Save the temporary graph GraphUtility.AutoSaveGraph(gameObject); } else { //Save the prefab contents and unload it uNodeEditorUtility.SavePrefabAsset(gameObject, prefab); } } uNodeEditorUtility.MarkDirty(prefab); } } if (prefabContent != null) { PrefabUtility.UnloadPrefabContents(prefabContent); } } } uNodeEditorUtility.RegisterFullHierarchyUndo(graph.gameObject); string oldVarName = property.Name; property.Name = name; graph.Refresh(); Func <object, bool> validation = delegate(object OBJ) { return(CallbackRenameProperty(OBJ, graph, property.name, oldVarName)); }; Array.ForEach(graph.nodes, item => AnalizerUtility.AnalizeObject(item, validation)); if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); uNodeEditorUtility.RegisterFullHierarchyUndo(prefab); GraphUtility.AutoSaveGraph(graph.gameObject); } uNodeEditor.ClearGraphCache(); uNodeEditor.window?.Refresh(true); DoCompileReferences(graph, referencedGraphs); }
public static void RefactorVariable(VariableData variable, string name, UnityEngine.Object owner) { bool isLocal = false; uNodeRoot graph = owner as uNodeRoot; if (graph == null) { INode <uNodeRoot> node = owner as INode <uNodeRoot>; if (node != null) { graph = node.GetOwner(); isLocal = true; } } if (graph != null) { HashSet <GameObject> referencedGraphs = new HashSet <GameObject>(); if (!isLocal) { RuntimeField field = null; if (graph is IIndependentGraph) { if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); if (prefab != null) { var oriGraph = prefab.GetComponent <uNodeRoot>(); if (oriGraph != null) { field = ReflectionUtils.GetRuntimeType(oriGraph).GetField(variable.Name) as RuntimeField; } } } else { field = ReflectionUtils.GetRuntimeType(graph).GetField(variable.Name) as RuntimeField; } } FieldInfo nativeMember = null; if (graph.GeneratedTypeName.ToType(false) != null) { var type = graph.GeneratedTypeName.ToType(false); nativeMember = type.GetField(variable.Name, MemberData.flags); } var graphPrefabs = uNodeEditorUtility.FindPrefabsOfType <uNodeRoot>(); foreach (var prefab in graphPrefabs) { var gameObject = prefab; GameObject prefabContent = null; if (GraphUtility.HasTempGraphObject(prefab)) { gameObject = GraphUtility.GetTempGraphObject(prefab); } else if (uNodeEditorUtility.IsPrefab(prefab)) { prefabContent = PrefabUtility.LoadPrefabContents(AssetDatabase.GetAssetPath(prefab)); gameObject = prefabContent; } var scripts = gameObject.GetComponentsInChildren <MonoBehaviour>(true); bool hasUndo = false; Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null) { var members = member.GetMembers(false); if (members != null) { for (int i = 0; i < members.Length; i++) { var m = members[i]; if (member.namePath.Length > i + 1) { if (m == field || m == nativeMember) { if (!hasUndo && prefabContent == null) { uNodeEditorUtility.RegisterFullHierarchyUndo(gameObject, "Rename Variable: " + variable.Name); hasUndo = true; } var path = member.namePath; path[i + 1] = name; member.name = string.Join(".", path); if (m == nativeMember) { referencedGraphs.Add(prefab); } return(true); } } } } } return(false); }; if (field != null || nativeMember != null) { bool hasChanged = false; Array.ForEach(scripts, script => { bool flag = AnalizerUtility.AnalizeObject(script, scriptValidation); if (flag) { hasChanged = true; hasUndo = false; uNodeGUIUtility.GUIChanged(script); uNodeEditorUtility.MarkDirty(script); } }); if (hasChanged) { if (gameObject != prefab) { uNodeEditorUtility.RegisterFullHierarchyUndo(prefab, "Rename Variable: " + variable.Name); if (prefabContent == null) { //Save the temporary graph GraphUtility.AutoSaveGraph(gameObject); } else { //Save the prefab contents uNodeEditorUtility.SavePrefabAsset(gameObject, prefab); } } uNodeEditorUtility.MarkDirty(prefab); } } if (prefabContent != null) { PrefabUtility.UnloadPrefabContents(prefabContent); } } } string oldVarName = variable.Name; variable.Name = name; Func <object, bool> validation = delegate(object OBJ) { return(CallbackRenameVariable(OBJ, owner, variable.Name, oldVarName)); }; graph.Refresh(); Array.ForEach(graph.nodes, item => AnalizerUtility.AnalizeObject(item, validation)); if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); uNodeEditorUtility.RegisterFullHierarchyUndo(prefab, "Rename Variable: " + oldVarName); GraphUtility.AutoSaveGraph(graph.gameObject); } uNodeEditor.ClearGraphCache(); uNodeEditor.window?.Refresh(true); DoCompileReferences(graph, referencedGraphs); } }
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 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 static HashSet <NodeComponent> GetFlowConnectedTo(Node target) { if (target != null) { if (generatorData.FlowConnectedTo.TryGetValue(target, out var comp)) { return(comp); } comp = new HashSet <NodeComponent>(); Node currNode = null; Func <object, bool> validation = delegate(object obj) { if (obj is MemberData) { MemberData member = obj as MemberData; Node targetNode = member.GetTargetNode(); if (targetNode == target) { if (member.targetType == MemberData.TargetType.FlowNode || member.targetType == MemberData.TargetType.FlowInput) { comp.Add(currNode); return(true); } else if (member.targetType == MemberData.TargetType.ValueNode || member.targetType == MemberData.TargetType.NodeField || member.targetType == MemberData.TargetType.NodeFieldElement) { var connectedNodes = GetFlowConnectedTo(currNode); if (connectedNodes != null) { foreach (var n in connectedNodes) { comp.Add(n); } } } } } return(false); }; foreach (Node node in generatorData.allNode) { if (target == node) { continue; } if (node is StateNode) { StateNode eventNode = node as StateNode; TransitionEvent[] TE = eventNode.GetTransitions(); foreach (TransitionEvent transition in TE) { if (transition != null && transition.GetTargetNode() == target) { comp.Add(node); break; } } } else if (node is IMacro) { IMacro macro = node as IMacro; var outputFlows = macro.OutputFlows; foreach (var flow in outputFlows) { if (flow != null && flow.target.GetTargetNode() == target) { comp.Add(node); break; } } } currNode = node; AnalizerUtility.AnalizeObject(node, validation); } foreach (EventNode method in generatorData.eventNodes) { if (method == null) { continue; } foreach (var flow in method.GetFlows()) { if (flow.GetTargetNode() == target) { comp.Add(method); break; } } } generatorData.FlowConnectedTo[target] = comp; return(comp); } return(null); }
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(); }