예제 #1
0
 public STETilemap GetDefaultTilemapForCurrentTileSelection()
 {
     if (SelectedTilemap && SelectedTilemap.Tileset)
     {
         if (SelectedTilemap.Tileset.SelectedTileId != Tileset.k_TileId_Empty)
         {
             return(GetDefaultTilemapForTileOrBrush(SelectedTilemap.Tileset.SelectedTileId, m_dicTileDefaultTilemap));
         }
         else if (SelectedTilemap.Tileset.SelectedBrushId != Tileset.k_BrushId_Default)
         {
             return(GetDefaultTilemapForTileOrBrush(SelectedTilemap.Tileset.SelectedBrushId, m_dicBrushDefaultTilemap));
         }
         else if (SelectedTilemap.Tileset.TileSelection != null && SelectedTilemap.Tileset.TileSelection.selectionData.Count > 0)
         {
             uint tileData = SelectedTilemap.Tileset.TileSelection.selectionData[0];
             int  brushId  = Tileset.GetBrushIdFromTileData(tileData);
             if (brushId != Tileset.k_BrushId_Default)
             {
                 return(GetDefaultTilemapForTileOrBrush(brushId, m_dicBrushDefaultTilemap));
             }
             else
             {
                 int tileId = Tileset.GetTileIdFromTileData(tileData);
                 if (tileId != Tileset.k_TileId_Empty)
                 {
                     return(GetDefaultTilemapForTileOrBrush(tileId, m_dicTileDefaultTilemap));
                 }
             }
         }
     }
     return(null);
 }
예제 #2
0
        /// <summary>
        /// Return the tile at the grid position
        /// </summary>
        /// <param name="gridX"></param>
        /// <param name="gridY"></param>
        /// <returns></returns>
        public Tile GetTile(int gridX, int gridY)
        {
            uint tileData = GetTileData(gridX, gridY);
            int  tileId   = Tileset.GetTileIdFromTileData(tileData);

            return(Tileset.GetTile(tileId));
        }
예제 #3
0
        static public Texture2D CreateTexture2DFromTilemap(Tilemap tilemap)
        {
            int       tilePxSizeX = (int)tilemap.Tileset.TilePxSize.x;
            int       tilePxSizeY = (int)tilemap.Tileset.TilePxSize.y;
            Texture2D output      = new Texture2D(tilemap.GridWidth * tilePxSizeX, tilemap.GridHeight * tilePxSizeY, TextureFormat.ARGB32, false);

            output.filterMode = FilterMode.Point;
            output.SetPixels32(new Color32[output.width * output.height]);
            output.Apply();
            Texture2D atlasTexture = tilemap.Tileset.AtlasTexture;

            System.Action <Tilemap, int, int, uint> action = (Tilemap source, int gridX, int gridY, uint tileData) =>
            {
                gridX -= source.MinGridX;
                gridY -= source.MinGridY;
                Tile tile = tilemap.Tileset.GetTile(Tileset.GetTileIdFromTileData(tileData));
                if (tile != null)
                {
                    Color[] srcTileColors = atlasTexture.GetPixels(Mathf.RoundToInt(tile.uv.x * atlasTexture.width), Mathf.RoundToInt(tile.uv.y * atlasTexture.height), tilePxSizeX, tilePxSizeY);
                    output.SetPixels(gridX * tilePxSizeX, gridY * tilePxSizeY, tilePxSizeX, tilePxSizeY, srcTileColors);
                }
            };
            IterateTilemapWithAction(tilemap, action);
            output.Apply();
            return(output);
        }
예제 #4
0
        /// <summary>
        /// Return a tile parameter (bool, int, float, string or UnityEngine.Object) from a tiledata.
        /// It takes first the parameter from a brush, if possible, then from a tile.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tileset"></param>
        /// <param name="tileData"></param>
        /// <param name="paramName"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        static public T GetTileParameter <T>(Tileset tileset, uint tileData, string paramName, T defaultValue = default(T))
        {
            Tile         tile  = tileset.GetTile(Tileset.GetTileIdFromTileData(tileData));
            TilesetBrush brush = tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData));
            T            value = defaultValue;

            if (brush)
            {
                value = brush.Params.GetParam <T>(paramName, defaultValue);
            }
            if (tile != null && EqualityComparer <T> .Default.Equals(value, defaultValue))
            {
                value = tile.paramContainer.GetParam <T>(paramName, defaultValue);
            }
            return(value);
        }
예제 #5
0
        private void SetDefaultTilemapFromTileData(STETilemap tilemap, int gx, int gy, uint tileData)
        {
            int brushId = Tileset.GetBrushIdFromTileData(tileData);

            if (brushId != Tileset.k_BrushId_Default)
            {
                m_target.SetBrushDefaultTilemap(brushId, tilemap);
            }
            else
            {
                int tileId = Tileset.GetTileIdFromTileData(tileData);
                if (tileId != Tileset.k_TileId_Empty)
                {
                    m_target.SetTileDefaultTilemap(tileId, tilemap);
                }
            }
        }
예제 #6
0
        public bool SetRenderTile(STETilemap tilemap, uint tileData)
        {
            m_parentTilemap = tilemap;
            Tile tile = tilemap.Tileset.GetTile(Tileset.GetTileIdFromTileData(tileData));

            if (tile != null)
            {
                m_meshRenderer.material       = tilemap.Material;
                m_meshRenderer.sortingLayerID = tilemap.SortingLayerID;
                m_meshRenderer.sortingOrder   = tilemap.OrderInLayer;
                Vector2   cellSizeDiv2 = tilemap.CellSize / 2f;
                Vector3[] vertices     = new Vector3[4]
                {
                    new Vector3(-cellSizeDiv2.x, -cellSizeDiv2.y, 0),
                    new Vector3(cellSizeDiv2.x, -cellSizeDiv2.y, 0),
                    new Vector3(-cellSizeDiv2.x, cellSizeDiv2.y, 0),
                    new Vector3(cellSizeDiv2.x, cellSizeDiv2.y, 0),
                };
                int[]     triangles = new int[] { 3, 0, 2, 0, 3, 1 };
                Vector2[] uvs       = new Vector2[]
                {
                    new Vector2(tile.uv.xMin, tile.uv.yMin),
                    new Vector2(tile.uv.xMax, tile.uv.yMin),
                    new Vector2(tile.uv.xMin, tile.uv.yMax),
                    new Vector2(tile.uv.xMax, tile.uv.yMax),
                };

                if (!m_meshFilter.sharedMesh)
                {
                    m_meshFilter.sharedMesh = new Mesh();
                }
                m_meshFilter.sharedMesh.name = "Quad";
                Mesh mesh = m_meshFilter.sharedMesh;
                mesh.Clear();
                mesh.vertices  = vertices;
                mesh.triangles = triangles;
                mesh.uv        = uvs;
                mesh.RecalculateNormals();
                return(true);
            }
            return(false);
        }
예제 #7
0
        /// <summary>
        /// Get the parameter container from tileData if tileData contains a tile with parameters or Null in other case
        /// </summary>
        /// <param name="tilemap"></param>
        /// <param name="tileData"></param>
        /// <returns></returns>
        static public ParameterContainer GetParamsFromTileData(STETilemap tilemap, uint tileData)
        {
            int          brushId = Tileset.GetBrushIdFromTileData(tileData);
            TilesetBrush brush   = tilemap.Tileset.FindBrush(brushId);

            if (brush)
            {
                return(brush.Params);
            }
            else
            {
                int  tileId = Tileset.GetTileIdFromTileData(tileData);
                Tile tile   = tilemap.Tileset.GetTile(tileId);
                if (tile != null)
                {
                    return(tile.paramContainer);
                }
            }
            return(null);
        }
예제 #8
0
        public static Sprite GetOrCreateSprite(TilemapChunk.OnTilePrefabCreationData data)
        {
            Sprite sprite = null;
            int    tileId = Tileset.GetTileIdFromTileData(data.ParentTilemap.GetTileData(data.GridX, data.GridY));
            Tile   tile   = data.ParentTilemap.Tileset.GetTile(tileId);

            if (tile != null)
            {
                float   pixelsPerUnit = data.ParentTilemap.Tileset.TilePxSize.x / data.ParentTilemap.CellSize.x;
                Vector2 atlasSize     = new Vector2(data.ParentTilemap.Tileset.AtlasTexture.width, data.ParentTilemap.Tileset.AtlasTexture.height);
                Rect    spriteUV      = new Rect(Vector2.Scale(tile.uv.position, atlasSize), Vector2.Scale(tile.uv.size, atlasSize));
                string  spriteName    = data.ParentTilemap.Tileset.name + "_" + tileId + "_" + pixelsPerUnit;
                if (!s_spriteCache.TryGetValue(spriteName, out sprite) || !sprite)
                {
                    sprite      = Sprite.Create(data.ParentTilemap.Tileset.AtlasTexture, spriteUV, new Vector2(.5f, .5f), pixelsPerUnit);
                    sprite.name = spriteName;
                    s_spriteCache[spriteName] = sprite;
                }
            }
            return(sprite);
        }
예제 #9
0
        public override Vector2[] GetMergedSubtileColliderVertices(STETilemap tilemap, int gridX, int gridY, uint tileData)
        {
            uint[] subTiles = GetSubtiles(tilemap, gridX, gridY, tileData);
            if (subTiles != null)
            {
                s_mergedColliderVertexList.Clear();
                for (int i = 0; i < subTiles.Length; ++i)
                {
                    uint subTileData = subTiles[i];
                    Tile tile        = tilemap.Tileset.GetTile(Tileset.GetTileIdFromTileData(subTiles[i]));
                    if (tile != null && tile.collData.type != eTileCollider.None)
                    {
                        TileColliderData tileCollData = tile.collData;
                        if ((subTileData & (Tileset.k_TileFlag_FlipH | Tileset.k_TileFlag_FlipV | Tileset.k_TileFlag_Rot90)) != 0)
                        {
                            tileCollData = tileCollData.Clone();
                            tileCollData.ApplyFlippingFlags(subTileData);
                        }
                        Vector2[] vertices = tile.collData.GetVertices();
                        if (vertices != null)
                        {
                            for (int v = 0; v < vertices.Length; ++v)
                            {
                                Vector2 v0, v1;
                                if (v < vertices.Length - 1)
                                {
                                    v0 = vertices[v];
                                    v1 = vertices[v + 1];
                                }
                                else
                                {
                                    v0 = vertices[v];
                                    v1 = vertices[0];
                                }

                                if (i == 0 || i == 2) //left side
                                {
                                    if (v0.x >= .5f && v1.x >= .5f)
                                    {
                                        continue;
                                    }
                                    float newY = v0.y + (.5f - v0.x) * (v1.y - v0.y) / (v1.x - v0.x);
                                    if (v0.x > .5f)
                                    {
                                        v0.y = newY;
                                        v0.x = .5f;
                                    }
                                    else if (v1.x > .5f)
                                    {
                                        v1.y = newY;
                                        v1.x = .5f;
                                    }
                                }
                                else // right side
                                {
                                    if (v0.x <= .5f && v1.x <= .5f)
                                    {
                                        continue;
                                    }
                                    float newY = v0.y + (.5f - v0.x) * (v1.y - v0.y) / (v1.x - v0.x);
                                    if (v0.x < .5f)
                                    {
                                        v0.y = newY;
                                        v0.x = .5f;
                                    }
                                    else if (v1.x < .5f)
                                    {
                                        v1.y = newY;
                                        v1.x = .5f;
                                    }
                                }

                                if (i == 0 || i == 1) //bottom side
                                {
                                    if (v0.y >= .5f && v1.y >= .5f)
                                    {
                                        continue;
                                    }
                                    float newX = v0.x + (.5f - v0.y) * (v1.x - v0.x) / (v1.y - v0.y);
                                    if (v0.y > .5f)
                                    {
                                        v0.x = newX;
                                        v0.y = .5f;
                                    }
                                    else if (v1.y > .5f)
                                    {
                                        v1.x = newX;
                                        v1.y = .5f;
                                    }
                                }
                                else // top side
                                {
                                    if (v0.y <= .5f && v1.y <= .5f)
                                    {
                                        continue;
                                    }
                                    float newX = v0.x + (.5f - v0.y) * (v1.x - v0.x) / (v1.y - v0.y);
                                    if (v0.y < .5f)
                                    {
                                        v0.x = newX;
                                        v0.y = .5f;
                                    }
                                    else if (v1.y < .5f)
                                    {
                                        v1.x = newX;
                                        v1.y = .5f;
                                    }
                                }

                                s_mergedColliderVertexList.Add(v0);
                                s_mergedColliderVertexList.Add(v1);
                            }
                        }
                    }
                }
                return(s_mergedColliderVertexList.ToArray());
            }
            return(null);
        }
예제 #10
0
        private void DoPaintInspector()
        {
            Event e = Event.current;

            Tilemap tilemap = (Tilemap)target;

            if (DoToolBar() ||
                DragAndDrop.objectReferences.Length > 0 || // hide brush when user is dragging a prefab into the scene
                EditorWindow.mouseOverWindow != SceneView.currentDrawingSceneView)    // hide brush when it's not over the scene view
            {
                m_brushVisible = false;
                SceneView.RepaintAll();
                return;
            }

            int controlID = GUIUtility.GetControlID(FocusType.Passive);

            HandleUtility.AddDefaultControl(controlID);
            EventType currentEventType = Event.current.GetTypeForControl(controlID);
            bool      skip             = false;
            int       saveControl      = GUIUtility.hotControl;

            try
            {
                if (currentEventType == EventType.Layout)
                {
                    skip = true;
                }
                else if (currentEventType == EventType.ScrollWheel)
                {
                    skip = true;
                }

                if (tilemap.Tileset == null)
                {
                    return;
                }

                if (!skip)
                {
                    if (e.type == EventType.KeyDown)
                    {
                        if (e.keyCode == ShortcutKeys.k_FlipH)
                        {
                            BrushBehaviour.GetOrCreateBrush(tilemap).FlipH(!e.shift);
                            e.Use(); // Use key event
                        }
                        else if (e.keyCode == ShortcutKeys.k_FlipV)
                        {
                            BrushBehaviour.GetOrCreateBrush(tilemap).FlipV(!e.shift);
                            e.Use(); // Use key event
                        }
                        else if (e.keyCode == ShortcutKeys.k_Rot90)
                        {
                            BrushBehaviour.GetOrCreateBrush(tilemap).Rot90(!e.shift);
                            e.Use(); // Use key event
                        }
                        else if (e.keyCode == ShortcutKeys.k_Rot90Back)
                        {
                            BrushBehaviour.GetOrCreateBrush(tilemap).Rot90Back(!e.shift);
                            e.Use(); // Use key event
                        }
                    }

                    EditorGUIUtility.AddCursorRect(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), MouseCursor.Arrow);
                    GUIUtility.hotControl = controlID;
                    {
                        Plane   chunkPlane = new Plane(tilemap.transform.forward, tilemap.transform.position);
                        Vector2 mousePos   = Event.current.mousePosition; mousePos.y = Screen.height - mousePos.y;
                        Ray     ray        = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        float   dist;
                        if (chunkPlane.Raycast(ray, out dist))
                        {
                            Rect rTile = new Rect(0, 0, m_tilemap.CellSize.x, m_tilemap.CellSize.y);
                            rTile.position = tilemap.transform.InverseTransformPoint(ray.GetPoint(dist));

                            Vector2 tilePos = rTile.position;
                            if (tilePos.x < 0)
                            {
                                tilePos.x -= m_tilemap.CellSize.x;
                            }
                            if (tilePos.y < 0)
                            {
                                tilePos.y -= m_tilemap.CellSize.y;
                            }
                            tilePos.x     -= tilePos.x % m_tilemap.CellSize.x;
                            tilePos.y     -= tilePos.y % m_tilemap.CellSize.y;
                            rTile.position = tilePos;


                            Vector2 startPos            = new Vector2(Mathf.Min(m_startDragging.x, m_endDragging.x), Mathf.Min(m_startDragging.y, m_endDragging.y));
                            Vector2 endPos              = new Vector2(Mathf.Max(m_startDragging.x, m_endDragging.x), Mathf.Max(m_startDragging.y, m_endDragging.y));
                            Vector2 selectionSnappedPos = BrushUtil.GetSnappedPosition(startPos, m_tilemap.CellSize);
                            Vector2 selectionSize       = BrushUtil.GetSnappedPosition(endPos, m_tilemap.CellSize) - selectionSnappedPos + m_tilemap.CellSize;

                            BrushBehaviour brush = BrushBehaviour.GetOrCreateBrush(tilemap);
                            // Update brush transform
                            m_localPaintPos = (Vector2)tilemap.transform.InverseTransformPoint(ray.GetPoint(dist));
                            Vector2 brushSnappedPos = BrushUtil.GetSnappedPosition(brush.Offset + m_localPaintPos, m_tilemap.CellSize);
                            brush.transform.rotation   = tilemap.transform.rotation;
                            brush.transform.localScale = tilemap.transform.lossyScale;
                            brush.transform.position   = tilemap.transform.TransformPoint(new Vector3(brushSnappedPos.x, brushSnappedPos.y, -0.01f));
                            //---

                            int prevMouseGridX = m_mouseGridX;
                            int prevMouseGridY = m_mouseGridY;
                            if (e.isMouse)
                            {
                                m_mouseGridX = BrushUtil.GetGridX(m_localPaintPos, tilemap.CellSize);
                                m_mouseGridY = BrushUtil.GetGridY(m_localPaintPos, tilemap.CellSize);
                            }
                            bool isMouseGridChanged = prevMouseGridX != m_mouseGridX || prevMouseGridY != m_mouseGridY;
                            //Update Fill Preview
                            if (GetBrushMode() == eBrushMode.Fill && isMouseGridChanged)
                            {
                                m_fillPreview.Clear();
                                TilemapDrawingUtils.FloodFillPreview(tilemap, brush.Offset + m_localPaintPos, brush.BrushTilemap.GetTileData(0, 0), m_fillPreview);
                            }

                            if (
                                (EditorWindow.focusedWindow == EditorWindow.mouseOverWindow) && // fix painting tiles when closing another window popup over the SceneView like GameObject Selection window
                                (e.type == EventType.MouseDown || e.type == EventType.MouseDrag && isMouseGridChanged)
                                )
                            {
                                if (e.button == 0)
                                {
                                    if (m_dblClick.IsDblClick && brush.BrushTilemap.GridWidth == 1 && brush.BrushTilemap.GridHeight == 1)
                                    {
                                        // Restore previous tiledata modified by Paint, because before the double click, a single click is done before
                                        tilemap.SetTileData(brush.Offset + m_localPaintPos, m_floodFillRestoredTileData);
                                        brush.FloodFill(tilemap, brush.Offset + m_localPaintPos, brush.BrushTilemap.GetTileData(0, 0));
                                    }
                                    // Do a brush paint action
                                    else
                                    {
                                        switch (GetBrushMode())
                                        {
                                        case eBrushMode.Paint:
                                            m_floodFillRestoredTileData = tilemap.GetTileData(m_mouseGridX, m_mouseGridY);
                                            brush.Paint(tilemap, brush.Offset + m_localPaintPos);
                                            break;

                                        case eBrushMode.Erase:
                                            brush.Erase(tilemap, brush.Offset + m_localPaintPos);
                                            break;

                                        case eBrushMode.Fill:
                                            brush.FloodFill(tilemap, brush.Offset + m_localPaintPos, brush.BrushTilemap.GetTileData(0, 0));
                                            break;
                                        }
                                    }
                                }
                                else if (e.button == 1)
                                {
                                    if (e.type == EventType.MouseDown)
                                    {
                                        m_isDragging = true;
                                        brush.BrushTilemap.ClearMap();
                                        m_startDragging = m_endDragging = m_localPaintPos;
                                    }
                                    else
                                    {
                                        m_endDragging = m_localPaintPos;
                                    }
                                }
                            }
                            else if (e.type == EventType.MouseUp)
                            {
                                if (e.button == 1) // right mouse button
                                {
                                    m_isDragging = false;
                                    ResetBrushMode();
                                    // Copy one tile
                                    if (selectionSize.x <= m_tilemap.CellSize.x && selectionSize.y <= m_tilemap.CellSize.y)
                                    {
                                        uint tileData = tilemap.GetTileData(m_localPaintPos);
                                        if (tileData == Tileset.k_TileData_Empty)
                                        {
                                            tilemap.Tileset.SelectedTileId = Tileset.k_TileId_Empty;
                                            brush.BrushTilemap.SetTileData(0, 0, Tileset.k_TileData_Empty);
                                        }
                                        else
                                        {
                                            int brushId = Tileset.GetBrushIdFromTileData(tileData);
                                            int tileId  = Tileset.GetTileIdFromTileData(tileData);

                                            // Select the copied tile in the tileset, alternating between the brush and the tile drawn by the brush
                                            if (brushId > 0 && brushId != tilemap.Tileset.SelectedBrushId)
                                            {
                                                tilemap.Tileset.SelectedBrushId = brushId;
                                            }
                                            else
                                            {
                                                tilemap.Tileset.SelectedTileId = tileId;
                                                brush.BrushTilemap.SetTileData(0, 0, tileData & ~Tileset.k_TileDataMask_BrushId); // keep tile flags
                                            }
                                        }

                                        // Cut tile if key shift is pressed
                                        if (e.shift)
                                        {
                                            int startGridX = BrushUtil.GetGridX(startPos, m_tilemap.CellSize);
                                            int startGridY = BrushUtil.GetGridY(startPos, m_tilemap.CellSize);
                                            brush.CutRect(tilemap, startGridX, startGridY, startGridX, startGridY);
                                        }

                                        brush.BrushTilemap.UpdateMesh();
                                        brush.Offset = Vector2.zero;
                                    }
                                    // copy a rect of tiles
                                    else
                                    {
                                        int startGridX = BrushUtil.GetGridX(startPos, m_tilemap.CellSize);
                                        int startGridY = BrushUtil.GetGridY(startPos, m_tilemap.CellSize);
                                        int endGridX   = BrushUtil.GetGridX(endPos, m_tilemap.CellSize);
                                        int endGridY   = BrushUtil.GetGridY(endPos, m_tilemap.CellSize);

                                        // Cut tile if key shift is pressed
                                        if (e.shift)
                                        {
                                            brush.CutRect(tilemap, startGridX, startGridY, endGridX, endGridY);
                                        }
                                        else
                                        {
                                            brush.CopyRect(tilemap, startGridX, startGridY, endGridX, endGridY);
                                        }
                                        brush.Offset.x = m_endDragging.x > m_startDragging.x ? -(endGridX - startGridX) * tilemap.CellSize.x : 0f;
                                        brush.Offset.y = m_endDragging.y > m_startDragging.y ? -(endGridY - startGridY) * tilemap.CellSize.y : 0f;
                                    }
                                }
                            }

                            if (m_isDragging)
                            {
                                Rect rGizmo = new Rect(selectionSnappedPos, selectionSize);
                                HandlesEx.DrawRectWithOutline(tilemap.transform, rGizmo, new Color(), Color.white);
                            }
                            else // Draw brush border
                            {
                                Rect  rBound = new Rect(brush.BrushTilemap.MapBounds.min, brush.BrushTilemap.MapBounds.size);
                                Color fillColor;
                                switch (GetBrushMode())
                                {
                                case eBrushMode.Paint:
                                    fillColor = new Color(0, 0, 0, 0);
                                    break;

                                case eBrushMode.Erase:
                                    fillColor = new Color(1f, 0f, 0f, 0.1f);
                                    break;

                                case eBrushMode.Fill:
                                    fillColor = new Color(1f, 1f, 0f, 0.2f);
                                    break;

                                default:
                                    fillColor = new Color(0, 0, 0, 0);
                                    break;
                                }
                                HandlesEx.DrawRectWithOutline(brush.transform, rBound, fillColor, new Color(1, 1, 1, 0.2f));
                            }
                        }
                    }

                    if (currentEventType == EventType.MouseDrag && Event.current.button < 2) // 2 is for central mouse button
                    {
                        // avoid dragging the map
                        Event.current.Use();
                    }
                }
            }
            // Avoid loosing the hotControl because of a triggered exception
            catch (System.Exception ex)
            {
                Debug.LogException(ex);
            }

            SceneView.RepaintAll();
            GUIUtility.hotControl = saveControl;
        }
        static public Texture2D CreateTexture2DFromTilemap(STETilemap tilemap)
        {
            MakeTextureReadable(tilemap.Tileset.AtlasTexture);
            int       tilePxSizeX = (int)tilemap.Tileset.TilePxSize.x;
            int       tilePxSizeY = (int)tilemap.Tileset.TilePxSize.y;
            Texture2D output      = new Texture2D(tilemap.GridWidth * tilePxSizeX, tilemap.GridHeight * tilePxSizeY, TextureFormat.ARGB32, false);

            output.filterMode = FilterMode.Point;
            output.SetPixels32(new Color32[output.width * output.height]);
            output.Apply();
            System.Action <STETilemap, int, int, uint> action = (STETilemap source, int gridX, int gridY, uint tileData) =>
            {
                gridX -= source.MinGridX;
                gridY -= source.MinGridY;
                Tile tile = tilemap.Tileset.GetTile(Tileset.GetTileIdFromTileData(tileData));
                if (tile != null)
                {
                    Texture2D atlasTexture = tilemap.Tileset.AtlasTexture;
                    int       tx           = Mathf.RoundToInt(tile.uv.x * atlasTexture.width);
                    int       ty           = Mathf.RoundToInt(tile.uv.y * atlasTexture.height);
                    int       tw           = tilePxSizeX;
                    int       th           = tilePxSizeY;
                    Sprite    prefabSprite = null;
                    if (tile.prefabData.prefab)
                    {
                        SpriteRenderer spriteRenderer = tile.prefabData.prefab.GetComponent <SpriteRenderer>();
                        if (spriteRenderer && spriteRenderer.sprite)
                        {
                            prefabSprite = spriteRenderer.sprite;
                            MakeTextureReadable(spriteRenderer.sprite.texture);
                            atlasTexture = spriteRenderer.sprite.texture;
                            tx           = Mathf.RoundToInt(spriteRenderer.sprite.textureRect.x);
                            ty           = Mathf.RoundToInt(spriteRenderer.sprite.textureRect.y);
                            tw           = Mathf.RoundToInt(spriteRenderer.sprite.textureRect.width);
                            th           = Mathf.RoundToInt(spriteRenderer.sprite.textureRect.height);
                        }
                    }
                    bool    flipH         = (tileData & Tileset.k_TileFlag_FlipH) != 0;
                    bool    flipV         = (tileData & Tileset.k_TileFlag_FlipV) != 0;
                    bool    rot90         = (tileData & Tileset.k_TileFlag_Rot90) != 0;
                    Color[] srcTileColors = atlasTexture.GetPixels(tx, ty, tw, th);
                    if (flipH)
                    {
                        Color[] tempArr = new Color[0];
                        for (int i = 0; i < th; ++i)
                        {
                            tempArr = tempArr.Concat(srcTileColors.Skip(tw * i).Take(tw).Reverse()).ToArray();
                        }
                        srcTileColors = tempArr;
                    }
                    if (flipV)
                    {
                        Color[] tempArr = new Color[0];
                        for (int i = th - 1; i >= 0; --i)
                        {
                            tempArr = tempArr.Concat(srcTileColors.Skip(tw * i).Take(tw)).ToArray();
                        }
                        srcTileColors = tempArr;
                    }
                    if (rot90)
                    {
                        Color[] tempArr = new Color[tw * th];
                        for (int x = tw - 1, i = 0; x >= 0; --x)
                        {
                            for (int y = 0; y < th; ++y, ++i)
                            {
                                tempArr[i] = srcTileColors[y * tw + x];
                            }
                        }
                        srcTileColors = tempArr;
                        int temp = tw;
                        tw = th;
                        th = temp;
                    }
                    if (prefabSprite)
                    {
                        Vector2 tileSize = prefabSprite.textureRect.size;
                        Vector2 pivot    = prefabSprite.pivot - prefabSprite.textureRectOffset;
                        if (flipV)
                        {
                            pivot.y = -pivot.y + prefabSprite.textureRect.height;
                        }
                        if (flipH)
                        {
                            pivot.x = -pivot.x + prefabSprite.textureRect.width;
                        }
                        if (rot90)
                        {
                            pivot      = new Vector2(pivot.y, tileSize.x - pivot.x);
                            tileSize.x = prefabSprite.textureRect.size.y;
                            tileSize.y = prefabSprite.textureRect.size.x;
                        }
                        Vector2 offset = pivot - tilemap.Tileset.TilePxSize / 2;// sprite.pivot + sprite.textureRect.position - sprite.textureRectOffset;
                        BlitPixels(output, gridX * tilePxSizeX - Mathf.RoundToInt(offset.x), gridY * tilePxSizeY - Mathf.RoundToInt(offset.y), Mathf.RoundToInt(tileSize.x), Mathf.RoundToInt(tileSize.y), srcTileColors);
                    }
                    else
                    {
                        output.SetPixels(gridX * tilePxSizeX, gridY * tilePxSizeY, tw, th, srcTileColors);
                    }
                }
            };
            TilemapUtils.IterateTilemapWithAction(tilemap, action);
            output.Apply();
            return(output);
        }