Esempio n. 1
0
        internal override void DrawButtonStrip()
        {
            GUILayout.Space(50);

            GUILayout.BeginVertical();

            if (this.HasModifiedInputs)
            {
                if (GUILayout.Button(TileLang.ParticularText("Action", "Apply Changes"), ExtraEditorStyles.Instance.BigButton))
                {
                    this.OnApplyChanges();
                    GUIUtility.ExitGUI();
                }

                GUILayout.Space(5);

                if (GUILayout.Button(TileLang.ParticularText("Action", "Revert"), ExtraEditorStyles.Instance.BigButton))
                {
                    this.OnRevert();
                    GUIUtility.ExitGUI();
                }
            }
            else
            {
                if (GUILayout.Button(TileLang.ParticularText("Action", "Regenerate"), ExtraEditorStyles.Instance.BigButton))
                {
                    this.OnApplyChanges();
                    GUIUtility.ExitGUI();
                }
            }

            GUILayout.EndVertical();
        }
        private void DrawTilePreviewSection()
        {
            GUILayout.Space(10);

            GUILayout.BeginHorizontal();
            RotorzEditorGUI.Title(TileLang.Text("Tile Previews"));

            GUILayout.FlexibleSpace();

            if (GUILayout.Button(TileLang.ParticularText("Action", "Refresh Previews"), RotorzEditorStyles.Instance.ButtonWide))
            {
                this.OnRefreshPreviews();
                GUIUtility.ExitGUI();
            }

            GUILayout.Space(5);
            GUILayout.EndHorizontal();
            ExtraEditorGUI.SeparatorLight();
            GUILayout.Space(-5);

            GUILayout.BeginVertical(RotorzEditorStyles.Instance.PaddedScrollView);
            this.DrawTilePreviews();
            GUILayout.EndVertical();

            GUILayout.Space(-10);
        }
Esempio n. 3
0
        /// <summary>
        /// Generate autotile tileset atlas from provided autotile artwork.
        /// </summary>
        /// <returns>
        /// The generated autotile tileset atlas.
        /// </returns>
        private Texture2D Generate()
        {
            try {
                EditorUtility.DisplayProgressBar(
                    TileLang.ParticularText("Action", "Generate Autotile Atlas"),
                    TileLang.Text("Preparing atlas texture..."),
                    progress: 0f
                    );

                Texture2D output = this.CreateTextureForExpandedAutotile();
                this.FillTexture(output, new Color());

                int bufferInsetX  = this.halfTileWidth - this.border;
                int bufferInsetY  = this.halfTileHeight - this.border;
                int bufferInsetX2 = bufferInsetX + this.tileOuterWidth;
                int bufferInsetY2 = bufferInsetY + this.tileOuterHeight;

                int outX = 0, outY = 0;

                int   progress = 0;
                float ratio    = 1f / (float)this.map.Length;

                foreach (byte[] orientation in this.map)
                {
                    if (progress++ % 10 == 0)
                    {
                        EditorUtility.DisplayProgressBar(
                            TileLang.ParticularText("Action", "Generate Autotile Atlas"),
                            TileLang.Text("Processing atlas texture..."),
                            progress: (float)progress * ratio
                            );
                    }

                    this.PopulateBuffer(orientation);

                    // Copy from buffer to output texture.
                    for (int by = bufferInsetY, oy = 0; by < bufferInsetY2; ++by, ++oy)
                    {
                        for (int bx = bufferInsetX, ox = 0; bx < bufferInsetX2; ++bx, ++ox)
                        {
                            output.SetPixel(outX + ox, output.height - (outY + oy) - 1, this.GetBufferPixel(bx, by));
                        }
                    }

                    outX += this.tileOuterWidth;
                    if (outX + this.tileOuterWidth > output.width)
                    {
                        outX  = 0;
                        outY += this.tileOuterHeight;
                    }
                }

                output.Apply();
                return(output);
            }
            finally {
                EditorUtility.ClearProgressBar();
            }
        }
Esempio n. 4
0
        private void CopySubtileToBuffer(int x, int y, int subtile, bool ignoreTransparent = false)
        {
            int sourceRow, sourceColumn;

            switch (this.layout)
            {
            //case AutotileStyle.tIDE:
            //    sourceRow = subtile / 8;
            //    sourceColumn = subtile % 8;
            //    break;
            case AutotileLayout.Extended:
                sourceRow    = subtile / 6;
                sourceColumn = subtile % 6;
                break;

            case AutotileLayout.Basic:
                sourceRow    = subtile / 4;
                sourceColumn = subtile % 4;
                break;

            default:
                throw new Exception(string.Format(
                                        /* 0: name of the unsupported autotile format */
                                        TileLang.ParticularText("Error", "Unsupported autotile format '{0}'."),
                                        this.layout
                                        ));
            }

            int sourceX = sourceColumn * this.halfTileWidth;
            int sourceY = sourceRow * this.halfTileHeight;

            if (ignoreTransparent)
            {
                // Find out if there are any non-transparent pixels in subtile.
                Color color = new Color();
                for (int iy = 0; iy < this.halfTileHeight && color.a <= 0.003f; ++iy)
                {
                    for (int ix = 0; ix < this.halfTileWidth && color.a <= 0.003f; ++ix)
                    {
                        color = this.autotileArtwork.GetPixel(sourceX + ix, this.autotileArtwork.height - (sourceY + iy) - 1);
                    }
                }

                // Abort, subtile is entirely transparent.
                if (color.a <= 0.003f)
                {
                    return;
                }
            }

            for (int iy = 0; iy < this.halfTileHeight; ++iy)
            {
                for (int ix = 0; ix < this.halfTileWidth; ++ix)
                {
                    this.SetBufferPixel(x + ix, y + iy, this.autotileArtwork.GetPixel(sourceX + ix, this.autotileArtwork.height - (sourceY + iy) - 1));
                }
            }
        }
Esempio n. 5
0
        private void DrawEdgeCorrectionGUI()
        {
            EditorGUIUtility.labelWidth = 1;
            EditorGUIUtility.fieldWidth = 125;

            GUILayout.BeginVertical();

            ExtraEditorGUI.AbovePrefixLabel(TileLang.Text("Edge Correction"));
            this.inputEdgeCorrectionPreset = (EdgeCorrectionPreset)EditorGUILayout.EnumPopup(this.inputEdgeCorrectionPreset);

            if (this.inputEdgeCorrectionPreset == EdgeCorrectionPreset.Custom)
            {
                ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Border Size (px)"));
                this.inputBorderSize = EditorGUILayout.IntField(this.inputBorderSize, GUILayout.Width(60));

                ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Delta (% of 1px)"));
                GUILayout.BeginHorizontal();
                {
                    this.inputDelta = Mathf.Clamp(EditorGUILayout.FloatField(this.inputDelta, GUILayout.Width(60)), 0f, 1f);

                    float newDelta = GUILayout.HorizontalSlider(this.inputDelta, 0f, +1f, GUILayout.Width(80));
                    if (newDelta != this.inputDelta)
                    {
                        this.inputDelta = (float)((int)(newDelta * 100f)) / 100f;
                    }
                }
                GUILayout.EndHorizontal();
            }
            else
            {
                this.inputBorderSize = 0;
                this.inputDelta      = (this.inputEdgeCorrectionPreset == EdgeCorrectionPreset.InsetUVs) ? 0.5f : 0f;

                EditorGUI.BeginDisabledGroup(true);

                ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Border Size (px)"));
                EditorGUILayout.IntField(this.inputBorderSize, GUILayout.Width(60));

                ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Delta (% of 1px)"));
                GUILayout.BeginHorizontal();
                {
                    EditorGUILayout.FloatField(this.inputDelta, GUILayout.Width(60));
                    GUILayout.HorizontalSlider(this.inputDelta, 0f, +1f, GUILayout.Width(80));
                }
                GUILayout.EndHorizontal();

                EditorGUI.EndDisabledGroup();
            }

            GUILayout.EndVertical();
        }
Esempio n. 6
0
        private void DrawAtlasParametersGUI()
        {
            EditorGUIUtility.labelWidth = 1;
            EditorGUIUtility.fieldWidth = 105;

            GUILayout.BeginVertical();

            EditorGUI.BeginChangeCheck();
            {
                ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Tile Width (px)"));
                this.inputTileWidth = EditorGUILayout.IntField(this.inputTileWidth, GUILayout.Width(60));
                ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Tile Height (px)"));
                this.inputTileHeight = EditorGUILayout.IntField(this.inputTileHeight, GUILayout.Width(60));
            }
            if (EditorGUI.EndChangeCheck())
            {
                this.ClearExpandedAutotileAtlas();

                // Automatically load uncompressed version of autotile artwork if it has
                // not already been loaded.
                if (this.inputNewAutotileArtworkUncompressed == null)
                {
                    this.LoadUncompressedAutotileArtwork(this.inputNewAutotileArtwork);
                }
            }

            GUILayout.Space(10);

            //this.alpha = GUILayout.Toggle(this.alpha, "Alpha Blending");

            using (var content = ControlContent.Basic(
                       TileLang.ParticularText("Property", "Procedural"),
                       TileLang.Text("Autotile brushes are always procedural, however atlas brushes of an autotile atlas can be non-procedural if desired.")
                       )) {
                this.inputProcedural = GUILayout.Toggle(this.inputProcedural, content);
            }

            using (var content = ControlContent.Basic(
                       TileLang.ParticularText("Property", "Clamp Edges"),
                       TileLang.Text("Indicates if outer edges should always be clamped. Often not appropriate when secondary tile acts as ground.")
                       )) {
                if (this.autotileTileset.AutotileLayout == AutotileLayout.Extended && this.inputBorderSize > 0)
                {
                    this.inputClampEdges = GUILayout.Toggle(this.inputClampEdges, content);
                }
            }

            GUILayout.EndVertical();
        }
        private void DrawAtlasParametersGUI()
        {
            EditorGUIUtility.labelWidth = 1;
            EditorGUIUtility.fieldWidth = 105;

            GUILayout.BeginVertical();

            ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Tile Width (px)"));
            this.inputTileWidth = EditorGUILayout.IntField(this.inputTileWidth, GUILayout.Width(60));
            ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Tile Height (px)"));
            this.inputTileHeight = EditorGUILayout.IntField(this.inputTileHeight, GUILayout.Width(60));

            GUILayout.Space(10);

            //_alpha = GUILayout.Toggle(_alpha, "Alpha Blending");

            this.inputProcedural = EditorGUILayout.ToggleLeft(TileLang.ParticularText("Property", "Procedural"), this.inputProcedural);

            GUILayout.EndVertical();
        }
        public void OnGUI()
        {
            GUILayout.Space(10);

            string assetPath = Path.GetDirectoryName(this.tilesetRecord.AssetPath) + "/";

            ExtraEditorGUI.AbovePrefixLabel(TileLang.ParticularText("Property", "Asset Path:"), RotorzEditorStyles.Instance.BoldLabel);
            EditorGUILayout.SelectableLabel(assetPath, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            string buttonTextShowInOS = TileLang.OpensWindow(
                Application.platform == RuntimePlatform.OSXEditor
                    ? TileLang.ParticularText("Action", "Show In Finder")
                    : TileLang.ParticularText("Action", "Show In Explorer"));

            if (GUILayout.Button(buttonTextShowInOS, RotorzEditorStyles.Instance.ButtonWide))
            {
                EditorUtility.OpenWithDefaultApp(assetPath);
                GUIUtility.ExitGUI();
            }

            var atlasTexture = this.tileset.AtlasTexture;

            if (atlasTexture == null)
            {
                GUILayout.Space(10);
                GUILayout.Label(TileLang.Text("Atlas texture is missing."));
                return;
            }

            if (atlasTexture.width != atlasTexture.height || !Mathf.IsPowerOfTwo(atlasTexture.width))
            {
                GUILayout.Space(3);
                EditorGUILayout.HelpBox(TileLang.Text("Atlas texture is not square and/or not a power of two size. This can lead to poor quality results."), MessageType.Warning, true);
                GUILayout.Space(3);
            }
            else
            {
                GUILayout.Space(5);
            }

            this.DrawAtlasTexture();
        }
Esempio n. 9
0
        /// <summary>
        /// Initializes a new instance of the autotile expander utility.
        /// </summary>
        /// <param name="layout">Layout style of autotile.</param>
        /// <param name="autotileArtwork">Autotile artwork to be expanded.</param>
        /// <param name="tileWidth">Width of tile in pixels.</param>
        /// <param name="tileHeight">Height of tile in pixels.</param>
        /// <param name="innerJoins">Indicates if inner joins should be generated.</param>
        /// <param name="border">Size of additional border in pixels to generate.</param>
        /// <param name="clampEdges">Indicates if edges should be clamped instead of tiled.</param>
        public AutotileExpanderUtility(AutotileLayout layout, Texture2D autotileArtwork, int tileWidth, int tileHeight, bool innerJoins, int border, bool clampEdges)
        {
            this.layout          = layout;
            this.autotileArtwork = autotileArtwork;

            switch (layout)
            {
            //case AutotileLayout.tIDE:
            //    _map = _TIDE_STYLE;
            //    break;

            case AutotileLayout.Extended:
                this.PrepareExtendedMap(innerJoins);
                break;

            case AutotileLayout.Basic:
                this.PrepareBasicMap(innerJoins);
                break;
            }

            if (tileWidth % 2 == 1 || tileHeight % 2 == 1)
            {
                throw new Exception(TileLang.ParticularText("Error", "Tile width and height must both be divisible by 2."));
            }

            this.tileWidth  = tileWidth;
            this.tileHeight = tileHeight;
            this.border     = border;
            this.clampEdges = clampEdges;

            this.halfTileWidth   = tileWidth / 2;
            this.halfTileHeight  = tileHeight / 2;
            this.tileOuterWidth  = tileWidth + border * 2;
            this.tileOuterHeight = tileHeight + border * 2;

            this.bufferWidth = tileWidth * 2;
            this.buffer      = new Color[this.bufferWidth * tileHeight * 2];
        }
Esempio n. 10
0
        private static string TemplateTextMatcher(Match match)
        {
            string text;

            string textFunctionName = match.Groups[3].Value;

            switch (textFunctionName)
            {
            case "Text":
                text = TileLang.Text(match.Groups[4].Value);
                break;

            case "ParticularText":
                text = TileLang.ParticularText(match.Groups[4].Value, match.Groups[6].Value);
                break;

            default:
                throw new KeyNotFoundException(string.Format("Unexpected text function '{0}'.", textFunctionName));
            }

            if (match.Groups[2].Value == "OpensWindow")
            {
                text = TileLang.OpensWindow(text);
            }

            text = "\"" + text + "\"";

            if (!match.Groups[2].Success)
            {
                // No wrapping function was added, so any trailing parenthesis does not
                // belong to that, simply copy to output.
                text = text + match.Groups[7].Value;
            }

            return(text);
        }
Esempio n. 11
0
        protected override void OnApplyChanges()
        {
            // Do not proceed if no atlas texture was selected.
            if (this.inputNewAutotileArtwork == null)
            {
                EditorUtility.DisplayDialog(
                    TileLang.ParticularText("Error", "Autotile artwork was not specified"),
                    TileLang.Text("Please select artwork for autotile before proceeding."),
                    TileLang.ParticularText("Action", "Close")
                    );
                return;
            }

            // Warn user if modified atlas will contain impossible brushes.
            if (BrushUtility.WouldHaveImpossibleTilesetBrushes(this.tileset, this.inputTileWidth, this.inputTileHeight, this.inputBorderSize))
            {
                if (!EditorUtility.DisplayDialog(
                        TileLang.Text("Warning, brushes will be deleted"),
                        TileLang.Text("Modified atlas contains fewer tiles than previously. Previously created brushes that are out of range will be deleted.\n\nWould you like to proceed?"),
                        TileLang.ParticularText("Action", "Yes"),
                        TileLang.ParticularText("Action", "No")
                        ))
                {
                    return;
                }
            }

            bool refreshProceduralMeshes = !this.inputProcedural && this.autotileTileset.procedural;

            // If raw uncompressed variation of autotile is not defined generate from
            // current selection.
            if (this.inputNewAutotileArtworkUncompressed == null)
            {
                if (this.inputNewAutotileArtwork == null)
                {
                    Debug.LogError(TileLang.ParticularText("Error", "Invalid autotile artwork was specified."));
                    return;
                }
                this.inputNewAutotileArtworkUncompressed = EditorInternalUtility.LoadTextureUncompressed(this.inputNewAutotileArtwork);
            }

            this.ExpandAutotileArtwork(this.inputBorderSize);

            string tilesetBasePath = this.tilesetRecord.AssetPath.Substring(0, this.tilesetRecord.AssetPath.LastIndexOf('/') + 1);

            // Save texture asset.
            string assetPath = AssetDatabase.GetAssetPath(this.autotileTileset.AtlasTexture);

            if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith(tilesetBasePath))
            {
                assetPath = AssetDatabase.GenerateUniqueAssetPath(tilesetBasePath + "atlas.png");
            }

            this.autotileTileset.AtlasTexture = EditorInternalUtility.SavePngAsset(assetPath, this.expandedAutotileAtlas);

            // Update and save material asset.
            if (this.autotileTileset.AtlasMaterial == null)
            {
                this.autotileTileset.AtlasMaterial             = new Material(Shader.Find("Rotorz/Tileset/Opaque Unlit"));
                this.autotileTileset.AtlasMaterial.mainTexture = this.autotileTileset.AtlasTexture;

                assetPath = AssetDatabase.GenerateUniqueAssetPath(tilesetBasePath + "atlas.mat");
                AssetDatabase.CreateAsset(this.autotileTileset.AtlasMaterial, assetPath);
                AssetDatabase.ImportAsset(assetPath);
            }
            else
            {
                this.autotileTileset.AtlasMaterial.mainTexture = this.autotileTileset.AtlasTexture;
                EditorUtility.SetDirty(this.autotileTileset.AtlasMaterial);
            }

            // Calculate metrics for tileset.
            var metrics = new TilesetMetrics(this.autotileTileset.AtlasTexture, this.inputTileWidth, this.inputTileHeight, this.inputBorderSize, this.inputDelta);

            // Update properties of tileset.
            this.autotileTileset.procedural      = this.inputProcedural;
            this.autotileTileset.ForceClampEdges = this.inputClampEdges;
            this.autotileTileset.rawTexture      = this.inputNewAutotileArtwork;
            this.autotileTileset.SetMetricsFrom(metrics);

            this.ClearExpandedAutotileAtlas();

            EditorUtility.SetDirty(this.autotileTileset);

            // Delete "impossible" tile brushes in tileset.
            // For example, an extra brush for a tile that no longer exists.
            BrushUtility.DeleteImpossibleTilesetBrushes(this.tileset);

            // Ensure that non-procedural meshes are pre-generated if missing.
            if (refreshProceduralMeshes)
            {
                BrushUtility.RefreshNonProceduralMeshes(this.tileset);
            }

            ToolUtility.RepaintBrushPalette();

            // Update procedural meshes for tile systems in scene if necessary.
            // Note: Only update if procedural mode of tileset was not modified.
            if (this.inputProcedural && this.tileset.procedural)
            {
                foreach (TileSystem tileSystem in Object.FindObjectsOfType(typeof(TileSystem)))
                {
                    tileSystem.UpdateProceduralTiles(true);
                }
            }
        }
Esempio n. 12
0
        public static void UseAsPrefabOffset()
        {
            var attachedGameObject = GetPrefabInstance();

            if (attachedGameObject == null || attachedGameObject != Selection.activeGameObject)
            {
                return;
            }

            var attachedTransform = attachedGameObject.transform;
            var tileTransform     = GetTileGameObject(attachedTransform);

            if (tileTransform == null)
            {
                return;
            }

            // Get chunk component.
            var chunk = tileTransform.parent.GetComponent <Chunk>();

            if (chunk.TileSystem == null)
            {
                return;
            }

            var prefab = PrefabUtility.GetCorrespondingObjectFromSource(attachedGameObject) as GameObject;
            //var prefab = PrefabUtility.GetPrefabParent(attachedGameObject) as GameObject;
            var prefabTransform = prefab.transform;

            var tileSystem = chunk.TileSystem;

            // Find object within chunk.
            TileIndex index = chunk.FindTileIndexFromGameObject(attachedTransform);

            if (index != TileIndex.invalid)
            {
                TileData tile = tileSystem.GetTile(index);
                if (tile.brush == null)
                {
                    return;
                }

                Vector3    positionOffset, scaleOffset;
                Quaternion rotationOffset;

                // Convert matrix of attachment into local space of tile system.
                Matrix4x4 matrix = Matrix4x4.TRS(attachedTransform.localPosition, attachedTransform.localRotation, attachedTransform.localScale);
                if (attachedTransform.parent != tileSystem.transform)
                {
                    matrix = tileSystem.transform.worldToLocalMatrix * attachedTransform.parent.localToWorldMatrix * matrix;
                }
                tile.brush.CalculatePrefabOffset(tileSystem, index.row, index.column, tile.Rotation, matrix, out positionOffset, out rotationOffset, out scaleOffset);

                Undo.RecordObject(prefabTransform, TileLang.ParticularText("Action", "Use as Prefab Offset"));
                prefabTransform.localPosition = positionOffset;
                prefabTransform.localRotation = rotationOffset;
                prefabTransform.localScale    = scaleOffset;

                EditorUtility.SetDirty(prefabTransform);

                // Should "Apply Prefab Transform" be enabled for brush?
                if (!tile.brush.applyPrefabTransform)
                {
                    if (EditorUtility.DisplayDialog(
                            TileLang.ParticularText("Action", "Apply Prefab Transform"),
                            string.Format(
                                /* 0: name of brush */
                                TileLang.Text("Prefab offset will have no effect unless 'Apply Prefab Transform' is enabled for brush.\n\nWould you like to enable this for '{0}'?"),
                                tile.brush.name
                                ),
                            TileLang.ParticularText("Action", "Yes"),
                            TileLang.ParticularText("Action", "No")
                            ))
                    {
                        Undo.RecordObject(tile.brush, "");

                        tile.brush.applyPrefabTransform = true;
                        EditorUtility.SetDirty(tile.brush);

                        // Designer window should be repainted since the toggle may be exposed!
                        RotorzWindow.RepaintIfShown <DesignerWindow>();
                    }
                }
            }
        }
        protected virtual void OnApplyChanges()
        {
            // Do not proceed if no atlas texture was selected.
            if (this.inputAtlasTexture == null)
            {
                EditorUtility.DisplayDialog(
                    TileLang.ParticularText("Error", "Atlas texture was not specified"),
                    TileLang.Text("Please select an atlas texture before proceeding."),
                    TileLang.ParticularText("Action", "Close")
                    );
                return;
            }

            // Warn user if modified atlas will contain impossible brushes.
            if (BrushUtility.WouldHaveImpossibleTilesetBrushes(this.tileset, this.inputTileWidth, this.inputTileHeight, this.inputBorderSize))
            {
                if (!EditorUtility.DisplayDialog(
                        TileLang.Text("Warning, brushes will be deleted"),
                        TileLang.Text("Modified atlas contains fewer tiles than previously. Previously created brushes that are out of range will be deleted.\n\nWould you like to proceed?"),
                        TileLang.ParticularText("Action", "Yes"),
                        TileLang.ParticularText("Action", "No")
                        ))
                {
                    return;
                }
            }

            bool refreshNonProceduralMeshes = !this.inputProcedural && this.tileset.procedural;

            string tilesetBasePath = this.tilesetRecord.AssetPath.Substring(0, this.tilesetRecord.AssetPath.LastIndexOf('/') + 1);

            // Update and save material asset.
            if (this.tileset.AtlasMaterial == null)
            {
                this.tileset.AtlasMaterial             = new Material(Shader.Find("Rotorz/Tileset/Opaque Unlit"));
                this.tileset.AtlasMaterial.mainTexture = this.inputAtlasTexture;

                string assetPath = AssetDatabase.GenerateUniqueAssetPath(tilesetBasePath + "atlas.mat");
                AssetDatabase.CreateAsset(this.tileset.AtlasMaterial, assetPath);
                AssetDatabase.ImportAsset(assetPath);
            }
            else
            {
                this.tileset.AtlasMaterial.mainTexture = this.inputAtlasTexture;
                EditorUtility.SetDirty(this.tileset.AtlasMaterial);
            }

            this.tileset.AtlasTexture = this.inputAtlasTexture;

            // Calculate metrics for tileset.
            this.RecalculateMetrics();

            // Update properties of tileset.
            this.tileset.procedural = this.inputProcedural;
            this.tileset.SetMetricsFrom(this.inputTilesetMetrics);

            EditorUtility.SetDirty(this.tileset);

            // Delete "impossible" tile brushes in tileset.
            // For example, an extra brush for a tile that no longer exists.
            BrushUtility.DeleteImpossibleTilesetBrushes(this.tileset);

            // Ensure that non-procedural meshes are pre-generated if missing.
            if (refreshNonProceduralMeshes)
            {
                BrushUtility.RefreshNonProceduralMeshes(this.tileset);
            }

            ToolUtility.RepaintBrushPalette();

            // Update procedural meshes for tile systems in scene if necessary.
            // Note: Only update if procedural mode of tileset was not modified.
            if (this.inputProcedural && this.tileset.procedural)
            {
                foreach (TileSystem system in Object.FindObjectsOfType(typeof(TileSystem)))
                {
                    system.UpdateProceduralTiles(true);
                }
            }
        }
        public void OnSideGUI()
        {
            var atlasTexture = this.tileset.AtlasTexture;

            float restoreLabelWidth = EditorGUIUtility.labelWidth;

            EditorGUIUtility.labelWidth = 85;

            Rect position = EditorGUILayout.BeginVertical(GUILayout.Width(210));

            GUILayout.Space(6);

            this.scrollingInfo = EditorGUILayout.BeginScrollView(this.scrollingInfo, RotorzEditorStyles.Instance.PaddedScrollView);

            if (this.autotileTileset != null)
            {
                GUILayout.Label(TileLang.Text("Autotile Atlas"), RotorzEditorStyles.Instance.BoldLabel);
            }
            else
            {
                GUILayout.Label(TileLang.Text("Atlas"), RotorzEditorStyles.Instance.BoldLabel);
            }

            ++EditorGUI.indentLevel;

            if (this.autotileTileset != null)
            {
                EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Layout"), this.autotileTileset.AutotileLayout.ToString());
                EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Inner Joins"), TileLang.FormatYesNoStatus(this.autotileTileset.HasInnerJoins));
                GUILayout.Space(6);
            }

            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Type"), this.tileset.procedural ? TileLang.Text("Procedural") : TileLang.Text("Non-Procedural"));

            if (atlasTexture != null)
            {
                EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Width"), TileLang.FormatPixelMetric(atlasTexture.width));
                EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Height"), TileLang.FormatPixelMetric(atlasTexture.height));
                GUILayout.Space(6);
            }

            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Rows"), this.tileset.Rows.ToString());
            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Columns"), this.tileset.Columns.ToString());
            --EditorGUI.indentLevel;

            GUILayout.Space(6);

            GUILayout.Label(TileLang.ParticularText("Property", "Tile Size"), RotorzEditorStyles.Instance.BoldLabel);
            ++EditorGUI.indentLevel;
            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Width"), TileLang.FormatPixelMetric(this.tileset.TileWidth));
            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Height"), TileLang.FormatPixelMetric(this.tileset.TileHeight));
            --EditorGUI.indentLevel;

            GUILayout.Space(6);

            GUILayout.Label(TileLang.Text("Edge Correction"), RotorzEditorStyles.Instance.BoldLabel);
            ++EditorGUI.indentLevel;
            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Border"), TileLang.FormatPixelMetric(this.tileset.BorderSize));
            EditorGUILayout.LabelField(TileLang.ParticularText("Property", "Delta"), TileLang.FormatPixelFractionMetric(this.tileset.Delta));
            --EditorGUI.indentLevel;

            EditorGUILayout.EndScrollView();

            EditorGUILayout.EndVertical();

            if (Event.current.type == EventType.Repaint)
            {
                RotorzEditorStyles.Instance.HorizontalSplitter.Draw(
                    new Rect(position.x, position.y, position.width - 6, position.height),
                    GUIContent.none,
                    false, false, false, false
                    );
            }

            EditorGUIUtility.labelWidth = restoreLabelWidth;
        }