Exemplo n.º 1
0
		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();
		}