public void DrawPortalSelector (Portal exit, Generator.InoutType type) { if (MapMagic.instance.guiGens == null) MapMagic.instance.guiGens = MapMagic.instance.gens; GeneratorsAsset gens = MapMagic.instance.guiGens; //if (MapMagic.instance.guiGens != null) gens = MapMagic.instance.guiGens; int entersNum = 0; for (int g=0; g<gens.list.Length; g++) { Portal portal = gens.list[g] as Portal; if (portal == null) continue; if (portal.form == Portal.PortalForm.Out) continue; if (portal.type != type) continue; entersNum++; } PopupMenu.MenuItem[] popupItems = new PopupMenu.MenuItem[entersNum]; int counter = 0; for (int g=0; g<gens.list.Length; g++) { Portal enter = gens.list[g] as Portal; if (enter == null) continue; if (enter.form == Portal.PortalForm.Out) continue; if (enter.type != type) continue; popupItems[counter] = new PopupMenu.MenuItem( enter.name, delegate () { if (enter.IsDependentFrom(exit)) { Debug.LogError("MapMagic: Linking portals this way will create dependency loop."); return; } exit.input.Link(enter.output, enter); gens.ChangeGenerator(exit); } ); counter++; } PopupMenu.DrawPopup(popupItems, Event.current.mousePosition, closeAllOther:true); }
private void OnGUI() { DrawWindow(); if (repaint) DrawWindow(); repaint = false; } //drawing window, or doing it twice if repaint is needed private void DrawWindow() { if (MapMagic.instance == null) MapMagic.instance = FindObjectOfType<MapMagic>(); MapMagic script = MapMagic.instance; if (script==null) return; if (MapMagic.instance.guiGens == null) MapMagic.instance.guiGens = MapMagic.instance.gens; GeneratorsAsset gens = MapMagic.instance.guiGens; //if (script.guiGens != null) gens = script.guiGens; //if (script.gens==null) script.gens = ScriptableObject.CreateInstance<GeneratorsAsset>(); //un-selecting field on drag if (Event.current.button != 0) UnityEditor.EditorGUI.FocusTextInControl(""); //startingscript.layout if (script.layout==null) { script.layout = new Layout(); script.layout.scroll = script.guiScroll; script.layout.zoom = script.guiZoom; script.layout.maxZoom = 1f; } script.layout.Zoom(); script.layout.Scroll(); //scrolling and zooming script.layout.field = this.position; //unity 5.4 beta if (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.layout) return; if (script.guiDebug) Profiler.BeginSample("Redraw Window"); //using middle mouse click events if (Event.current.button == 2) Event.current.Use(); //undo Undo.undoRedoPerformed -= PerformUndo; Undo.undoRedoPerformed += PerformUndo; //setting title content titleContent = new GUIContent("Map Magic"); titleContent.image =script.layout.GetIcon("MapMagic_WindowIcon"); //drawing background Vector2 windowZeroPos =script.layout.ToInternal(Vector2.zero); windowZeroPos.x = ((int)(windowZeroPos.x/64f)) * 64; windowZeroPos.y = ((int)(windowZeroPos.y/64f)) * 64; script.layout.Icon( "MapMagic_Background", new Rect(windowZeroPos - new Vector2(64,64), position.size + new Vector2(128,128)), tile:true); //drawing test center //script.layout.Button("Zero", new Rect(-10,-10,20,20)); //calculating visible area Rect visibleArea = script.layout.ToInternal( new Rect(0,0,position.size.x,position.size.y) ); if (forceAll) { visibleArea = new Rect(-200000,-200000,400000,400000); forceAll = false; } //visibleArea = new Rect(visibleArea.x+100, visibleArea.y+100, visibleArea.width-200, visibleArea.height-200); //layout.Label("Area", helpBox:true, rect:visibleArea); //checking if all generators are loaded, and none of them is null for (int i=gens.list.Length-1; i>=0; i--) { if (gens.list[i] == null) { ArrayTools.RemoveAt(ref gens.list, i); continue; } foreach (Generator.Input input in gens.list[i].Inputs()) { if (input == null) continue; if (input.linkGen == null) input.Link(null, null); } } #region Drawing groups if (script.guiDebug) Profiler.BeginSample("Drawing Groups"); for(int i=0; i<gens.list.Length; i++) { if (!(gens.list[i] is Group)) continue; Group group = gens.list[i] as Group; //checking if this is withinscript.layout field if (group.guiRect.x > visibleArea.x+visibleArea.width || group.guiRect.y > visibleArea.y+visibleArea.height || group.guiRect.x+group.guiRect.width < visibleArea.x || group.guiRect.y+group.guiRect.height < visibleArea.y) if (group.guiRect.width > 0.001f &&script.layout.dragState != Layout.DragState.Drag) continue; //if guiRect initialized and not dragging //settingscript.layout data group.layout.field = group.guiRect; group.layout.scroll =script.layout.scroll; group.layout.zoom =script.layout.zoom; group.OnGUI(); group.guiRect = group.layout.field; } if (script.guiDebug) Profiler.EndSample(); #endregion #region Drawing connections (before generators to make them display under nodes) if (script.guiDebug) Profiler.BeginSample("Drawing Connections"); foreach(Generator gen in gens.list) { foreach (Generator.Input input in gen.Inputs()) { if (input==null || input.link == null) continue; //input could be null in layered generators if (gen is Portal) { Portal portal = (Portal)gen; if (!portal.drawInputConnection) continue; } script.layout.Spline(input.link.guiConnectionPos, input.guiConnectionPos, color:Generator.CanConnect(input.link,input)? input.guiColor : Color.red); } } if (script.guiDebug) Profiler.EndSample(); #endregion #region creating connections (after generators to make clicking in inout work) if (script.guiDebug) Profiler.BeginSample("Creating Connections"); int dragIdCounter = gens.list.Length+1; foreach (Generator gen in gens.list) foreach (Generator.IGuiInout inout in gen.Inouts()) { if (inout == null) continue; if (script.layout.DragDrop(inout.guiRect, dragIdCounter)) { //finding target Generator.IGuiInout target = null; foreach (Generator gen2 in gens.list) foreach (Generator.IGuiInout inout2 in gen2.Inouts()) if (inout2.guiRect.Contains(script.layout.dragPos)) target = inout2; //converting inout to Input (or Output) and target to Output (or Input) Generator.Input input = inout as Generator.Input; if (input==null) input = target as Generator.Input; Generator.Output output = inout as Generator.Output; if (output==null) output = target as Generator.Output; //connection validity test bool canConnect = input!=null && output!=null && Generator.CanConnect(output,input); //infinite loop test if (canConnect) { Generator outputGen = output.GetGenerator(gens.list); Generator inputGen = input.GetGenerator(gens.list); if (inputGen == outputGen || outputGen.IsDependentFrom(inputGen)) canConnect = false; } //drag //if (script.layout.dragState==Layout.DragState.Drag) //commented out because will not be displayed on repaint otherwise //{ if (input == null)script.layout.Spline(output.guiConnectionPos,script.layout.dragPos, color:Color.red); else if (output == null)script.layout.Spline(script.layout.dragPos, input.guiConnectionPos, color:Color.red); else script.layout.Spline(output.guiConnectionPos, input.guiConnectionPos, color:canConnect? input.guiColor : Color.red); //} //release if (script.layout.dragState==Layout.DragState.Released && input!=null) //on release. Do nothing if input not defined { Undo.RecordObject (gens, "MapMagic Connection"); gens.setDirty = !gens.setDirty; input.Unlink(); if (canConnect) input.Link(output, output.GetGenerator(gens.list)); gens.ChangeGenerator(gen); EditorUtility.SetDirty(gens); } } dragIdCounter++; } if (script.guiDebug) Profiler.EndSample(); #endregion #region Drawing generators if (script.guiDebug) Profiler.BeginSample("Drawing Generators"); for(int i=0; i<gens.list.Length; i++) { Generator gen = gens.list[i]; if (gen is Group) continue; //skipping groups //checking if this generator is withinscript.layout field if (gen.guiRect.x > visibleArea.x+visibleArea.width || gen.guiRect.y > visibleArea.y+visibleArea.height || gen.guiRect.x+gen.guiRect.width < visibleArea.x || gen.guiRect.y+gen.guiRect.height < visibleArea.y) if (gen.guiRect.width > 0.001f &&script.layout.dragState != Layout.DragState.Drag) continue; //if guiRect initialized and not dragging if (gen.layout == null) gen.layout = new Layout(); gen.layout.field = gen.guiRect; gen.layout.field.width = MapMagic.instance.guiGeneratorWidth; //gen.layout.OnBeforeChange -= RecordGeneratorUndo; //gen.layout.OnBeforeChange += RecordGeneratorUndo; gen.layout.undoObject = gens; gen.layout.undoName = "MapMagic Generators Change"; gen.layout.dragChange = true; gen.layout.disabled = locked; //copyscript.layout params gen.layout.scroll =script.layout.scroll; gen.layout.zoom =script.layout.zoom; //drawing if (script.guiDebug) Profiler.BeginSample("Generator GUI"); gen.OnGUIBase(); if (script.guiDebug) Profiler.EndSample(); //instant generate on params change if (gen.layout.change) { gens.ChangeGenerator(gen); repaint=true; Repaint(); EditorUtility.SetDirty(gens); } if (gen.guiRect.width<1 && gen.guiRect.height<1) { repaint=true; Repaint(); } //repainting if some of the generators rect is 0 gen.guiRect = gen.layout.field; } if (script.guiDebug) Profiler.EndSample(); #endregion #region Toolbar if (script.guiDebug) Profiler.BeginSample("Toolbar"); if (script.toolbarLayout==null) script.toolbarLayout = new Layout(); script.toolbarLayout.margin = 0; script.toolbarLayout.rightMargin = 0; script.toolbarLayout.field.width = this.position.width; script.toolbarLayout.field.height = 18; script.toolbarLayout.cursor = new Rect(); //script.toolbarLayout.window = this; script.toolbarLayout.Par(18, padding:0); EditorGUI.LabelField(script.toolbarLayout.field, "", EditorStyles.toolbarButton); //drawing state icon script.toolbarLayout.Inset(25); if (!MapMagic.instance.terrains.complete) { script.toolbarLayout.Icon("MapMagic_Loading", new Rect(5,0,16,16), animationFrames:12); Repaint(); } else script.toolbarLayout.Icon("MapMagic_Success", new Rect(5,0,16,16)); //TODO: changed sign //generate buttons if (GUI.Button(script.toolbarLayout.Inset(120,padding:0), "Generate Changed", EditorStyles.toolbarButton) && MapMagic.instance.enabled) MapMagic.instance.Generate(); if (GUI.Button(script.toolbarLayout.Inset(120,padding:0), "Force Generate All", EditorStyles.toolbarButton) && MapMagic.instance.enabled) MapMagic.instance.ForceGenerate(); //seed field script.toolbarLayout.Inset(10); Rect seedLabelRect = script.toolbarLayout.Inset(34); seedLabelRect.y+=1; seedLabelRect.height-=4; Rect seedFieldRect = script.toolbarLayout.Inset(64); seedFieldRect.y+=2; seedFieldRect.height-=4; EditorGUI.LabelField(seedLabelRect, "Seed:", EditorStyles.miniLabel); int newSeed = EditorGUI.IntField(seedFieldRect, MapMagic.instance.seed, EditorStyles.toolbarTextField); if (newSeed != MapMagic.instance.seed) { MapMagic.instance.seed = newSeed; if (MapMagic.instance.instantGenerate) MapMagic.instance.ForceGenerate(); } //right part script.toolbarLayout.Inset(script.toolbarLayout.field.width - script.toolbarLayout.cursor.x - 150,padding:0); //drawing exit biome button Rect biomeRect = script.toolbarLayout.Inset(80, padding:0); if (MapMagic.instance.guiGens != null && MapMagic.instance.guiGens != MapMagic.instance.gens) { if (script.toolbarLayout.Button("", biomeRect, icon:"MapMagic_ExitBiome", style:EditorStyles.toolbarButton)) MapMagic.instance.guiGens = null; script.toolbarLayout.Label("Exit Biome", new Rect(script.toolbarLayout.cursor.x-60, script.toolbarLayout.cursor.y+3, 60, script.toolbarLayout.cursor.height), fontSize:9); } //focus button // if (GUI.Button(script.toolbarLayout.Inset(100,padding:0), "Focus", EditorStyles.toolbarButton)) FocusOnGenerators(); if (script.toolbarLayout.Button("", script.toolbarLayout.Inset(23,padding:0), icon:"MapMagic_Focus", style:EditorStyles.toolbarButton)) FocusOnGenerators(); if (script.toolbarLayout.Button("", script.toolbarLayout.Inset(60,padding:0), icon:"MapMagic_Zoom", style:EditorStyles.toolbarButton))script.layout.zoom=1; script.toolbarLayout.Label((int)(script.layout.zoom*100)+"%", new Rect(script.toolbarLayout.cursor.x-42, script.toolbarLayout.cursor.y+3, 42, script.toolbarLayout.cursor.height), fontSize:8); if (script.guiDebug) Profiler.EndSample(); #endregion #region Draging if (script.guiDebug) Profiler.BeginSample("Dragging"); //dragging generators for(int i=gens.list.Length-1; i>=0; i--) { Generator gen = gens.list[i]; if (gen is Group) continue; gen.layout.field = gen.guiRect; //dragging if (script.layout.DragDrop(gen.layout.field, i)) { if (script.layout.dragState == Layout.DragState.Pressed) { Undo.RecordObject (gens, "MapMagic Generators Drag"); gens.setDirty = !gens.setDirty; } if (script.layout.dragState == Layout.DragState.Drag ||script.layout.dragState == Layout.DragState.Released) { //moving inout rects to remove lag //foreach (Generator.IGuiInout inout in gen.Inouts()) // inout.guiRect = new Rect(inout.guiRect.position+layout.dragDelta, inout.guiRect.size); gen.Move(script.layout.dragDelta,true); repaint=true; Repaint(); EditorUtility.SetDirty(gens); } } //saving all generator rects gen.guiRect = gen.layout.field; } //dragging groups for (int i=gens.list.Length-1; i>=0; i--) { //Generator gen = gens.list[i]; Group group = gens.list[i] as Group; if (group == null) continue; group.layout.field = group.guiRect; //resizing group.layout.field =script.layout.ResizeRect(group.layout.field, i+20000); //dragging if (script.layout.DragDrop(group.layout.field, i)) { if (script.layout.dragState == Layout.DragState.Pressed) { Undo.RecordObject (gens, "MapMagic Group Drag"); gens.setDirty = !gens.setDirty; group.Populate(gens); } if (script.layout.dragState == Layout.DragState.Drag ||script.layout.dragState == Layout.DragState.Released) { group.Move(script.layout.dragDelta,true); repaint=true; Repaint(); EditorUtility.SetDirty(gens); } if (script.layout.dragState == Layout.DragState.Released && group != null) gens.SortGroups(); } //saving all group rects group.guiRect = group.layout.field; } if (script.guiDebug) Profiler.EndSample(); #endregion //right-click menus if (Event.current.type == EventType.MouseDown && Event.current.button == 1) DrawPopup(); //debug center //EditorGUI.HelpBox(script.layout.ToLocal(new Rect(-25,-10,50,20)), "Zero", MessageType.None); //assigning portal popup action Portal.OnChooseEnter -= DrawPortalSelector; Portal.OnChooseEnter += DrawPortalSelector; //saving scroll and zoom script.guiScroll =script.layout.scroll; script.guiZoom =script.layout.zoom; //producing synthetic lag to test performance //for (int i=0; i<10; i++) Debug.LogWarning("Lag"); //drawing lock warning if (locked) { script.toolbarLayout.Label("", rect: new Rect(4,20,300,155), helpbox:true); script.toolbarLayout.Label("You are using the demo version of Map Magic. " + "It should be used for evaluation purposes only and has a save limitation: although the node graph could be saved, " + "it could not be edited after the load. " + "You can get a fully functional version at the Asset Store or reset your graph to proceed editing:", rect: new Rect(4,20,300,155), helpbox:true); if (script.toolbarLayout.Button("Get MapMagic at the Asset Store", rect: new Rect(20,120, 260, 22))) Application.OpenURL("https://www.assetstore.unity3d.com/en/#!/content/56762"); if (script.toolbarLayout.Button("Reset node graph", rect: new Rect(20,145, 260, 18))) { MapMagic.instance.gens = ScriptableObject.CreateInstance<GeneratorsAsset>(); gens = MapMagic.instance.gens; MapMagic.instance.guiGens = gens; gens.OnBeforeSerialize(); } } if (script.guiDebug) Profiler.EndSample(); }