Example #1
0
 public virtual uint Refresh(Tilemap tilemap, int gridX, int gridY, uint tileData)
 {
     return(tileData);
 }
Example #2
0
 public virtual uint[] GetSubtiles(Tilemap tilemap, int gridX, int gridY, uint tileData)
 {
     return(null);
 }
Example #3
0
 /// <summary>
 /// Get the world position for the center of a given grid cell position.
 /// </summary>
 /// <param name="gridX"></param>
 /// <param name="gridY"></param>
 /// <returns></returns>
 static public Vector3 GetGridWorldPos(Tilemap tilemap, int gridX, int gridY)
 {
     return(tilemap.transform.TransformPoint(new Vector2((gridX + .5f) * tilemap.CellSize.x, (gridY + .5f) * tilemap.CellSize.y)));
 }
 public virtual Vector2[] GetMergedSubtileColliderVertices(Tilemap tilemap, int gridX, int gridY, uint tileData)
 {
     return(null);
 }
Example #5
0
        public override Vector2[] GetMergedSubtileColliderVertices(Tilemap 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 < tile.collData.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);
        }
Example #6
0
        //https://social.msdn.microsoft.com/Forums/en-US/9d926a16-0051-4ca3-b77c-8095fb489ae2/flood-fill-c?forum=csharplanguage
        public static void FloodFill(Tilemap tilemap, int gridX, int gridY, uint tileData)
        {
            float timeStamp;

            timeStamp = Time.realtimeSinceStartup;
            //float callTimeStamp = timeStamp;

            LinkedList <Point> check = new LinkedList <Point>();
            uint floodFrom           = tilemap.GetTileData(gridX, gridY);

            tilemap.SetTileData(gridX, gridY, tileData);
            bool isBrush = Tileset.GetBrushIdFromTileData(floodFrom) != 0;

            //Debug.Log(" Flood Fill Starts +++++++++++++++ ");
            if (
                isBrush?
                Tileset.GetBrushIdFromTileData(floodFrom) != Tileset.GetBrushIdFromTileData(tileData)
                :
                floodFrom != tileData
                )
            {
                check.AddLast(new Point(gridX, gridY));
                while (check.Count > 0)
                {
                    Point cur = check.First.Value;
                    check.RemoveFirst();

                    foreach (Point off in new Point[] {
                        new Point(0, -1), new Point(0, 1),
                        new Point(-1, 0), new Point(1, 0)
                    })
                    {
                        Point next         = new Point(cur.X + off.X, cur.Y + off.Y);
                        uint  nextTileData = tilemap.GetTileData(next.X, next.Y);
                        if (
                            next.X >= tilemap.MinGridX && next.X <= tilemap.MaxGridX &&
                            next.Y >= tilemap.MinGridY && next.Y <= tilemap.MaxGridY
                            )
                        {
                            if (
                                isBrush?
                                Tileset.GetBrushIdFromTileData(floodFrom) == Tileset.GetBrushIdFromTileData(nextTileData)
                                :
                                floodFrom == nextTileData
                                )
                            {
                                check.AddLast(next);
                                tilemap.SetTileData(next.X, next.Y, tileData);
                            }
                        }
                    }

                    float timePast = Time.realtimeSinceStartup - timeStamp;
                    if (timePast > k_timeToAbortFloodFill)
                    {
#if UNITY_EDITOR
                        int result = UnityEditor.EditorUtility.DisplayDialogComplex("FloodFill is taking too much time", "Do you want to continue for another " + k_timeToAbortFloodFill + " seconds?", "Wait", "Cancel", "Wait and Don't ask again");
                        if (result == 0)
                        {
                            timeStamp = Time.realtimeSinceStartup;
                        }
                        else if (result == 1)
                        {
                            break;
                        }
                        else if (result == 2)
                        {
                            timeStamp = float.MaxValue;
                        }
#else
                        check.Clear();
#endif
                    }
                }
            }

            //Debug.Log("FloodFill Time " + (int)((Time.realtimeSinceStartup - callTimeStamp) * 1000) + "ms");
        }
        private ReorderableList CreateTilemapReorderableList()
        {
            ReorderableList reordList = new ReorderableList(serializedObject, serializedObject.FindProperty("m_tilemaps"), true, true, true, true);

            reordList.displayAdd         = reordList.displayRemove = true;
            reordList.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, "Tilemaps", EditorStyles.boldLabel);
                Texture2D btnTexture = reordList.elementHeight == 0f ? EditorGUIUtility.FindTexture("winbtn_win_max_h") : EditorGUIUtility.FindTexture("winbtn_win_min_h");
                if (GUI.Button(new Rect(rect.width - rect.height, rect.y, rect.height, rect.height), btnTexture, EditorStyles.label))
                {
                    reordList.elementHeight = reordList.elementHeight == 0f ? EditorGUIUtility.singleLineHeight : 0f;
                    reordList.draggable     = reordList.elementHeight > 0f;
                }
            };
            reordList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                var element = reordList.serializedProperty.GetArrayElementAtIndex(index);

                if (Event.current.type == EventType.Repaint)
                {
                    m_reordListRectsDic[m_reordIdx] = rect;
                }
                else if (Event.current.type == EventType.Layout)
                {
                    m_reordListRectsDic.TryGetValue(m_reordIdx, out rect);
                }
                m_reordIdx++;

                rect.y += 2;

                Tilemap          tilemap              = element.objectReferenceValue as Tilemap;
                SerializedObject tilemapSerialized    = new SerializedObject(tilemap);
                SerializedObject tilemapObjSerialized = new SerializedObject(tilemapSerialized.FindProperty("m_GameObject").objectReferenceValue);

                GUILayout.BeginArea(rect);
                EditorGUILayout.BeginHorizontal();
                tilemap.IsVisible = EditorGUILayout.Toggle(tilemap.IsVisible, GUILayout.Width(16));
                EditorGUILayout.PropertyField(tilemapObjSerialized.FindProperty("m_Name"), GUIContent.none);
                if (TilemapEditor.EditMode == TilemapEditor.eEditMode.Collider)
                {
                    SerializedProperty colliderTypeProperty = tilemapSerialized.FindProperty("ColliderType");
                    string[]           colliderTypeNames    = new List <string>(System.Enum.GetNames(typeof(eColliderType)).Select(x => x.Replace('_', ' '))).ToArray();
                    EditorGUI.BeginChangeCheck();
                    colliderTypeProperty.intValue = GUILayout.SelectionGrid(colliderTypeProperty.intValue, colliderTypeNames, colliderTypeNames.Length, GUILayout.MaxHeight(0.9f * EditorGUIUtility.singleLineHeight));
                    if (EditorGUI.EndChangeCheck())
                    {
                        tilemapSerialized.ApplyModifiedProperties();
                        tilemap.Refresh(false, true);
                    }
                }
                else
                {
                    // Sorting Layer and Order in layer
                    EditorGUI.BeginChangeCheck();
                    EditorGUIUtility.labelWidth = 1;
                    EditorGUILayout.PropertyField(tilemapSerialized.FindProperty("m_sortingLayer"), new GUIContent(" "));
                    EditorGUIUtility.labelWidth = 40;
                    EditorGUILayout.PropertyField(tilemapSerialized.FindProperty("m_orderInLayer"), new GUIContent("Order"), GUILayout.MaxWidth(90));
                    EditorGUIUtility.labelWidth = 0;
                    tilemapSerialized.FindProperty("m_orderInLayer").intValue = (tilemapSerialized.FindProperty("m_orderInLayer").intValue << 16) >> 16; // convert from int32 to int16 keeping sign
                    if (EditorGUI.EndChangeCheck())
                    {
                        tilemapSerialized.ApplyModifiedProperties();
                        tilemap.RefreshChunksSortingAttributes();
                        SceneView.RepaintAll();
                    }
                    //---
                }
                EditorGUILayout.EndHorizontal();
                GUILayout.EndArea();

                if (GUI.changed)
                {
                    tilemapObjSerialized.ApplyModifiedProperties();
                }
            };
            reordList.onReorderCallback = (ReorderableList list) =>
            {
                var targetObj   = target as TilemapGroup;
                int sibilingIdx = 0;
                foreach (Tilemap tilemap in targetObj.Tilemaps)
                {
                    tilemap.transform.SetSiblingIndex(sibilingIdx++);
                }
                Repaint();
            };
            reordList.onSelectCallback = (ReorderableList list) =>
            {
                serializedObject.FindProperty("m_selectedIndex").intValue = reordList.index;
                serializedObject.ApplyModifiedProperties();
                GUI.changed = true;
                TileSelectionWindow.RefreshIfVisible();
                TilePropertiesWindow.RefreshIfVisible();
            };
            reordList.onAddCallback = (ReorderableList list) =>
            {
                var targetObj = target as TilemapGroup;
                Undo.RegisterCompleteObjectUndo(targetObj, "New Tilemap");
                GameObject obj = new GameObject();
                Undo.RegisterCreatedObjectUndo(obj, "New Tilemap");
                Tilemap newTilemap = obj.AddComponent <Tilemap>();
                obj.transform.parent = targetObj.transform;
                obj.name             = GameObjectUtility.GetUniqueNameForSibling(obj.transform.parent, "New Tilemap");

                Tilemap copiedTilemap = targetObj.SelectedTilemap;
                if (copiedTilemap)
                {
                    UnityEditorInternal.ComponentUtility.CopyComponent(copiedTilemap);
                    UnityEditorInternal.ComponentUtility.PasteComponentValues(newTilemap);
                    obj.SendMessage("_DoDuplicate");
                    obj.name = GameObjectUtility.GetUniqueNameForSibling(obj.transform.parent, copiedTilemap.name);
                }
            };
            reordList.onRemoveCallback = (ReorderableList list) =>
            {
                var targetObj = target as TilemapGroup;
                Undo.DestroyObjectImmediate(targetObj.SelectedTilemap.gameObject);
                //NOTE: Fix argument exception
                if (m_tilemapReordList.index == targetObj.Tilemaps.Count - 1)
                {
                    serializedObject.FindProperty("m_selectedIndex").intValue = m_tilemapReordList.index = m_tilemapReordList.index - 1;
                }
            };

            return(reordList);
        }
Example #8
0
        // '°', '├', '═', '┤', | 0, 2, 10, 8,
        // '┬', '╔', '╦', '╗', | 4, 6, 14, 12,
        // '║', '╠', '╬', '╣', | 5, 7, 15, 13,
        // '┴', '╚', '╩', '╝', | 1, 3, 11, 9,
        public override uint[] GetSubtiles(Tilemap tilemap, int gridX, int gridY, uint tileData)
        {
            CalculateNeighbourData(tilemap, gridX, gridY, tileData);
            // tiles that need subtile division
            if (s_needsSubTiles)
            {
                uint[] aSubTileData = null;

                if (s_neighIdx == 0) //°
                {
                    aSubTileData = new uint[] { TileIds[3], TileIds[9], TileIds[6], TileIds[12] };
                }
                else if (s_neighIdx == 4)//┬
                {
                    aSubTileData = new uint[] { TileIds[6], TileIds[12], TileIds[6], TileIds[12] };
                }
                else if (s_neighIdx == 5)//║
                {
                    aSubTileData = new uint[] { TileIds[7], TileIds[13], TileIds[7], TileIds[13] };
                }
                else if (s_neighIdx == 1)//┴
                {
                    aSubTileData = new uint[] { TileIds[3], TileIds[9], TileIds[3], TileIds[9] };
                }
                else if (s_neighIdx == 2)//├
                {
                    aSubTileData = new uint[] { TileIds[3], TileIds[3], TileIds[6], TileIds[6] };
                }
                else if (s_neighIdx == 10)//═
                {
                    aSubTileData = new uint[] { TileIds[11], TileIds[11], TileIds[14], TileIds[14] };
                }
                else if (s_neighIdx == 8)//┤
                {
                    aSubTileData = new uint[] { TileIds[9], TileIds[9], TileIds[12], TileIds[12] };
                }
                // NOTE: this case '╬' cut the tiles different (using corner tiles).
                // If it is commented, and default case is used, instead or corner tiles, it will use the center tile '╬'
                // Depending on the graphics it could be interesting add a check box to choose between using this or not.
                else if (s_neighIdx == 15)// ╬
                {
                    aSubTileData = new uint[] { InteriorCornerTileIds[0], InteriorCornerTileIds[1], InteriorCornerTileIds[2], InteriorCornerTileIds[3] };
                }
                else
                {
                    aSubTileData = new uint[] { TileIds[s_neighIdx], TileIds[s_neighIdx], TileIds[s_neighIdx], TileIds[s_neighIdx] };
                }

                for (int i = 0; i < s_showDiagonal.Length; ++i)
                {
                    if (s_showDiagonal[i])
                    {
                        aSubTileData[i] = InteriorCornerTileIds[3 - i];
                    }
                    // Add animated tiles
                    {
                        TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(aSubTileData[i]));
                        if (brush && brush.IsAnimated())
                        {
                            TilemapChunk.RegisterAnimatedBrush(brush, i);
                        }
                    }
                }

                return(aSubTileData);
            }

            // Add animated tiles
            {
                TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(s_tileData));
                if (brush && brush.IsAnimated())
                {
                    TilemapChunk.RegisterAnimatedBrush(brush);
                }
            }
            return(null);
        }
        public void DoPaintDragged(Tilemap tilemap, Vector2 localPos, EventModifiers modifiers = default(EventModifiers))
        {
            //Debug.Log("DoPaintDragged (" + TilemapUtils.GetGridX(tilemap, localPos) + "," + TilemapUtils.GetGridY(tilemap, localPos) + ")");
            if (m_paintMode == eBrushPaintMode.Pencil)
            {
                Paint(tilemap, localPos);
            }
            else
            {
                if (m_isDragging)
                {
                    BrushTilemap.ClearMap();
                    Vector2 brushLocPos = tilemap.transform.InverseTransformPoint(transform.position);
                    Vector2 startPos    = BrushUtil.GetSnappedPosition(m_pressedPosition, BrushTilemap.CellSize) + BrushTilemap.CellSize / 2f - brushLocPos;
                    Vector2 endPos      = BrushUtil.GetSnappedPosition(localPos, BrushTilemap.CellSize) + BrushTilemap.CellSize / 2f - brushLocPos;
                    bool    isCtrl      = (modifiers & EventModifiers.Control) != 0;
                    bool    isShift     = (modifiers & EventModifiers.Shift) != 0;
                    switch (m_paintMode)
                    {
                    case eBrushPaintMode.Line:
                        if (isCtrl)
                        {
                            TilemapDrawingUtils.DrawLineMirrored(BrushTilemap, startPos, endPos, m_brushPattern);
                        }
                        else
                        {
                            TilemapDrawingUtils.DrawLine(BrushTilemap, startPos, endPos, m_brushPattern);
                        }
                        break;

                    case eBrushPaintMode.Rect:
                    case eBrushPaintMode.FilledRect:
                    case eBrushPaintMode.Ellipse:
                    case eBrushPaintMode.FilledEllipse:
                        if (isShift)
                        {
                            Vector2 vTemp = endPos - startPos;
                            float   absX  = Mathf.Abs(vTemp.x);
                            float   absY  = Mathf.Abs(vTemp.y);
                            vTemp.x = (absX > absY) ? vTemp.x : Mathf.Sign(vTemp.x) * absY;
                            vTemp.y = Mathf.Sign(vTemp.y) * Mathf.Abs(vTemp.x);
                            endPos  = startPos + vTemp;
                        }
                        if (isCtrl)
                        {
                            startPos = 2f * startPos - endPos;
                        }
                        if (m_paintMode == eBrushPaintMode.Rect || m_paintMode == eBrushPaintMode.FilledRect)
                        {
                            TilemapDrawingUtils.DrawRect(BrushTilemap, startPos, endPos, m_brushPattern, m_paintMode == eBrushPaintMode.FilledRect, (modifiers & EventModifiers.Alt) != 0);
                        }
                        else if (m_paintMode == eBrushPaintMode.Ellipse || m_paintMode == eBrushPaintMode.FilledEllipse)
                        {
                            TilemapDrawingUtils.DrawEllipse(BrushTilemap, startPos, endPos, m_brushPattern, m_paintMode == eBrushPaintMode.FilledEllipse);
                        }
                        break;
                    }
                    BrushTilemap.UpdateMeshImmediate();
                }
            }
        }
Example #10
0
        static public Texture2D CreateTexture2DFromTilemap(Tilemap 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 <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)
                {
                    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);
        }
        /// <summary>
        /// /// Gets the grid X position for a given tilemap and camera where the mouse is over.
        /// </summary>
        /// <param name="tilemap"></param>
        /// <param name="camera"></param>
        /// <returns></returns>
        static public int GetMouseGridY(Tilemap tilemap, Camera camera)
        {
            Vector2 locPos = camera.ScreenToWorldPoint(Input.mousePosition);

            return(GetGridY(tilemap, tilemap.transform.InverseTransformPoint(locPos)));
        }
 /// <summary>
 /// Gets the grid Y position for a given tilemap and local position. To convert from world to local position use tilemap.transform.InverseTransformPoint(worldPosition).
 /// Avoid using positions multiple of cellSize like 0.32f if cellSize = 0.16f because due float imprecisions the return value could be wrong.
 /// </summary>
 /// <param name="tilemap"></param>
 /// <param name="locPosition"></param>
 /// <returns></returns>
 static public int GetGridY(Tilemap tilemap, Vector2 locPosition)
 {
     return(BrushUtil.GetGridY(locPosition, tilemap.CellSize));
 }
Example #13
0
        //Note: this is doing the same as FloodFill but not saving data in the tilemap, only saving the filled points and returning a list
        public static void FloodFillPreview(Tilemap tilemap, int gridX, int gridY, uint tileData, List <Vector2> outFilledPoints, uint maxPoints = uint.MaxValue)
        {
            if (
                gridX >= tilemap.MinGridX && gridX <= tilemap.MaxGridX &&
                gridY >= tilemap.MinGridY && gridY <= tilemap.MaxGridY
                )
            {
                bool[]             filledPoints = new bool[tilemap.GridWidth * tilemap.GridHeight];
                LinkedList <Point> check        = new LinkedList <Point>();
                uint floodFrom = tilemap.GetTileData(gridX, gridY);
                outFilledPoints.Add(Vector2.Scale(new Vector2(gridX, gridY), tilemap.CellSize));
                filledPoints[(gridY - tilemap.MinGridY) * tilemap.GridWidth + gridX - tilemap.MinGridX] = true;
                bool isBrush = Tileset.GetBrushIdFromTileData(floodFrom) != 0;
                if (
                    isBrush ?
                    Tileset.GetBrushIdFromTileData(floodFrom) != Tileset.GetBrushIdFromTileData(tileData)
                    :
                    floodFrom != tileData
                    )
                {
                    check.AddLast(new Point(gridX, gridY));
                    while (check.Count > 0)
                    {
                        Point cur = check.First.Value;
                        check.RemoveFirst();

                        foreach (Point off in new Point[] {
                            new Point(0, -1), new Point(0, 1),
                            new Point(-1, 0), new Point(1, 0)
                        })
                        {
                            Point next = new Point(cur.X + off.X, cur.Y + off.Y);

                            if (
                                next.X >= tilemap.MinGridX && next.X <= tilemap.MaxGridX &&
                                next.Y >= tilemap.MinGridY && next.Y <= tilemap.MaxGridY
                                )
                            {
                                if (filledPoints[(next.Y - tilemap.MinGridY) * tilemap.GridWidth + next.X - tilemap.MinGridX])
                                {
                                    continue;                                                                                            // skip already filled points
                                }
                                uint nextTileData = tilemap.GetTileData(next.X, next.Y);
                                if (
                                    isBrush ?
                                    Tileset.GetBrushIdFromTileData(floodFrom) == Tileset.GetBrushIdFromTileData(nextTileData)
                                    :
                                    floodFrom == nextTileData
                                    )
                                {
                                    check.AddLast(next);
                                    filledPoints[(next.Y - tilemap.MinGridY) * tilemap.GridWidth + next.X - tilemap.MinGridX] = true;
                                    outFilledPoints.Add(Vector2.Scale(new Vector2(next.X, next.Y), tilemap.CellSize));
                                    if (outFilledPoints.Count >= maxPoints)
                                    {
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }