//... void OnGUI() { if (EditorApplication.isCompiling) { ShowNotification(new GUIContent("...Compiling Please Wait...")); willRepaint = true; return; } //Init GUI.color = Color.white; GUI.backgroundColor = Color.white; GUI.skin.label.richText = true; e = Event.current; //get the graph from the GraphOwner if one is set if (targetOwner != null) { rootGraph = targetOwner.graph; } if (rootGraph == null) { ShowEmptyGraphGUI(); return; } //set the currently viewing graph by getting the current child graph from the root graph recursively var curr = GetCurrentGraph(rootGraph); if (!ReferenceEquals(curr, currentGraph)) { currentGraph = curr; OnCurrentGraphChanged(); } if (currentGraph == null || ReferenceEquals(currentGraph, null)) { return; } //handle undo/redo keyboard commands if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed") { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; GraphEditorUtility.activeElement = null; willRepaint = true; fullDrawPass = true; UpdateReferencesAndNodeIDs(); currentGraph.Validate(); e.Use(); return; } if (e.type == EventType.MouseDown) { RemoveNotification(); } if (mouseOverWindow == current && (e.isMouse || e.isKey)) { willRepaint = true; } ///should we set dirty? Put in practise at the end var willDirty = false; if ( (e.rawType == EventType.MouseUp && e.button != 2) || (e.type == EventType.DragPerform) || (e.type == EventType.KeyUp && (e.keyCode == KeyCode.Return || GUIUtility.keyboardControl == 0)) ) { willDirty = true; } //initialize rects canvasRect = Rect.MinMaxRect(5, TOP_MARGIN, position.width - 5, position.height - BOTTOM_MARGIN); minimapRect = Rect.MinMaxRect(canvasRect.xMax - NCPrefs.minimapSize.x, canvasRect.yMax - NCPrefs.minimapSize.y, canvasRect.xMax - 2, canvasRect.yMax - 2); var originalCanvasRect = canvasRect; //canvas background GUI.Box(canvasRect, string.Empty, CanvasStyles.canvasBG); //background grid DrawGrid(canvasRect, pan, zoomFactor); //handle minimap HandleMinimapEvents(minimapRect); //PRE nodes events HandlePreNodesGraphEvents(currentGraph, mousePosInCanvas); var oldMatrix = default(Matrix4x4); if (zoomFactor != 1) { canvasRect = StartZoomArea(canvasRect, zoomFactor, out oldMatrix); } //main group GUI.BeginGroup(canvasRect); { //pan the view rect var totalCanvas = canvasRect; totalCanvas.x = 0; totalCanvas.y = 0; totalCanvas.x += pan.x / zoomFactor; totalCanvas.y += pan.y / zoomFactor; totalCanvas.width -= pan.x / zoomFactor; totalCanvas.height -= pan.y / zoomFactor; //begin panning group GUI.BeginGroup(totalCanvas); { //inverse pan the view rect viewRect = totalCanvas; viewRect.x = 0; viewRect.y = 0; viewRect.x -= pan.x / zoomFactor; viewRect.y -= pan.y / zoomFactor; viewRect.width += pan.x / zoomFactor; viewRect.height += pan.y / zoomFactor; DoCanvasGroups(); BeginWindows(); ShowNodesGUI(currentGraph, viewRect, fullDrawPass, mousePosInCanvas, zoomFactor); EndWindows(); DoCanvasRectSelection(viewRect); } GUI.EndGroup(); } GUI.EndGroup(); if (zoomFactor != 1 && oldMatrix != default(Matrix4x4)) { EndZoomArea(oldMatrix); } //minimap DrawMinimap(minimapRect); //Breadcrumb navigation GUILayout.BeginArea(new Rect(20, TOP_MARGIN + 5, screenWidth, screenHeight)); DoBreadCrumbNavigation(rootGraph); GUILayout.EndArea(); //POST nodes events HandlePostNodesGraphEvents(currentGraph, mousePosInCanvas); //Graph controls (after windows so that panels (inspector, blackboard) show on top) ShowToolbar(currentGraph); ShowPanels(currentGraph, mousePosInCanvas); AcceptDrops(currentGraph, mousePosInCanvas); // //dirty? if (willDirty) { willDirty = false; willRepaint = true; currentGraph.Serialize(); EditorUtility.SetDirty(currentGraph); } //repaint? if (willRepaint || e.type == EventType.MouseMove || rootGraph.isRunning) { Repaint(); } if (e.type == EventType.Repaint) { fullDrawPass = false; willRepaint = false; } //playmode indicator if (Application.isPlaying) { var r = new Rect(0, 0, 120, 10); r.center = new Vector2(screenWidth / 2, screenHeight - BOTTOM_MARGIN - 50); GUI.color = Color.green; GUI.Box(r, "PlayMode Active", CanvasStyles.windowHighlight); } //hack for quick popups if (OnDoPopup != null) { var temp = OnDoPopup; OnDoPopup = null; QuickPopup.Show(temp); } //PostGUI GraphEditorUtility.InvokePostGUI(); //closure GUI.Box(originalCanvasRect, string.Empty, CanvasStyles.canvasBorders); GUI.color = Color.white; GUI.backgroundColor = Color.white; }
///---------------------------------------------------------------------------------------------- //EDIT MENU static GenericMenu GetToolbarMenu_Edit(Graph graph, GraphOwner owner) { var menu = new GenericMenu(); //Bind if (!Application.isPlaying && owner != null && !owner.graphIsBound) { menu.AddItem(new GUIContent("Bind To Owner"), false, () => { if (EditorUtility.DisplayDialog("Bind Graph", "This will make a local copy of the graph, bound to the owner.\n\nThis allows you to make local changes and assign scene object references directly.\n\nNote that you can also use scene object references through the use of Blackboard Variables.\n\nBind Graph?", "YES", "NO")) { UndoUtility.RecordObject(owner, "New Local Graph"); owner.SetBoundGraphReference(owner.graph); UndoUtility.SetDirty(owner); } }); } else { menu.AddDisabledItem(new GUIContent("Bind To Owner")); } //Save to asset if (!EditorUtility.IsPersistent(graph)) { menu.AddItem(new GUIContent("Save To Asset"), false, () => { var newGraph = (Graph)EditorUtils.CreateAsset(graph.GetType()); if (newGraph != null) { EditorUtility.CopySerialized(graph, newGraph); newGraph.Validate(); AssetDatabase.SaveAssets(); } }); } else { menu.AddDisabledItem(new GUIContent("Save To Asset")); } //Create defined vars if (graph.blackboard != null) { foreach (var bb in graph.blackboard.GetAllParents(true).Reverse()) { var category = "Promote Missing Parameters To Variables/"; menu.AddItem(new GUIContent(category + $"In '{bb.identifier}' Blackboard"), false, () => { if (EditorUtility.DisplayDialog("Promote Missing Parameters", "This will fill the target Blackboard with a Variable for each defined missing Parameter in the graph.\nContinue?", "YES", "NO")) { UndoUtility.RecordObject(graph, "Promote Variables"); UndoUtility.RecordObject(bb.unityContextObject, "Promote Variables"); graph.PromoteMissingParametersToVariables(bb); UndoUtility.SetDirty(graph); UndoUtility.SetDirty(bb.unityContextObject); } }); } } else { menu.AddDisabledItem(new GUIContent("Promote Defined Parameters To Variables")); } menu.AddItem(new GUIContent("Scan Graph for Serialized Struct Types"), false, () => { GraphEditorUtility.ScanForStructTypesAndAppendThem(graph); }); if (!Application.isPlaying) { menu.AddItem(new GUIContent("Re-Validate Graph"), false, () => { graph.SelfDeserialize(); graph.Validate(); FullDrawPass(); }); } else { menu.AddDisabledItem(new GUIContent("Re-Validate Graph")); } return(menu); }