/// <summary>
        /// Set a tile color using a tilemap local position
        /// </summary>
        /// <param name="vLocalPos"></param>
        /// <param name="c0">Bottom left corner</param>
        /// <param name="c1">Bottom right corner</param>
        /// <param name="c2">Top left corner</param>
        /// <param name="c3">Top right corner</param>
        public void SetTileColor(Vector2 vLocalPos, TileColor32 tileColor, eBlendMode blendMode = eBlendMode.AlphaBlending)
        {
            int gridX = BrushUtil.GetGridX(vLocalPos, CellSize);
            int gridY = BrushUtil.GetGridY(vLocalPos, CellSize);

            SetTileColor(gridX, gridY, tileColor, blendMode);
        }
Beispiel #2
0
 public static TileColor32 BlendColors(TileColor32 tileColorA, TileColor32 tileColorB, eBlendMode blendMode)
 {
     if (tileColorA.singleColor && tileColorB.singleColor)
     {
         return(new TileColor32(BlendColor(tileColorA.c0, tileColorB.c0, blendMode)));
     }
     else
     {
         return(new TileColor32(BlendColor(tileColorA.c0, tileColorB.c0, blendMode), BlendColor(tileColorA.c1, tileColorB.c1, blendMode), BlendColor(tileColorA.c2, tileColorB.c2, blendMode), BlendColor(tileColorA.c3, tileColorB.c3, blendMode)));
     }
 }
 public void SetTileColor(int locGridX, int locGridY, Color32 color)
 {
     if (locGridX >= 0 && locGridX < m_width && locGridY >= 0 && locGridY < m_height)
     {
         int tileIdx = locGridY * m_width + locGridX;
         if (m_tileColorList == null || m_tileColorList.Count == 0)
         {
             m_tileColorList = Enumerable.Repeat(new TileColor32(new Color32(0xff, 0xff, 0xff, 0xff)), m_tileDataList.Count).ToList();
         }
         m_tileColorList[tileIdx] = new TileColor32(color);
     }
 }
 public void SetTileColor(int locGridX, int locGridY, TileColor32 tileColor, eBlendMode blendMode = eBlendMode.AlphaBlending)
 {
     if (locGridX >= 0 && locGridX < m_width && locGridY >= 0 && locGridY < m_height)
     {
         int tileIdx = locGridY * m_width + locGridX;
         if (m_tileColorList == null || m_tileColorList.Count == 0)
         {
             m_tileColorList = Enumerable.Repeat(new TileColor32(new Color32(0xff, 0xff, 0xff, 0xff)), m_tileDataList.Count).ToList();
         }
         m_tileColorList[tileIdx] = TileColor32.BlendColors(m_tileColorList[tileIdx], tileColor, blendMode);
         m_needsRebuildMeshColor  = true;
     }
 }
 public Color32[] GetTileColor(int locGridX, int locGridY)
 {
     if (locGridX >= 0 && locGridX < m_width && locGridY >= 0 && locGridY < m_height)
     {
         int tileIdx = locGridY * m_width + locGridX;
         if (m_tileColorList == null || m_tileColorList.Count == 0)
         {
             Color32 whiteColor = new Color32(255, 255, 255, 255);
             return(new Color32[] { whiteColor, whiteColor, whiteColor, whiteColor });
         }
         TileColor32 tileColor32 = m_tileColorList[tileIdx];
         return(new Color32[] { tileColor32.c0, tileColor32.c1, tileColor32.c2, tileColor32.c3 });
     }
     return(null);
 }
        /// <summary>
        /// Set a tile color in the grid position
        /// </summary>
        /// <param name="gridX"></param>
        /// <param name="gridY"></param>
        /// <param name="c0">Bottom left corner</param>
        /// <param name="c1">Bottom right corner</param>
        /// <param name="c2">Top left corner</param>
        /// <param name="c3">Top right corner</param>
        public void SetTileColor(int gridX, int gridY, TileColor32 tileColor, eBlendMode blendMode = eBlendMode.AlphaBlending)
        {
            TilemapChunk chunk      = GetOrCreateTileChunk(gridX, gridY, true);
            int          chunkGridX = (gridX < 0 ? -gridX - 1 : gridX) % k_chunkSize;
            int          chunkGridY = (gridY < 0 ? -gridY - 1 : gridY) % k_chunkSize;

            if (gridX < 0)
            {
                chunkGridX = k_chunkSize - 1 - chunkGridX;
            }
            if (gridY < 0)
            {
                chunkGridY = k_chunkSize - 1 - chunkGridY;
            }
            if (m_allowPaintingOutOfBounds || (gridX >= m_minGridX && gridX <= m_maxGridX && gridY >= m_minGridY && gridY <= m_maxGridY))
            {
                chunk.SetTileColor(chunkGridX, chunkGridY, tileColor, blendMode);
            }
        }
        private void UpdateMeshVertexColor()
        {
            //Debug.Log( "[" + ParentTilemap.name + "] FillData -> " + name);
            if (!Tileset || !Tileset.AtlasTexture)
            {
                return;
            }

            int totalTiles = m_width * m_height;

            if (s_colors32 == null)
            {
                s_colors32 = new List <Color32>(totalTiles * 4);
            }
            else
            {
                s_colors32.Clear();
            }

            for (int ty = 0, tileIdx = 0; ty < m_height; ++ty)
            {
                for (int tx = 0; tx < m_width; ++tx, ++tileIdx)
                {
                    uint tileData = m_tileDataList[tileIdx];
                    if (tileData != Tileset.k_TileData_Empty)
                    {
                        int          brushId   = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16);
                        int          tileId    = (int)(tileData & Tileset.k_TileDataMask_TileId);
                        Tile         tile      = Tileset.GetTile(tileId);
                        TilesetBrush tileBrush = null;
                        if (brushId > 0)
                        {
                            tileBrush = Tileset.FindBrush(brushId);
                        }

                        uint[] subtileData = tileBrush != null?tileBrush.GetSubtiles(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData) : null;

                        if (subtileData == null)
                        {
                            if (tile != null)
                            {
                                if (tile.prefabData.prefab == null || tile.prefabData.showTileWithPrefab || //hide the tiles with prefabs ( unless showTileWithPrefab is true )
                                    tileBrush && tileBrush.IsAnimated())    // ( skip if it's an animated brush )
                                {
                                    if (m_tileColorList != null && m_tileColorList.Count > tileIdx)
                                    {
                                        TileColor32 tileColor32 = m_tileColorList[tileIdx];
                                        s_colors32.Add(tileColor32.c0);
                                        s_colors32.Add(tileColor32.c1);
                                        s_colors32.Add(tileColor32.c2);
                                        s_colors32.Add(tileColor32.c3);
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int i = 0; i < subtileData.Length; ++i)
                            {
                                //if (tileUV != default(Rect)) //NOTE: if this is uncommented, there won't be coherence with geometry ( 16 vertices per tiles with subtiles ). But it means also, the tile shouldn't be null.
                                {
                                    if (m_tileColorList != null && m_tileColorList.Count > tileIdx)
                                    {
                                        TileColor32 tileColor32 = m_tileColorList[tileIdx];
                                        Color32     middleColor = new Color32(
                                            System.Convert.ToByte((tileColor32.c0.r + tileColor32.c1.r + tileColor32.c2.r + tileColor32.c3.r) >> 2),
                                            System.Convert.ToByte((tileColor32.c0.g + tileColor32.c1.g + tileColor32.c2.g + tileColor32.c3.g) >> 2),
                                            System.Convert.ToByte((tileColor32.c0.b + tileColor32.c1.b + tileColor32.c2.b + tileColor32.c3.b) >> 2),
                                            System.Convert.ToByte((tileColor32.c0.a + tileColor32.c1.a + tileColor32.c2.a + tileColor32.c3.a) >> 2)
                                            );
                                        switch (i)
                                        {
                                        case 0:
                                            s_colors32.Add(tileColor32.c0);
                                            s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c0, .5f));
                                            s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c0, .5f));
                                            s_colors32.Add(middleColor);
                                            break;

                                        case 1:
                                            s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c1, .5f));
                                            s_colors32.Add(tileColor32.c1);
                                            s_colors32.Add(middleColor);
                                            s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c1, .5f));
                                            break;

                                        case 2:
                                            s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c2, .5f));
                                            s_colors32.Add(middleColor);
                                            s_colors32.Add(tileColor32.c2);
                                            s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c2, .5f));
                                            break;

                                        case 3:
                                            s_colors32.Add(middleColor);
                                            s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c3, .5f));
                                            s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c3, .5f));
                                            s_colors32.Add(tileColor32.c3);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 public void SetTileColor(Vector2 vLocalPos, TileColor32 tileColor, eBlendMode blendMode = eBlendMode.AlphaBlending)
 {
     SetTileColor((int)(vLocalPos.x / CellSize.x), (int)(vLocalPos.y / CellSize.y), tileColor, blendMode);
 }
        /*
         * private void DummyDeepProfilingFix()
         * {
         *  // For some reason, in Unity 2017.3.1f1, the Deep Profiling crashes unless FillMeshData call any method, even a dummy method like this
         *  // Other weird thing is, the crash doesn't happens if one case of the switch statement is commented
         *  // FINALLY: the fix was to change the Switch for if-else statements. I keep this notes just in case to remember about this weird issue.
         * }
         */

        /// <summary>
        /// Fill the mesh data and return false if all tiles are empty
        /// </summary>
        /// <returns></returns>
        private bool FillMeshData()
        {
            //Debug.Log( "[" + ParentTilemap.name + "] FillData -> " + name);
            //DummyDeepProfilingFix();

            if (!Tileset || !Tileset.AtlasTexture)
            {
                return(false);
            }
            s_currUpdatedTilechunk = this;

            int totalTiles = m_width * m_height;

            if (s_vertices == null)
            {
                s_vertices = new List <Vector3>(totalTiles * 4);
            }
            else
            {
                s_vertices.Clear();
            }
            if (s_triangles == null)
            {
                s_triangles = new List <int>(totalTiles * 6);
            }
            else
            {
                s_triangles.Clear();
            }
            if (s_colors32 == null)
            {
                s_colors32 = new List <Color32>(totalTiles * 4);
            }
            else
            {
                s_colors32.Clear();
            }
            if (m_uv == null)
            {
                m_uv = new List <Vector2>(totalTiles * 4);
            }
            else
            {
                m_uv.Clear();
            }

            Vector2[] subTileOffset = new Vector2[]
            {
                new Vector2(0f, 0f),
                new Vector2(CellSize.x / 2f, 0f),
                new Vector2(0f, CellSize.y / 2f),
                new Vector2(CellSize.x / 2f, CellSize.y / 2f),
            };
            Vector2 subTileSize = CellSize / 2f;

            m_animatedTiles.Clear();
            bool isEmpty = true;

            for (int ty = 0, tileIdx = 0; ty < m_height; ++ty)
            {
                for (int tx = 0; tx < m_width; ++tx, ++tileIdx)
                {
                    uint tileData = m_tileDataList[tileIdx];
                    if (tileData != Tileset.k_TileData_Empty)
                    {
                        int          brushId   = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16);
                        int          tileId    = (int)(tileData & Tileset.k_TileDataMask_TileId);
                        Tile         tile      = Tileset.GetTile(tileId);
                        TilesetBrush tileBrush = null;
                        if (tileId >= 0 && tile == null && brushId <= 0)
                        {
                            Debug.LogWarning(ParentTilemap.name + "\\" + name + ": TileId " + tileId + " not found! GridPos(" + (GridPosX + tx) + "," + (GridPosY + ty) + ") tilaData 0x" + tileData.ToString("X"));
                            m_tileDataList[tileIdx] = Tileset.k_TileData_Empty;
                        }
                        if (brushId > 0)
                        {
                            tileBrush = Tileset.FindBrush(brushId);
                            if (tileBrush == null)
                            {
                                Debug.LogWarning(ParentTilemap.name + "\\" + name + ": BrushId " + brushId + " not found! GridPos(" + (GridPosX + tx) + "," + (GridPosY + ty) + ") tilaData 0x" + tileData.ToString("X"));
                                m_tileDataList[tileIdx] = tileData & ~Tileset.k_TileDataMask_BrushId;
                            }
                            if (tileBrush != null && (m_invalidateBrushes || (tileData & Tileset.k_TileFlag_Updated) == 0))
                            {
                                tileData = tileBrush.Refresh(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData);
                                //+++NOTE: this code add support for animated brushes inside a random brush
                                // Collateral effects of supporting changing the brush id in Refresh:
                                // - When the random brush select a tile data with another brush id, this tile won't be a random tile any more
                                // - If the tilemap is refreshed several times, and at least a tile data contains another brush id, then all tiles will loose the brush id of the random brush
                                if (BrushBehaviour.Instance.BrushTilemap == ParentTilemap) // avoid changing brushId when updating the BrushTilemap
                                {
                                    tileData &= ~Tileset.k_TileDataMask_BrushId;
                                    tileData |= (uint)(brushId << 16);
                                }
                                int newBrushId = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16);
                                if (brushId != newBrushId)
                                {
                                    brushId   = newBrushId;
                                    tileBrush = Tileset.FindBrush(brushId);
                                }
                                //---
                                tileData |= Tileset.k_TileFlag_Updated; // set updated flag
                                m_tileDataList[tileIdx] = tileData;     // update tileData
                                tileId = (int)(tileData & Tileset.k_TileDataMask_TileId);
                                tile   = Tileset.GetTile(tileId);
                                // update created objects
                                if (tile != null && tile.prefabData.prefab != null)
                                {
                                    CreateTileObject(tileIdx, tile.prefabData);
                                }
                                else
                                {
                                    DestroyTileObject(tileIdx);
                                }
                            }
                        }

                        isEmpty = false;

                        if (tileBrush != null && tileBrush.IsAnimated())
                        {
                            m_animatedTiles.Add(new AnimTileData()
                            {
                                VertexIdx = s_vertices.Count, Brush = tileBrush, SubTileIdx = -1
                            });
                        }

                        s_currUVVertex = s_vertices.Count;
                        Rect   tileUV;
                        uint[] subtileData = tileBrush != null?tileBrush.GetSubtiles(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData) : null;

                        if (subtileData == null)
                        {
                            if (tile != null)
                            {
                                if (tile.prefabData.prefab == null || tile.prefabData.showTileWithPrefab || //hide the tiles with prefabs ( unless showTileWithPrefab is true )
                                    tileBrush && tileBrush.IsAnimated())    // ( skip if it's an animated brush )
                                {
                                    tileUV = tile.uv;
                                    _AddTileToMesh(tileUV, tx, ty, tileData, Vector2.zero, CellSize);
                                    if (m_tileColorList != null && m_tileColorList.Count > tileIdx)
                                    {
                                        TileColor32 tileColor32 = m_tileColorList[tileIdx];
                                        s_colors32.Add(tileColor32.c0);
                                        s_colors32.Add(tileColor32.c1);
                                        s_colors32.Add(tileColor32.c2);
                                        s_colors32.Add(tileColor32.c3);
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int i = 0; i < subtileData.Length; ++i)
                            {
                                uint subTileData = subtileData[i];
                                int  subTileId   = (int)(subTileData & Tileset.k_TileDataMask_TileId);
                                Tile subTile     = Tileset.GetTile(subTileId);
                                tileUV = subTile != null ? subTile.uv : default(Rect);
                                //if (tileUV != default(Rect)) //NOTE: if this is uncommented, there won't be coherence with geometry ( 16 vertices per tiles with subtiles ). But it means also, the tile shouldn't be null.
                                {
                                    _AddTileToMesh(tileUV, tx, ty, subTileData, subTileOffset[i], subTileSize, i);
                                    if (m_tileColorList != null && m_tileColorList.Count > tileIdx)
                                    {
                                        TileColor32 tileColor32 = m_tileColorList[tileIdx];
                                        Color32     middleColor = new Color32(
                                            System.Convert.ToByte((tileColor32.c0.r + tileColor32.c1.r + tileColor32.c2.r + tileColor32.c3.r) >> 2),
                                            System.Convert.ToByte((tileColor32.c0.g + tileColor32.c1.g + tileColor32.c2.g + tileColor32.c3.g) >> 2),
                                            System.Convert.ToByte((tileColor32.c0.b + tileColor32.c1.b + tileColor32.c2.b + tileColor32.c3.b) >> 2),
                                            System.Convert.ToByte((tileColor32.c0.a + tileColor32.c1.a + tileColor32.c2.a + tileColor32.c3.a) >> 2)
                                            );
                                        //switch(i) // FIX Deep Profiling crash in Unity 2017.3.1f1 see: DummyDeepProfilingFix notes
                                        {
                                            if (i == 0)
                                            {
                                                s_colors32.Add(tileColor32.c0);
                                                s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c0, .5f));
                                                s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c0, .5f));
                                                s_colors32.Add(middleColor);
                                            }
                                            else if (i == 1)
                                            {
                                                s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c1, .5f));
                                                s_colors32.Add(tileColor32.c1);
                                                s_colors32.Add(middleColor);
                                                s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c1, .5f));
                                            }
                                            else if (i == 2)
                                            {
                                                s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c2, .5f));
                                                s_colors32.Add(middleColor);
                                                s_colors32.Add(tileColor32.c2);
                                                s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c2, .5f));
                                            }
                                            else if (i == 3)
                                            {
                                                s_colors32.Add(middleColor);
                                                s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c3, .5f));
                                                s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c3, .5f));
                                                s_colors32.Add(tileColor32.c3);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //NOTE: the destruction of tileobjects needs to be done here to avoid a Undo/Redo bug. Check inside DestroyTileObject for more information.
            for (int i = 0; i < m_tileObjToBeRemoved.Count; ++i)
            {
                DestroyTileObject(m_tileObjToBeRemoved[i]);
            }
            m_tileObjToBeRemoved.Clear();
            s_currUpdatedTilechunk = null;
            return(!isEmpty);
        }