Exemple #1
0
    /// <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>();
        }
    }
Exemple #2
0
    /// <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>();
        }
    }
Exemple #3
0
    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 */ }
    }
Exemple #4
0
    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>();
        }
    }
Exemple #5
0
    /// <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);
    }