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); }