public void OpenGraphWindow(Graph graph) { GraphEditor window = null; int _id = graph.GetInstanceID(); // check if other graph windows are already open // happens if user has closed unity and left some graph windows open // then we have to add them to the graphwindows list again. if (graphWindows.Count == 0 || graphWindows == null) { GraphEditor[] _w = Resources.FindObjectsOfTypeAll <GraphEditor>(); if (_w.Length > 0) { //Debug.Log(_w.Length); for (int w = 0; w < _w.Length; w++) { graphWindows.Add(new GraphWindows(_w[w].rootGraph.GetInstanceID(), _w[w])); } } } for (int i = 0; i < graphWindows.Count; i++) { if (graphWindows[i].id == _id) { window = graphWindows[i].graphEditor; } } if (window != null) { window.Init(window, graph); window.Focus(); } else { //window = CreateInstance<GraphEditor>(); window = (GraphEditor)EditorWindow.CreateWindow <GraphEditor>(typeof(GraphEditor)); graphWindows.Add(new GraphWindows(graph.GetInstanceID(), window)); window.Init(window, graph); } // Check if graph needs to be updated GraphUpdater.UpdateGraph(graph); EditorUtility.SetDirty(this); }
public override void OnInspectorGUI() { if (editorSkin == null) { editorSkin = EditorHelpers.LoadSkin(); editIcon = EditorHelpers.LoadIcon("editIcon.png"); refreshIcon = EditorHelpers.LoadIcon("refreshIcon.png"); okIcon = EditorHelpers.LoadIcon("checkmarkIcon.png"); cancelIcon = EditorHelpers.LoadIcon("cancelIcon.png"); } if (fr != null && fr.graph != null) { GUI.enabled = true; } else { GUI.enabled = false; } using (new GUILayout.HorizontalScope("Box")) { if (GUILayout.Button((Application.isPlaying && fr.runUniqueInstance) ? "Open instance" : "Open", GUILayout.Height(50))) { //var window = CreateInstance<GraphEditor>(); //window.Init(window, fr.graph); var _settings = (FREditorSettings)FREditorSettings.GetOrCreateSettings(); _settings.OpenGraphWindow(fr.graph); // Check if graph needs to be updated GraphUpdater.UpdateGraph(fr.graph); } if (Application.isPlaying && fr.runUniqueInstance) { if (GUILayout.Button("Open original", GUILayout.Height(50))) { //var window = CreateInstance<GraphEditor>(); //window.Init(window, fr.originalGraph); var _settings = (FREditorSettings)FREditorSettings.GetOrCreateSettings(); _settings.OpenGraphWindow(fr.originalGraph); } } } GUI.enabled = true; EditorGUI.BeginChangeCheck(); using (new GUILayout.HorizontalScope("Box")) { fr.graph = (Graph)EditorGUILayout.ObjectField(fr.graph, typeof(Graph), false); if (GUILayout.Button("New Graph")) { NodeCreator.CreateNewGraphWithDefaultNodes(fr); } } using (new GUILayout.VerticalScope(("Box"))) { using (new GUILayout.HorizontalScope()) { GUILayout.Label("Graph settings"); GUILayout.FlexibleSpace(); if (GUILayout.Button("?", GUILayout.Width(18))) { Application.OpenURL("https://flowreactor.io/documentation/flowreactor-component/"); } } fr.runUniqueInstance = GUILayout.Toggle(fr.runUniqueInstance, "unique instance"); fr.useGlobalUpdateLoop = GUILayout.Toggle(fr.useGlobalUpdateLoop, "global update loop"); } if (fr.graph == null) { return; } // cache keys which needs to be removed List <string> cleanupKeys = new List <string>(); EditorHelpers.DrawUILine(); #region nodecontrollables // NODE CONTROLLABLES //////////////////////////// using (new GUILayout.HorizontalScope("Toolbar")) { GUILayout.Label("Node controlled objects", "boldLabel"); GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent(refreshIcon, "Collect all controllable nodes"), "toolbarButton")) { fr.graph.RegisterINodeControllables(fr); UpdateControllablesDictionary(); } if (GUILayout.Button("?", "toolbarButton")) { Application.OpenURL("https://flowreactor.io/documentation/frnodemodules/"); } } if (fr.nodeControllables != null && fr.nodeControllables.Count > 0) { EditorGUI.BeginChangeCheck(); using (new GUILayout.VerticalScope(editorSkin.GetStyle("BoxLine"))) { if (fr.nodeControllables != null) { foreach (Node node in fr.nodeControllables.Keys) { using (new GUILayout.VerticalScope("Box")) { using (new GUILayout.HorizontalScope("Toolbar")) { GUILayout.Label(node.nodeData.title); GUILayout.FlexibleSpace(); } Dictionary <string, INodeControllable> tempController = new Dictionary <string, INodeControllable>(); foreach (var faces in fr.nodeControllables[node].interfaces.Keys) { using (new GUILayout.HorizontalScope()) { GUILayout.Label(faces); var _lastRect = GUILayoutUtility.GetLastRect(); var _obj = EditorGUILayout.ObjectField((UnityEngine.Object)fr.nodeControllables[node].interfaces[faces], typeof(INodeControllable), true); if (GUILayout.Button("select")) { PopupWindow.Show(_lastRect, new PopupShowINodeControllableObjects(node, faces)); } //fr.gameControllerInterfaces[node].interfaces[faces] = _obj as INodeController; tempController.Add(faces, _obj as INodeControllable); } } foreach (var t in tempController.Keys) { fr.nodeControllables[node].interfaces[t] = tempController[t]; } } } } else { GUILayout.Label("null"); } } if (EditorGUI.EndChangeCheck()) { UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene()); } } EditorHelpers.DrawUILine(); //////////////////////////// #endregion #region exposedvariables // EXPOSED VARIABLES //////////////////////////// using (new GUILayout.HorizontalScope("Toolbar")) { GUILayout.Label("Exposed variables", "boldLabel"); GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent(refreshIcon, "Manually collect and update exposed variables from nodes"), "ToolbarButton")) { fr.CollectAndUpdateAllExposedVariables(); } #if FLOWREACTOR_DEBUG GUI.color = Color.yellow; if (GUILayout.Button("Clear exposed variables", "ToolbarButton")) { fr.exposedNodeVariables = new Dictionary <string, Dictionary <string, FRVariable> >(); fr.graph.exposedNodeVariables = new Dictionary <string, Graph.ExposedVariables>(); } GUI.color = Color.white; #endif } if (fr.exposedNodeVariables != null) { if (fr.exposedNodeVariables.Keys.Count > 0) { var i = 0; using (new GUILayout.VerticalScope(editorSkin.GetStyle("BoxLine"))) { foreach (string exposedNodeKey in fr.exposedNodeVariables.Keys) { if (EditorGUIUtility.isProSkin) { GUI.color = colorsDarkSkin[i % 2]; } else { GUI.color = colorsLighSkin[i % 2]; } using (new GUILayout.VerticalScope(editorSkin.GetStyle("BoxWhite"))) { GUI.color = Color.white; GUILayout.Label(exposedNodeKey, "boldLabel"); List <string> _variableKeys = fr.exposedNodeVariables[exposedNodeKey].Keys.ToList(); for (int s = 0; s < _variableKeys.Count; s++) { using (new GUILayout.HorizontalScope()) { var _variableKey = _variableKeys[s]; var _exposedVariable = fr.exposedNodeVariables[exposedNodeKey][_variableKey]; var _varType = _exposedVariable.GetType().Name.ToString(); GUILayout.Label(new GUIContent(_varType, "GetExposedVariable<" + _varType + ">(" + "\"" + exposedNodeKey + "\"," + "\"" + _variableKey + "\");"), GUILayout.Width(80)); GUI.enabled = _exposedVariable.editExposedName; _exposedVariable.exposedName = GUILayout.TextField(_exposedVariable.exposedName, GUILayout.Width(100)); GUI.enabled = true; if (_exposedVariable.editExposedName) { if (string.IsNullOrEmpty(_exposedVariable.exposedName)) { GUI.enabled = false; } if (GUILayout.Button(okIcon, GUILayout.Width(20), GUILayout.Height(20))) { _exposedVariable.editExposedName = false; var _fromName = _variableKey; var _newName = _exposedVariable.exposedName; #if FLOWREACTOR_DEBUG Debug.Log("update key from: " + _fromName + " to: " + _newName); #endif // check if new name already exists bool _nameAlreadyExists = false; foreach (var variableKeyB in fr.exposedNodeVariables[exposedNodeKey].Keys) { if (variableKeyB.Equals(_newName)) { _nameAlreadyExists = true; } } if (!_nameAlreadyExists) { var _nodeVariableField = fr.graph.exposedNodeVariables[exposedNodeKey].variables[_fromName].nodeOwner.GetType().GetField(fr.graph.exposedNodeVariables[exposedNodeKey].variables[_fromName].name); var _nodeVariable = _nodeVariableField.GetValue(fr.graph.exposedNodeVariables[exposedNodeKey].variables[_fromName].nodeOwner) as FRVariable; _nodeVariable.exposedName = _newName; fr.exposedNodeVariables[exposedNodeKey].UpdateKey(_fromName, _newName); fr.graph.exposedNodeVariables[exposedNodeKey].variables.UpdateKey(_fromName, _newName); } else { _exposedVariable.exposedName = _fromName; } } GUI.enabled = true; if (GUILayout.Button(cancelIcon, GUILayout.Width(20), GUILayout.Height(20))) { fr.exposedNodeVariables[exposedNodeKey][_variableKey].exposedName = _variableKey; fr.exposedNodeVariables[exposedNodeKey][_variableKey].editExposedName = false; } } else { if (GUILayout.Button(editIcon, GUILayout.Width(20), GUILayout.Height(20))) { fr.exposedNodeVariables[exposedNodeKey][_variableKey].editExposedName = true; } } if (fr.exposedNodeVariables[exposedNodeKey].ContainsKey(_variableKey)) { GUILayout.Label("Value: ", GUILayout.Width(50)); fr.exposedNodeVariables[exposedNodeKey][_variableKey].Draw(true, null); } //GUILayout.Label("Runtime access: GetData<" + fr.exposedNodeVariables[exposed].variables[variableKeys[s]].GetType().ToString() + ">("); } } } i++; } } } } //////////////////////////// #endregion #region sceneoverrides // BLACKBOARD SCENE OVERRIDES //////////////////////////// if (fr.graph.blackboards != null && fr.graph.blackboards.Keys.Count > 0) { EditorHelpers.DrawUILine(); using (new GUILayout.HorizontalScope("Toolbar")) { GUILayout.Label("Blackboard scene overrides", "boldLabel"); } using (new GUILayout.VerticalScope(editorSkin.GetStyle("BoxLine"))) { foreach (var bb in fr.graph.blackboards.Keys) { if (fr.graph.blackboards[bb].blackboard == null) { EditorGUILayout.HelpBox("Blackboard is empty, please assign a blackboard asset to the graph", MessageType.Warning); continue; } using (new GUILayout.HorizontalScope(FlowReactorEditorStyles.overflowButton)) { fr.graph.blackboards[bb].foldout = EditorGUILayout.Foldout(fr.graph.blackboards[bb].foldout, fr.graph.blackboards[bb].blackboard.name); } if (fr.graph.blackboards[bb].foldout) { foreach (var key in fr.graph.blackboards[bb].blackboard.variables.Keys) { FRVariable value = null; // object is in the scene but variable is not set as overridable if (fr.overrideSceneVariables.TryGetValue(key.ToString(), out value) && !IsObjectPrefabInProject()) { using (new GUILayout.HorizontalScope()) { EditorGUI.BeginChangeCheck(); if (fr.graph.blackboards[bb].blackboard.variables[key].sceneReferenceOnly) { GUI.enabled = false; value.overrideVariable = true; } value.overrideVariable = GUILayout.Toggle(value.overrideVariable, "Override", GUILayout.Width(100)); GUI.enabled = true; if (value.overrideVariable == false) { //fr.overrideSceneVariables.Remove(key.ToString()); GUI.enabled = false; GUILayout.Label(fr.graph.blackboards[bb].blackboard.variables[key].name); if (fr.graph.blackboards[bb].blackboard.variables[key].useDatabox) { GUILayout.Label(fr.graph.blackboards[bb].blackboard.variables[key].databoxID + " | " + fr.graph.blackboards[bb].blackboard.variables[key].tableID + " | " + fr.graph.blackboards[bb].blackboard.variables[key].entryID + " | " + fr.graph.blackboards[bb].blackboard.variables[key].tableID); } else { fr.graph.blackboards[bb].blackboard.variables[key].Draw(true, null); } GUI.enabled = true; } else { GUI.enabled = true; //GUILayout.Label(value.name); GUILayout.Label(fr.graph.blackboards[bb].blackboard.variables[key].name); value.Draw(true, null); } GUI.enabled = true; if (EditorGUI.EndChangeCheck() && !Application.isPlaying) { UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene()); } } } // object lives in the scene else { using (new GUILayout.HorizontalScope()) { var v = fr.graph.blackboards[bb].blackboard.variables[key] as FRVariable; if (!IsObjectPrefabInProject()) { if (v.sceneReferenceOnly) { GUI.enabled = false; v.overrideVariable = true; } } else { GUI.enabled = false; } v.overrideVariable = GUILayout.Toggle(v.overrideVariable, "Override", GUILayout.Width(100)); GUI.enabled = true; if (v.overrideVariable) { // create new item and copy it to the override variables var _newOverrideVariable = (FRVariable)Activator.CreateInstance(fr.graph.blackboards[bb].blackboard.variables[key].GetType()); _newOverrideVariable.overrideVariable = true; _newOverrideVariable.name = v.name; fr.overrideSceneVariables.Add(key.ToString(), _newOverrideVariable); fr.overrideSceneVariables[key.ToString()].overrideVariable = true; fr.overrideSceneVariables[key.ToString()].name = v.name; v.overrideVariable = false; // blackboard is always false } GUI.enabled = false; GUILayout.Label(v.name); if (fr.graph.blackboards[bb].blackboard.variables[key].useDatabox) { GUILayout.Label(fr.graph.blackboards[bb].blackboard.variables[key].databoxID + " | " + fr.graph.blackboards[bb].blackboard.variables[key].tableID + " | " + fr.graph.blackboards[bb].blackboard.variables[key].entryID + " | " + fr.graph.blackboards[bb].blackboard.variables[key].tableID); } else { fr.graph.blackboards[bb].blackboard.variables[key].Draw(true, null); } GUI.enabled = true; } } } GUILayout.Space(10); EditorHelpers.DrawUILine(); } // cleanup override variables if they don't exist in the blackboard anymore foreach (var kc in fr.overrideSceneVariables.Keys) { bool _overrideVarExists = false; foreach (var bc in fr.graph.blackboards.Keys) { if (fr.graph.blackboards[bc].blackboard.variables.ContainsKey(Guid.Parse(kc))) { _overrideVarExists = true; } } if (!_overrideVarExists) { Debug.Log("cleanup"); cleanupKeys.Add(kc.ToString()); } } } } } for (int c = 0; c < cleanupKeys.Count; c++) { #if FLOWREACTOR_DEBUG Debug.Log("remove override variable " + cleanupKeys[c]); #endif Debug.Log("remove"); fr.overrideSceneVariables.Remove(cleanupKeys[c]); } // only for debug #if FLOWREACTOR_DEBUG DrawDefaultInspector(); #endif if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(target); } serializedObject.Update(); serializedObject.ApplyModifiedProperties(); }