/// <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>(); } }
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 */ } }