/// <summary> /// Displays tags available for terrains to select from and those currently chosen for this terrain /// </summary> /// <param name="t"></param> /// <returns></returns> public void DisplayAvaliableForegrounds(TerrainDefinition t) { Color c = TerrainDefinition.GetColor(t.source.foregroundColor); GUILayout.BeginHorizontal(); GUILayout.Label("Theme Color:"); Color newColor = EditorGUILayout.ColorField(c); GUILayout.EndHorizontal(); if (newColor != c) { uint color = (uint)(newColor.r * 255) << 16 | (uint)(newColor.g * 255) << 8 | (uint)(newColor.b * 255); t.source.foregroundColor = color.ToString("X"); MHDatabase.SaveDB <MHTerrain>(); } if (GUILayout.Button("Foreground selector", GUILayout.Width(150))) { SpriteSelectorWindow.OpenWindow(t); } MHSimpleCounter toRemove = null; foreach (MHSimpleCounter fgType in t.source.fgTypes) { GUILayout.BeginHorizontal(); GUI.color = Color.red; if (GUILayout.Button("x", GUILayout.Width(19))) { toRemove = fgType; } GUI.color = Color.white; GUILayout.Label(fgType.name); if (IntField(ref fgType.count)) { MHDatabase.SaveDB <MHTerrain>(); } GUILayout.EndHorizontal(); } if (toRemove != null) { t.source.fgTypes.Remove(toRemove); MHDatabase.SaveDB <MHTerrain>(); } }
/// <summary> /// Displays tags available for terrains to select from and those currently chosen for this terrain /// </summary> /// <param name="t"></param> /// <returns></returns> public void DisplayAvaliableTags(TerrainDefinition t) { GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUI.color = Color.green; if (GUILayout.Button("+", GUILayout.Width(19))) { if (!t.source.typeList.Contains(selectedEnum)) { t.source.typeList.Add(selectedEnum); MHDatabase.SaveDB <MHTerrain>(); } } GUI.color = Color.white; selectedEnum = (MHTerrain.Type)EditorGUILayout.EnumPopup(selectedEnum); GUILayout.EndHorizontal(); int toRemove = -1; for (int i = 0; i < t.source.typeList.Count; i++) { GUILayout.BeginHorizontal(); GUI.color = Color.red; if (GUILayout.Button("x", GUILayout.Width(19))) { toRemove = i; } GUI.color = Color.white; GUILayout.Label(t.source.typeList[i].ToString()); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (toRemove >= 0) { t.source.typeList.RemoveAt(toRemove); MHDatabase.SaveDB <MHTerrain>(); } }
void OnGUI() { if (curentTerrain == null) { return; } // If its first run or refresh have been requested by pressing button we will fetch atlasses available for us in project // so that the user my chose one of them for foreground if (atlasCollection == null || GUILayout.Button("Find Sprite Atlases")) { List <string> atlasses = new List <string>(); atlasMetadata = new List <UFTAtlasMetadata>(); string[] guids = AssetDatabase.FindAssets("t:UFTAtlasMetadata"); foreach (string guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); if (path != null && path.Length > 0) { UFTAtlasMetadata t = AssetDatabase.LoadAssetAtPath(path, typeof(UFTAtlasMetadata)) as UFTAtlasMetadata; if (!atlasMetadata.Contains(t)) { atlasses.Add(t.atlasName); atlasMetadata.Add(t); } } } atlasCollection = atlasses.ToArray(); } if (atlasCollection.Length > 0) { int selected = selectedAtlas == null ? 0 : atlasMetadata.IndexOf(selectedAtlas); if (selected == -1) { selected = 0; } int newSelection = EditorGUILayout.Popup(selected, atlasCollection); if (newSelection != selected || selectedAtlas == null) { selectedAtlas = atlasMetadata[newSelection]; deAtlassedTextures.Clear(); //preparation for reading atlas texture. Its likely that texture is unreadable and compressed. //for this process we will have to change its mode temporarily, and store old setting to reapply them later TextureImporterSettings oldSettings = TextureUtils.ChangeTextureSettings(selectedAtlas.texture, true); if (oldSettings == null) { return; } // Converting part of the atlas texture into separated textures fitting to the scale of the window is done using atlas mipmaps and coordinate scaling foreach (UFTAtlasEntryMetadata m in selectedAtlas.entries) { Rect size = m._pixelRect; int width = Mathf.RoundToInt(size.width); int height = Mathf.RoundToInt(size.height); int minX = Mathf.RoundToInt(size.xMin); int minY = Mathf.RoundToInt(size.yMin); int maxSize = Mathf.Max(width, height); //mipmap levels are x1, x2, x4, x8. to match original texture. //we have to invert this process to find best mipmap level fitting our texture size. // "imageSize +1" ensures that if size is exactly matching we do not need to use smaller mipmap, because division would return less than 1 int mLevel = (int)Mathf.Sqrt(maxSize / (imageSize + 1)); if (selectedAtlas.texture.mipmapCount < mLevel) { mLevel = 0; } //height starts from the bottom of the texture, so we need to find "min" taking into account minY = selectedAtlas.texture.height - minY - height; //scale values using bytewise operations to correct mipmap level width = width >> mLevel; height = height >> mLevel; minX = minX >> mLevel; minY = minY >> mLevel; Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, true); Color[] colors = selectedAtlas.texture.GetPixels(minX, minY, width, height, mLevel); texture.SetPixels(colors); texture.Apply(); deAtlassedTextures[m.name] = texture; } //reapplying original atlas texture settings TextureUtils.ChangeTextureSettings(selectedAtlas.texture, oldSettings); } } else { EditorGUILayout.LabelField("No atlased sprites have been found in resource folders!"); return; } if (selectedAtlas == null || window == null) { return; } //find how many items fit in a row Rect r = window.position; int horizontalCount = Mathf.Max(1, (int)r.width / imageSize); //using try ensures no errors thrown by repaint if the structure of the editor gui change. //they are harmless but annoying when they show for single frame. try { scroll = GUILayout.BeginScrollView(scroll); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); for (int i = 0; i < selectedAtlas.entries.Length; i++) { UFTAtlasEntryMetadata t = selectedAtlas.entries[i]; int index = curentTerrain.source.fgTypes.FindIndex(o => o.name == t.name); if (TextureButton(t, index >= 0)) { if (index >= 0) { curentTerrain.source.fgTypes.RemoveAt(index); MHDatabase.SaveDB <MHTerrain>(); } else { MHSimpleCounter c = new MHSimpleCounter(); c.name = t.name; c.count = 1; curentTerrain.source.fgTypes.Add(c); MHDatabase.SaveDB <MHTerrain>(); } } //end of line if enough elements are in line if (((i + 1) % horizontalCount) == 0) { GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); } } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.EndScrollView(); } catch { /* repaint updates sometimes may get interrupted. Nothing to worry about */ } }
void OnGUI() { bool requiresApply = false; //We now allow to reload definitions of the terrains. Its most likely first thing user have to do when opens this window, //but may be useful as well later when some changes occurs during window session if (GUILayout.Button("Reload definitions")) { window = (TerrainEditor)EditorWindow.GetWindow(typeof(TerrainEditor)); TerrainDefinition.ReloadDefinitions(); return; } if (!DataManager.isInitialized) { GUILayout.Label("Missing data manager initialization!"); return; } if (window == null) { GUILayout.Label("Missing window reference!"); return; } List <TerrainDefinition> terrains = TerrainDefinition.definitions; bool add = false; int del = -1; //Button which allows to create new terrain definition slot GUI.color = Color.green; if (GUILayout.Button("+")) { add = true; requiresApply = true; } GUI.color = Color.white; //this part will calculate how many items in a row we want to display Rect r = window.position; int horizontalCount = Mathf.Max(1, (int)r.width / 610); scrall = EditorGUILayout.BeginScrollView(scrall); GUILayout.BeginHorizontal(); for (int i = 0; i < terrains.Count; i++) { if (i % horizontalCount == 0) { GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); } if (!EditTerrain(terrains[i], ref requiresApply)) { del = i; requiresApply = true; } } GUILayout.EndHorizontal(); //check if any terrain requested removal if (del > -1) { MHTerrain.list.Remove(terrains[del].source); MHDatabase.SaveDB <MHTerrain>(); TerrainDefinition.ReloadDefinitions(); } //check if new terrain definition should be initialized if (add) { MHTerrain terrain = new MHTerrain(); terrain.CreateDBIndex(); MHTerrain.list.Add(terrain); MHDatabase.SaveDB <MHTerrain>(); TerrainDefinition.ReloadDefinitions(); } EditorGUILayout.EndScrollView(); //if any element noticed change, database will save file if (requiresApply) { MHDatabase.SaveDB <MHTerrain>(); } }
/// <summary> /// Single terrain definition edit. /// </summary> /// <param name="t"> terrain definition to display </param> /// <param name="requiresApply">returns information if terrain changed</param> /// <returns></returns> public bool EditTerrain(TerrainDefinition t, ref bool requiresApply) { bool v = true; GUILayout.BeginVertical("Box", GUILayout.Width(600)); GUI.color = Color.red; //button which allows to mark terrain for removal if (GUILayout.Button("x")) { v = false; } GUI.color = Color.white; GUILayout.BeginHorizontal(); //terrain specific tags and settings GUILayout.BeginVertical(GUILayout.Width(200)); GUILayout.BeginHorizontal(); GUI.color = t.source.IsNameUnique() ? Color.white : Color.red; GUILayout.Label("Terrain Name:"); if (TextField(ref t.source.name, GUILayout.Width(110))) { MHDatabase.SaveDB <MHTerrain>(); } GUI.color = Color.white; GUILayout.EndHorizontal(); MHTerrain.Mode m = (MHTerrain.Mode)EditorGUILayout.EnumPopup(t.source.mode, GUILayout.Width(180)); if (m != t.source.mode) { t.source.mode = m; MHDatabase.SaveDB <MHTerrain>(); } DisplayAvaliableTags(t); GUILayout.EndVertical(); //foreground editor for terrain GUILayout.BeginVertical("Box", GUILayout.Width(150)); DisplayAvaliableForegrounds(t); GUILayout.EndVertical(); //texture list used to bake terrain GUILayout.BeginVertical(GUILayout.Width(250)); if (ObjectField <Texture>("Diffuse:", ref t.diffuse, false)) { t.source.diffusePath = GetAssetPath(AssetDatabase.GetAssetPath(t.diffuse)); t.source.UseDiffusenameIfNoName(); requiresApply = true; } if (ObjectField <Texture>("Height:", ref t.height, false)) { t.source.heightPath = GetAssetPath(AssetDatabase.GetAssetPath(t.height)); requiresApply = true; } if (ObjectField <Texture>("Mixer:", ref t.mixer, false)) { t.source.mixerPath = GetAssetPath(AssetDatabase.GetAssetPath(t.mixer)); requiresApply = true; } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); return(v); }