示例#1
0
        public static void TileDataField(Rect position, GUIContent label, SerializedProperty property, Tileset tileset)
        {
            Event e = Event.current;
            bool  isLeftMouseReleased = e.type == EventType.MouseUp && e.button == 0;
            //NOTE: there is a bug with DrawTextureWithTexCoords where the texture disappears. It is fixed by overriding the Editor Script with a CustomEditor.
            Rect         rVisualTile = new Rect(position.x, position.y, k_TilePreviewSize, k_TilePreviewSize);
            uint         tileData    = (uint)property.intValue;
            TilesetBrush brush       = tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData));

            if (brush)
            {
                tileData = brush.PreviewTileData();
            }

            TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, tileData, tileset);
            if (isLeftMouseReleased && rVisualTile.Contains(e.mousePosition))
            {
                EditorWindow wnd = EditorWindow.focusedWindow;
                TileSelectionWindow.Show(tileset);
                TileSelectionWindow.Instance.Ping();
                wnd.Focus();
                GUI.FocusControl("");
            }
            EditorGUI.PropertyField(new Rect(position.x, position.y + k_TilePreviewSize, position.width, position.height - k_TilePreviewSize), property, label);
        }
示例#2
0
        /// <summary>
        /// Flip the map horizontally
        /// </summary>
        /// <param name="changeFlags"></param>
        public void FlipH(bool changeFlags)
        {
            List <uint> flippedList = new List <uint>(GridWidth * GridHeight);

            for (int gx = MinGridX; gx <= MaxGridX; ++gx)
            {
                for (int gy = MinGridY; gy <= MaxGridY; ++gy)
                {
                    int flippedGx = GridWidth - 1 - gx;
                    flippedList.Add(GetTileData(flippedGx, gy));
                }
            }

            int idx = 0;

            for (int gx = MinGridX; gx <= MaxGridX; ++gx)
            {
                for (int gy = MinGridY; gy <= MaxGridY; ++gy, ++idx)
                {
                    uint flippedTileData = flippedList[idx];
                    if (
                        changeFlags &&
                        (flippedTileData != Tileset.k_TileData_Empty) &&
                        (flippedTileData & Tileset.k_TileDataMask_BrushId) == 0    // don't activate flip flags on brushes
                        )
                    {
                        flippedTileData = TilesetBrush.ApplyAndMergeTileFlags(flippedTileData, Tileset.k_TileFlag_FlipH);
                    }
                    SetTileData(gx, gy, flippedTileData);
                }
            }
        }
示例#3
0
        void OnBrushSelected(Tileset source, int prevBrushId, int newBrushId)
        {
            if (AllowBrushSelection)
            {
                if (m_selectedTileIdx >= 0 && m_hasFocus)
                {
                    m_tileIdOff = 0;
                    uint brushTileData = m_getTileDataFunc(m_selectedTileIdx);
                    if (brushTileData == Tileset.k_TileData_Empty)
                    {
                        brushTileData = 0u; // reset flags and everything
                    }
                    Undo.RecordObject(m_target, "BrushChanged");

                    TilesetBrush brush  = Tileset.FindBrush(newBrushId);
                    int          tileId = (int)(brush.PreviewTileData() & Tileset.k_TileDataMask_TileId);
                    brushTileData &= Tileset.k_TileDataMask_Flags;
                    brushTileData |= (uint)(newBrushId << 16) & Tileset.k_TileDataMask_BrushId;
                    brushTileData |= (uint)(tileId & Tileset.k_TileDataMask_TileId);

                    m_setTileDataFunc(m_selectedTileIdx, brushTileData);
                    m_hasChanged = true;
                }
                EditorUtility.SetDirty(m_target);
            }
        }
示例#4
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            TilesetBrush brush = (TilesetBrush)target;

            if (brush.Tileset == null)
            {
                EditorGUILayout.HelpBox("Select a tileset first", MessageType.Info);
                EditorGUILayout.PropertyField(m_tileset);
                serializedObject.ApplyModifiedProperties();
                return;
            }

            EditorGUILayout.PropertyField(m_tileset);
            m_group.intValue = TilesetEditor.DoGroupFieldLayout(brush.Tileset, "Group", m_group.intValue);
            string sAutotilingModeTooltip =
                "Autotiling Mode:\n" +
                "Self: autotile only with brushes of same type\n" +
                "Other: autotile with any other not empty tile\n" +
                "Group: autotile with brushes of a group that autotile the brush group";

            m_autotilingMode.intValue = System.Convert.ToInt32(EditorGUILayout.EnumMaskField(new GUIContent("Autotiling Mode", sAutotilingModeTooltip), brush.AutotilingMode));

            if (GUI.changed)
            {
                serializedObject.ApplyModifiedProperties();
                EditorUtility.SetDirty(target);
            }
        }
        private void DisplayAutotiling()
        {
            if (Tileset.SelectedBrushId != Tileset.k_BrushId_Default)
            {
                TilesetBrush brush = Tileset.FindBrush(Tileset.SelectedBrushId);
                if (brush)
                {
                    EditorGUILayout.BeginHorizontal();
                    GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y));
                    TilesetEditor.DoGUIDrawTileFromTileData(GUILayoutUtility.GetLastRect(), brush.GetAnimTileData(), Tileset, brush.GetAnimUV());
                    GUILayout.Label("(" + brush.name + ":" + brush.GetType().Name + ")", EditorStyles.boldLabel);
                    EditorGUILayout.EndHorizontal();

                    if (!m_brushEditor || m_brushEditor.target != brush)
                    {
                        m_brushEditor = TilesetBrushEditor.CreateEditor(brush) as TilesetBrushEditor;
                    }
                    (m_brushEditor as TilesetBrushEditor).DoInspectorGUI();
                }
            }
            else
            {
                bool isMultiselection = Tileset.TileSelection != null;
                Tile selectedTile     = isMultiselection ? Tileset.Tiles[(int)(Tileset.TileSelection.selectionData[0] & Tileset.k_TileDataMask_TileId)] : Tileset.SelectedTile;
                GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y));
                Rect tileUV = selectedTile.uv;
                GUI.color = Tileset.BackgroundColor;
                GUI.DrawTextureWithTexCoords(GUILayoutUtility.GetLastRect(), EditorGUIUtility.whiteTexture, tileUV, true);
                GUI.color = Color.white;
                GUI.DrawTextureWithTexCoords(GUILayoutUtility.GetLastRect(), Tileset.AtlasTexture, tileUV, true);

                if (isMultiselection)
                {
                    EditorGUILayout.LabelField("* Multi-selection Edition", EditorStyles.boldLabel);
                }
                EditorGUI.BeginChangeCheck();

                selectedTile.autilingGroup = TilesetEditor.DoGroupFieldLayout(Tileset, "Group", selectedTile.autilingGroup);

                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(Tileset, "Tile Autotiling Data Changed");
                    if (isMultiselection)
                    {
                        for (int i = 0; i < Tileset.TileSelection.selectionData.Count; ++i)
                        {
                            Tile tile = Tileset.Tiles[(int)(Tileset.TileSelection.selectionData[i] & Tileset.k_TileDataMask_TileId)];
                            tile.autilingGroup = selectedTile.autilingGroup;
                        }
                    }
                    EditorUtility.SetDirty(Tileset);
                }
            }
        }
示例#6
0
        public static uint DoTileDataPropertiesLayout(uint tileData, Tileset tileset, bool displayBrush = true)
        {
            EditorGUILayout.BeginVertical(EditorStyles.helpBox);

            GUI.enabled = tileData != Tileset.k_TileData_Empty;
            EditorGUIUtility.labelWidth = 100;

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.Toggle("Flip Horizontally", (tileData & Tileset.k_TileFlag_FlipH) != 0);
            if (EditorGUI.EndChangeCheck())
            {
                tileData ^= Tileset.k_TileFlag_FlipH;
            }
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.Toggle("Flip Vertically", (tileData & Tileset.k_TileFlag_FlipV) != 0);
            if (EditorGUI.EndChangeCheck())
            {
                tileData ^= Tileset.k_TileFlag_FlipV;
            }
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.Toggle("Rotate 90º", (tileData & Tileset.k_TileFlag_Rot90) != 0);
            if (EditorGUI.EndChangeCheck())
            {
                tileData ^= Tileset.k_TileFlag_Rot90;
            }

            if (displayBrush)
            {
                EditorGUI.BeginChangeCheck();
                int          brushId = Tileset.GetBrushIdFromTileData(tileData);
                TilesetBrush brush   = tileset.FindBrush(brushId);
                brush = (TilesetBrush)EditorGUILayout.ObjectField("Brush", brush, typeof(TilesetBrush), false);
                if (EditorGUI.EndChangeCheck())
                {
                    brushId = brush != null?tileset.FindBrushId(brush.name) : Tileset.k_BrushId_Default;

                    int tileId = brush != null ? (int)(brush.PreviewTileData() & Tileset.k_TileDataMask_TileId) : Tileset.GetTileIdFromTileData(tileData);
                    tileData &= Tileset.k_TileDataMask_Flags;
                    tileData |= (uint)(brushId << 16) & Tileset.k_TileDataMask_BrushId;
                    tileData |= (uint)(tileId & Tileset.k_TileDataMask_TileId);
                }
            }

            if (GUILayout.Button("Reset"))
            {
                tileData = Tileset.k_TileData_Empty;
            }

            EditorGUIUtility.labelWidth = 0;
            GUI.enabled = true;

            EditorGUILayout.EndVertical();
            return(tileData);
        }
示例#7
0
文件: Tileset.cs 项目: Aye1/Herborist
 public bool IsBrushVisibleByTypeMask(TilesetBrush brush)
 {
     if (brush)
     {
         string[] brushTypes = GetBrushTypeArray();
         if (brushTypes != null && brushTypes.Length > 0)
         {
             int idx = System.Array.IndexOf(brushTypes, brush.GetType().Name);
             return(((1 << idx) & m_brushTypeMask) != 0);
         }
     }
     return(false);
 }
示例#8
0
        public override uint[] GetSubtiles(Tilemap tilemap, int gridX, int gridY, uint tileData)
        {
            // Add animated tiles
            {
                int idx = CalculateIndex(tilemap, gridX, gridY, tileData);

                TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(TileIds[idx]));
                if (brush && brush.IsAnimated())
                {
                    TilemapChunk.RegisterAnimatedBrush(brush);
                }
            }
            return(null);
        }
示例#9
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);
        }
示例#10
0
        public TilesetBrush FindBrush(int brushId)
        {
            if (brushId == Tileset.k_BrushId_Empty)
            {
                return(null);
            }
            TilesetBrush tileBrush = null;

            if (!m_brushCache.TryGetValue(brushId, out tileBrush))
            {
                tileBrush             = m_brushes.FirstOrDefault(x => x.Id == brushId).BrushAsset;
                m_brushCache[brushId] = tileBrush;
                //Debug.Log(" Cache miss! " + tileBrush.name);
            }
            return(tileBrush);
        }
示例#11
0
文件: Tileset.cs 项目: Aye1/Herborist
        public TilesetBrush FindBrush(int brushId)
        {
            if (brushId <= 0)
            {
                return(null);
            }

            TilesetBrush tileBrush = null;

            if (!m_brushCache.TryGetValue(brushId, out tileBrush))
            {
                tileBrush             = FindBrushContainerByBrushId(brushId).BrushAsset;
                m_brushCache[brushId] = tileBrush;
                //Debug.Log(" Cache miss! " + tileBrush.name);
            }
            return(tileBrush);
        }
示例#12
0
 private void OnBrushSelected(Tileset source, int prevBrushId, int newBrushId)
 {
     if (m_randTileListHasFocus && m_randTileList.index >= 0 && m_randTileList.index < m_brush.RandomTileList.Count)
     {
         if (m_brush.RandomTileList[m_randTileList.index].tileData == Tileset.k_TileData_Empty)
         {
             m_brush.RandomTileList[m_randTileList.index].tileData = 0u;// reset flags and everything
         }
         m_brush.RandomTileList[m_randTileList.index].tileData &= ~Tileset.k_TileDataMask_TileId;
         m_brush.RandomTileList[m_randTileList.index].tileData &= ~Tileset.k_TileDataMask_BrushId;
         m_brush.RandomTileList[m_randTileList.index].tileData |= (uint)(newBrushId << 16);
         TilesetBrush brush = m_brush.Tileset.FindBrush(newBrushId);
         m_brush.RandomTileList[m_randTileList.index].tileData |= (uint)(brush.PreviewTileData() & Tileset.k_TileDataMask_TileId);
     }
     EditorUtility.SetDirty(target);
     m_brush.InvalidateSortedList();
 }
示例#13
0
        protected static bool s_refreshingLinkedBrush = false; //avoid infinite loop
        /// <summary>
        /// Returns a new tiledata after calling the refresh method of the linked brush.
        /// This is used to give support for tiles in a brush that are linked to another brush. Ex: a Road Brush with a tile linked to a random brush.
        /// </summary>
        /// <param name="tilemap"></param>
        /// <param name="gridX"></param>
        /// <param name="gridY"></param>
        /// <param name="tileData"></param>
        /// <returns></returns>
        public uint RefreshLinkedBrush(STETilemap tilemap, int gridX, int gridY, uint tileData)
        {
            if (s_refreshingLinkedBrush)
            {
                return(tileData);
            }

            int          brushId = Tileset.GetBrushIdFromTileData(tileData);
            TilesetBrush brush   = Tileset.FindBrush(brushId);

            if (brush)
            {
                s_refreshingLinkedBrush = true;
                tileData = ApplyAndMergeTileFlags(brush.Refresh(tilemap, gridX, gridY, tileData), tileData);
                s_refreshingLinkedBrush = false;
            }
            return(tileData);
        }
示例#14
0
        public override uint Refresh(STETilemap tilemap, int gridX, int gridY, uint tileData)
        {
            if (RandomTileList.Count > 0)
            {
                uint randomTileData = GetRandomTile();
                if (RandomizeFlagMask != 0)
                {
                    uint flags = ((uint)Random.Range(0, 8) << 29) & RandomizeFlagMask;
                    randomTileData &= ~RandomizeFlagMask;
                    randomTileData |= flags;
                }
                uint brushTileData = RefreshLinkedBrush(tilemap, gridX, gridY, randomTileData);
                // overwrite flags
                brushTileData &= ~Tileset.k_TileDataMask_Flags;
                brushTileData |= randomTileData & Tileset.k_TileDataMask_Flags;


                TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(brushTileData));
                if (brush && brush.IsAnimated())
                {
                    // Set the animated brush (overwriting the random brush for this tile)
                    brushTileData &= ~Tileset.k_TileDataMask_BrushId;
                    brushTileData |= randomTileData & Tileset.k_TileDataMask_BrushId;
                }

                // Overwrite the brush id for the one in the selected random tile
                // Side Effect: the tile will loose the brush id for the random brush
                if (RemoveBrushIdAfterRefresh)
                {
                    // Do nothing
                }
                // Overwrite the selected tile brush id for the random brush id
                // NOTE: animated tiles wont be animated
                else
                {
                    // overwrite brush id
                    brushTileData &= ~Tileset.k_TileDataMask_BrushId;
                    brushTileData |= tileData & Tileset.k_TileDataMask_BrushId;
                }

                return(brushTileData);
            }
            return(tileData);
        }
示例#15
0
        public override uint Refresh(Tilemap tilemap, int gridX, int gridY, uint tileData)
        {
            if (RandomTileList.Count > 0)
            {
                uint randomTileData = GetRandomTile();
                if (RandomizeFlagMask != 0)
                {
                    uint flags = ((uint)Random.Range(0, 8) << 29) & RandomizeFlagMask;
                    randomTileData &= ~RandomizeFlagMask;
                    randomTileData |= flags;
                }
                uint brushTileData = RefreshLinkedBrush(tilemap, gridX, gridY, randomTileData);
                // overwrite flags
                brushTileData &= ~Tileset.k_TileDataMask_Flags;
                brushTileData |= randomTileData & Tileset.k_TileDataMask_Flags;


                TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(brushTileData));
                if (brush && brush.IsAnimated())
                {
                    // Set the animated brush (overwriting the random brush for this tile)
                    brushTileData &= ~Tileset.k_TileDataMask_BrushId;
                    brushTileData |= randomTileData & Tileset.k_TileDataMask_BrushId;
                }

                // - Commented:
                // This code will make the Random Brush to work only once
                // Copy the tile will copy the tile placed the first time
                // - Uncommented:
                // This code will make Refresh Tilemap to update all random brushes
                // Copy the tile will copy a random brush tile

                /*
                 * {
                 *  // overwrite brush id
                 *  brushTileData &= ~Tileset.k_TileDataMask_BrushId;
                 *  brushTileData |= tileData & Tileset.k_TileDataMask_BrushId;
                 * }*/

                return(brushTileData);
            }
            return(tileData);
        }
示例#16
0
 public bool AutotileWith(int selfBrushId, int otherBrushId)
 {
     if (
         ((AutotilingMode & eAutotilingMode.Self) != 0 && selfBrushId == otherBrushId) ||
         ((AutotilingMode & eAutotilingMode.Other) != 0 && otherBrushId != selfBrushId && otherBrushId != (Tileset.k_TileDataMask_BrushId >> 16))
         )
     {
         return(true);
     }
     else if ((AutotilingMode & eAutotilingMode.Group) != 0)
     {
         TilesetBrush brush = Tileset.FindBrush(otherBrushId);
         if (brush)
         {
             return(Tileset.GetGroupAutotiling(Group, brush.Group));
         }
     }
     return(false);
 }
示例#17
0
文件: Tileset.cs 项目: Aye1/Herborist
        public string[] UpdateBrushTypeArray()
        {
            List <string> outList = new List <string>();

            for (int i = 0; i < Brushes.Count; ++i)
            {
                TilesetBrush brush = Brushes[i].BrushAsset;
                if (brush)
                {
                    string type = brush.GetType().Name;
                    if (!outList.Contains(type))
                    {
                        outList.Add(type);
                    }
                }
            }
            m_brushTypeMaskOptions = outList.ToArray();
            return(m_brushTypeMaskOptions);
        }
示例#18
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);
        }
示例#19
0
        /// <summary>
        /// Rotate the map 90 degrees clockwise
        /// </summary>
        /// <param name="changeFlags"></param>
        public void Rot90(bool changeFlags)
        {
            List <uint> flippedList = new List <uint>(GridWidth * GridHeight);

            for (int gy = MinGridY; gy <= MaxGridY; ++gy)
            {
                for (int gx = MinGridX; gx <= MaxGridX; ++gx)
                {
                    flippedList.Add(GetTileData(gx, gy));
                }
            }

            int minGridX = MinGridX;
            int minGridY = MinGridY;
            int maxGridX = MaxGridY;
            int maxGridY = MaxGridX;

            ClearMap();

            int idx = 0;

            for (int gx = minGridX; gx <= maxGridX; ++gx)
            {
                for (int gy = maxGridY; gy >= minGridY; --gy, ++idx)
                {
                    uint flippedTileData = flippedList[idx];
                    if (
                        changeFlags &&
                        (flippedTileData != Tileset.k_TileData_Empty) &&
                        (flippedTileData & Tileset.k_TileDataMask_BrushId) == 0    // don't activate flip flags on brushes
                        )
                    {
                        flippedTileData = TilesetBrush.ApplyAndMergeTileFlags(flippedTileData, Tileset.k_TileFlag_Rot90);
                    }
                    SetTileData(gx, gy, flippedTileData);
                }
            }
        }
示例#20
0
 public bool AutotileWith(int selfBrushId, int otherBrushId)
 {
     if (
         ((AutotilingMode & eAutotilingMode.Self) != 0 && selfBrushId == otherBrushId) ||
         ((AutotilingMode & eAutotilingMode.Other) != 0 && otherBrushId != selfBrushId && otherBrushId != (Tileset.k_TileDataMask_BrushId >> 16))
         )
     {
         return(true);
     }
     if ((AutotilingMode & eAutotilingMode.Group) != 0)
     {
         TilesetBrush brush = Tileset.FindBrush(otherBrushId);
         if (brush)
         {
             return(Tileset.GetGroupAutotiling(Group, brush.Group));
         }
         else if (otherBrushId == Tileset.k_BrushId_Default)
         {
             return(Tileset.GetGroupAutotiling(Group, 0)); //with normal tiles, use default group (0) //TODO: this is old code, now it is possible to change tile group. Check if this method is useful after removing it from TilemapChunk
         }
     }
     return(false);
 }
示例#21
0
        private void DisplayBrushReorderableList()
        {
            Event e = Event.current;

            if (m_brushList == null || m_brushList.list != Tileset.Brushes)
            {
                if (e.type != EventType.Layout)
                {
                    m_brushList = TilesetEditor.CreateBrushReorderableList(Tileset);
                    m_brushList.onSelectCallback += (ReorderableList list) =>
                    {
                        Tileset.BrushContainer brushCont = Tileset.Brushes[list.index];
                        Tileset.SelectedBrushId = brushCont.Id;
                        RemoveTileSelection();
                        if (m_dblClick.IsDblClick)
                        {
                            EditorGUIUtility.PingObject(brushCont.BrushAsset);
                            m_selectBrushInInspector = brushCont.BrushAsset;
                        }
                    };
                }
            }
            else
            {
                GUILayout.BeginVertical(m_customBox);
                m_brushList.index         = Tileset.Brushes.FindIndex(x => x.Id == Tileset.SelectedBrushId);
                m_brushList.index         = Mathf.Clamp(m_brushList.index, -1, Tileset.Brushes.Count - 1);
                m_brushList.elementHeight = Tileset.VisualTileSize.y + 10f;
                m_brushList.DoLayoutList();
                Rect rList = GUILayoutUtility.GetLastRect();
                if (e.isMouse && !rList.Contains(e.mousePosition))
                {
                    m_brushList.ReleaseKeyboardFocus();
                }
                GUILayout.EndVertical();
            }
        }
示例#22
0
        public override uint[] GetSubtiles(STETilemap tilemap, int gridX, int gridY, uint tileData)
        {
            // Add animated tiles
            {
                int  brushId      = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16);
                bool autotiling_N = AutotileWith(tilemap, brushId, gridX, gridY + 1);
                bool autotiling_E = AutotileWith(tilemap, brushId, gridX + 1, gridY);
                bool autotiling_S = AutotileWith(tilemap, brushId, gridX, gridY - 1);
                bool autotiling_W = AutotileWith(tilemap, brushId, gridX - 1, gridY);

                int idx = 0;
                if (autotiling_N)
                {
                    idx = 1;
                }
                if (autotiling_E)
                {
                    idx |= 2;
                }
                if (autotiling_S)
                {
                    idx |= 4;
                }
                if (autotiling_W)
                {
                    idx |= 8;
                }

                TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(TileIds[idx]));
                if (brush && brush.IsAnimated())
                {
                    TilemapChunk.RegisterAnimatedBrush(brush);
                }
            }
            return(null);
        }
示例#23
0
文件: Tileset.cs 项目: Aye1/Herborist
 public void AddBrush(TilesetBrush brush)
 {
     if (brush.Tileset == this)
     {
         if (!m_brushes.Exists(x => x.BrushAsset == brush))
         {
             int id    = m_brushes.Count > 0 ? m_brushes[m_brushes.Count - 1].Id : 1; //NOTE: id 0 is reserved for default brush
             int maxId = (int)(k_TileDataMask_BrushId >> 16);
             if (m_brushes.Count >= maxId)
             {
                 Debug.LogError(" Max number of brushes reached! " + maxId);
             }
             else
             {
                 // find a not used id
                 while (m_brushes.Exists(x => x.Id == id))
                 {
                     ++id;
                     if (id > maxId)
                     {
                         id = 1;
                     }
                 }
                 m_brushes.Add(new BrushContainer()
                 {
                     Id = id, BrushAsset = brush
                 });
                 m_brushCache.Clear();
             }
         }
     }
     else
     {
         Debug.LogWarning("This brush " + brush.name + " has a different tileset and will not be added! ");
     }
 }
示例#24
0
        private bool m_displayAutocompleteBtn = false; // fix gui warning when button appears
        public void Display(Vector2 visualTileSize)
        {
            GUI.changed |= m_hasChanged;
            m_hasChanged = false;
            Event e = Event.current;
            bool  isLeftMouseReleased = e.type == EventType.MouseUp && e.button == 0;

            if (isLeftMouseReleased)
            {
                m_hasFocus = m_tileSelectionRect.Contains(e.mousePosition);
            }

            bool  hasEmptyTiles        = false;
            int   size                 = m_width * m_height;
            Color cSelectedBorderColor = new Color(1f, 1f, 0f, 1f);

            if (!m_hasFocus)
            {
                cSelectedBorderColor *= .8f;
            }
            GUILayout.BeginHorizontal();
            {
                // Draw Autotile Combination Control
                GUI.backgroundColor = Tileset.BackgroundColor;
                GUILayoutUtility.GetRect(visualTileSize.x * m_width, visualTileSize.y * m_height + 1f);
                Rect rArea = GUILayoutUtility.GetLastRect();
                {
                    if (m_backgroundTexture)
                    {
                        GUI.DrawTexture(new Rect(rArea.position, Vector2.Scale(visualTileSize, new Vector2(m_width, m_height))), m_backgroundTexture);
                    }
                    GUI.backgroundColor = Color.white;
                    for (int tileIdx = 0; tileIdx < size; ++tileIdx)
                    {
                        int  gx          = tileIdx % m_width;
                        int  gy          = tileIdx / m_width;
                        Rect rVisualTile = new Rect(gx * visualTileSize.x, gy * visualTileSize.y, visualTileSize.x, visualTileSize.y);
                        rVisualTile.position += rArea.position;
                        uint tileData = m_getTileDataFunc(tileIdx);
                        hasEmptyTiles |= tileData == Tileset.k_TileData_Empty;
                        TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData));
                        if (brush)
                        {
                            tileData = TilesetBrush.ApplyAndMergeTileFlags(brush.PreviewTileData(), tileData);
                        }
                        int tileId = (int)(tileData & Tileset.k_TileDataMask_TileId);
                        if (tileId != Tileset.k_TileId_Empty)
                        {
                            TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, tileData, Tileset);
                        }

                        Color bgColor = new Color(1f - Tileset.BackgroundColor.r, 1f - Tileset.BackgroundColor.g, 1f - Tileset.BackgroundColor.b, Tileset.BackgroundColor.a);
                        HandlesEx.DrawRectWithOutline(rVisualTile, m_selectedTileIdx == tileIdx ? new Color(0f, 0f, 0f, 0.1f) : new Color(), m_selectedTileIdx == tileIdx ? cSelectedBorderColor : bgColor);

                        if (isLeftMouseReleased && rVisualTile.Contains(e.mousePosition))
                        {
                            m_selectedTileIdx = tileIdx;
                            EditorWindow wnd = EditorWindow.focusedWindow;
                            TileSelectionWindow.Show(Tileset);
                            TileSelectionWindow.Instance.Ping();
                            wnd.Focus();
                            GUI.FocusControl("");
                        }
                    }
                }

                uint brushTileData = m_selectedTileIdx >= 0 ? m_getTileDataFunc(m_selectedTileIdx) : Tileset.k_TileData_Empty;
                brushTileData = DoTileDataPropertiesLayout(brushTileData, Tileset, AllowBrushSelection);
                if (m_selectedTileIdx >= 0)
                {
                    m_setTileDataFunc(m_selectedTileIdx, brushTileData);
                }
            }
            GUILayout.EndHorizontal();

            if (e.type == EventType.Repaint)
            {
                m_tileSelectionRect = GUILayoutUtility.GetLastRect();
            }

            m_displayAutocompleteBtn = e.type == EventType.Layout ? !hasEmptyTiles && m_tileIdOff != 0 : m_displayAutocompleteBtn;
            if (size > 1 && m_displayAutocompleteBtn && GUILayout.Button("Autocomplete relative to last change"))
            {
                Undo.RecordObject(m_target, "MultipleTileChanged");
                for (int tileIdx = 0; tileIdx < size; ++tileIdx)
                {
                    if (tileIdx != m_tileIdOffSkipIdx)
                    {
                        int brushTileId = (int)(m_getTileDataFunc(tileIdx) & Tileset.k_TileDataMask_TileId);
                        brushTileId += m_tileIdOff;
                        if (brushTileId < 0 || brushTileId >= m_tileset.Tiles.Count)
                        {
                            m_setTileDataFunc(tileIdx, Tileset.k_TileData_Empty);
                        }
                        else
                        {
                            uint tileData = m_getTileDataFunc(tileIdx);
                            tileData &= ~Tileset.k_TileDataMask_TileId;
                            tileData |= (uint)(brushTileId & Tileset.k_TileDataMask_TileId);
                            m_setTileDataFunc(tileIdx, tileData);
                        }
                    }
                }
                m_tileIdOff = 0;
                EditorUtility.SetDirty(m_target);
            }
            if (Tileset.TileSelection != null && Tileset.TileSelection.selectionData.Count == m_width * m_height && Tileset.TileSelection.rowLength == m_width)
            {
                if (GUILayout.Button("Autocomplete from selection"))
                {
                    Undo.RecordObject(m_target, "MultipleTileChanged");
                    for (int tileIdx = 0; tileIdx < size; ++tileIdx)
                    {
                        int selectionIdx = (tileIdx % m_width) + (m_height - 1 - tileIdx / m_width) * m_width;
                        int brushTileId  = (int)(Tileset.TileSelection.selectionData[selectionIdx] & Tileset.k_TileDataMask_TileId);
                        m_setTileDataFunc(tileIdx, (uint)(brushTileId & Tileset.k_TileDataMask_TileId));
                    }
                    m_tileIdOff = 0;
                    EditorUtility.SetDirty(m_target);
                }
            }

            if (ShowHelpBox)
            {
                EditorGUILayout.HelpBox(HelpBoxText, MessageType.Info);
            }
        }
示例#25
0
        public override void OnEnable()
        {
            base.OnEnable();
            m_brush = (RandomBrush)target;
            if (m_brush.Tileset != null)
            {
                m_brush.Tileset.OnTileSelected  += OnTileSelected;
                m_brush.Tileset.OnBrushSelected += OnBrushSelected;
            }

            m_randTileList = new ReorderableList(serializedObject, serializedObject.FindProperty("RandomTileList"), true, true, true, true);
            m_randTileList.drawHeaderCallback += (Rect rect) =>
            {
                EditorGUI.LabelField(rect, "Random Tiles", EditorStyles.boldLabel);
            };
            m_randTileList.drawElementCallback += (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                Rect         rTile    = rect; rTile.width = rTile.height = m_brush.Tileset.VisualTileSize.y;
                uint         tileData = m_brush.RandomTileList[index].tileData;
                int          tileId   = (int)(tileData & Tileset.k_TileDataMask_TileId);
                int          brushId  = Tileset.GetBrushIdFromTileData(tileData);
                TilesetBrush brush    = m_brush.Tileset.FindBrush(brushId);
                if (brush)
                {
                    GUI.Box(new Rect(rTile.position - Vector2.one, rTile.size + 2 * Vector2.one), "");
                    TilesetEditor.DoGUIDrawTileFromTileData(rTile, tileData, m_brush.Tileset, brush.GetAnimUV());
                }
                else if (tileId != Tileset.k_TileId_Empty)
                {
                    GUI.Box(new Rect(rTile.position - Vector2.one, rTile.size + 2 * Vector2.one), "");
                    TilesetEditor.DoGUIDrawTileFromTileData(rTile, tileData, m_brush.Tileset);
                }

                Rect rTileId = rect;
                rTileId.x     += rTile.width + 10; rTileId.width -= rTile.width + 20;
                rTileId.height = rect.height / 2;
                if (brush)
                {
                    GUI.Label(rTileId, "Brush Id(" + brushId + ")");
                }
                else
                {
                    GUI.Label(rTileId, "Id(" + tileId + ")");
                }

                SerializedProperty randomTileDataProperty    = m_randTileList.serializedProperty.GetArrayElementAtIndex(index);
                SerializedProperty probabilityFactorProperty = randomTileDataProperty.FindPropertyRelative("probabilityFactor");
                Rect  rProbabilityField    = new Rect(rect.x + rTile.width + 10f, rect.y + EditorGUIUtility.singleLineHeight * 2.5f, rect.width - rTile.width - 10f, EditorGUIUtility.singleLineHeight);
                Rect  rProbabilityLabel    = new Rect(rProbabilityField.x, rProbabilityField.y - EditorGUIUtility.singleLineHeight, rProbabilityField.width, rProbabilityField.height);
                float sumProbabilityFactor = m_brush.GetSumProbabilityFactor();
                float probability          = sumProbabilityFactor >= 0 ? probabilityFactorProperty.floatValue * 100f / sumProbabilityFactor : 100f;
                EditorGUI.PrefixLabel(rProbabilityLabel, new GUIContent("Probability (" + Mathf.RoundToInt(probability) + "%)"));
                EditorGUI.PropertyField(rProbabilityField, probabilityFactorProperty, GUIContent.none);
                if (probabilityFactorProperty.floatValue == 0f)
                {
                    serializedObject.ApplyModifiedProperties();
                    sumProbabilityFactor = m_brush.GetSumProbabilityFactor();
                    if (sumProbabilityFactor <= 0f)
                    {
                        probabilityFactorProperty.floatValue = 0.01f;
                    }
                }

                if (GUI.Button(new Rect(rect.x + rect.width - 50f, rect.y, 50f, EditorGUIUtility.singleLineHeight), "Clear"))
                {
                    m_brush.RandomTileList[index].tileData = Tileset.k_TileData_Empty;
                }
            };
            m_randTileList.onSelectCallback += (ReorderableList list) =>
            {
                TileSelectionWindow.Show(m_brush.Tileset);
                TileSelectionWindow.Instance.Ping();
            };
            m_randTileList.onAddCallback += (ReorderableList list) =>
            {
                if (list.index >= 0)
                {
                    list.serializedProperty.InsertArrayElementAtIndex(list.index);
                }
                else
                {
                    list.serializedProperty.InsertArrayElementAtIndex(0);
                }
                list.index = Mathf.Max(0, list.index + 1);
                list.serializedProperty.serializedObject.ApplyModifiedProperties();
                m_brush.RandomTileList[list.index].probabilityFactor = 1f;
                if (m_brush.Tileset.SelectedTile != null)
                {
                    m_randTileList.GrabKeyboardFocus();
                    OnTileSelected(m_brush.Tileset, -1, m_brush.Tileset.SelectedTileId);
                }
            };
        }
示例#26
0
        public void SetTileData(int locGridX, int locGridY, uint tileData)
        {
            if (locGridX >= 0 && locGridX < m_width && locGridY >= 0 && locGridY < m_height)
            {
                int tileIdx = locGridY * m_width + locGridX;

                int  tileId = (int)(tileData & Tileset.k_TileDataMask_TileId);
                Tile tile   = Tileset.GetTile(tileId);

                int  prevTileId = (int)(m_tileDataList[tileIdx] & Tileset.k_TileDataMask_TileId);
                Tile prevTile   = Tileset.GetTile(prevTileId);

                int brushId     = Tileset.GetBrushIdFromTileData(tileData);
                int prevBrushId = Tileset.GetBrushIdFromTileData(m_tileDataList[tileIdx]);

                if (brushId != prevBrushId ||
                    brushId == 0)                //NOTE: because of the autotiling mode, neighbour tiles could be affected by this change, even if the tile is not a brush
                {
                    if (!s_currUpdatedTilechunk) // avoid this is chunks is being Updated from FillMeshData
                    {
                        // Refresh Neighbors ( and itself if needed )
                        for (int yf = -1; yf <= 1; ++yf)
                        {
                            for (int xf = -1; xf <= 1; ++xf)
                            {
                                if ((xf | yf) == 0)
                                {
                                    if (brushId > 0)
                                    {
                                        // Refresh itself
                                        tileData = (tileData & ~Tileset.k_TileFlag_Updated);
                                    }
                                }
                                else
                                {
                                    int          gx               = (locGridX + xf);
                                    int          gy               = (locGridY + yf);
                                    int          idx              = gy * m_width + gx;
                                    bool         isInsideChunk    = (gx >= 0 && gx < m_width && gy >= 0 && gy < m_height);
                                    uint         neighborTileData = isInsideChunk ? m_tileDataList[idx] : ParentTilemap.GetTileData(GridPosX + locGridX + xf, GridPosY + locGridY + yf);
                                    int          neighborBrushId  = (int)((neighborTileData & Tileset.k_TileDataMask_BrushId) >> 16);
                                    TilesetBrush neighborBrush    = ParentTilemap.Tileset.FindBrush(neighborBrushId);
                                    if (neighborBrush != null &&
                                        (neighborBrush.AutotileWith(ParentTilemap.Tileset, neighborBrushId, tileData) || neighborBrush.AutotileWith(ParentTilemap.Tileset, neighborBrushId, m_tileDataList[tileIdx])))
                                    {
                                        neighborTileData = (neighborTileData & ~Tileset.k_TileFlag_Updated); // force a refresh
                                        if (isInsideChunk)
                                        {
                                            m_tileDataList[idx] = neighborTileData;
                                        }
                                        else
                                        {
                                            ParentTilemap.SetTileData(GridPosX + gx, GridPosY + gy, neighborTileData);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else if (brushId > 0)
                {
                    // Refresh itself
                    tileData = (tileData & ~Tileset.k_TileFlag_Updated);
                }

                m_needsRebuildMesh      |= (m_tileDataList[tileIdx] != tileData) || (tileData & Tileset.k_TileDataMask_TileId) == Tileset.k_TileId_Empty;
                m_needsRebuildColliders |= m_needsRebuildMesh &&
                                           (
                    (prevBrushId > 0) || (brushId > 0) || // there is a brush (a brush could change the collider data later)
                    (tile != null && tile.collData.type != eTileCollider.None) || (prevTile != null && prevTile.collData.type != eTileCollider.None)    // prev. or new tile has colliders
                                           );

                if (ParentTilemap.ColliderType != eColliderType.None && m_needsRebuildColliders)
                {
                    // Refresh Neighbors tilechunk colliders, to make the collider autotiling
                    // Only if neighbor is outside this tilechunk
                    for (int yf = -1; yf <= 1; ++yf)
                    {
                        for (int xf = -1; xf <= 1; ++xf)
                        {
                            if ((xf | yf) != 0) // skip this tile position xf = yf = 0
                            {
                                int  gx            = (locGridX + xf);
                                int  gy            = (locGridY + yf);
                                bool isInsideChunk = (gx >= 0 && gx < m_width && gy >= 0 && gy < m_height);
                                if (!isInsideChunk)
                                {
                                    ParentTilemap.InvalidateChunkAt(GridPosX + gx, GridPosY + gy, false, true);
                                }
                            }
                        }
                    }
                }

                // Update tile data
                m_tileDataList[tileIdx] = tileData;

                if (!STETilemap.DisableTilePrefabCreation)
                {
                    // Create tile Objects
                    if (tile != null && tile.prefabData.prefab != null)
                    {
                        CreateTileObject(tileIdx, tile.prefabData);
                    }
                    else
                    {
                        DestroyTileObject(tileIdx);
                    }
                }

                TilesetBrush brush = ParentTilemap.Tileset.FindBrush(brushId);
                if (brushId != prevBrushId)
                {
                    TilesetBrush prevBrush = ParentTilemap.Tileset.FindBrush(prevBrushId);
                    if (prevBrush != null)
                    {
                        prevBrush.OnErase(this, locGridX, locGridY, tileData, prevBrushId);
                    }
                }
                if (brush != null)
                {
                    tileData = brush.OnPaint(this, locGridX, locGridY, tileData);
                }
            }
        }
示例#27
0
        public void Display()
        {
            Event e = Event.current;

            m_dblClick.Update();

            // This way a gui exception is avoided
            if (e.type == EventType.Layout && m_selectBrushInInspector != null)
            {
                Selection.activeObject   = m_selectBrushInInspector;
                m_selectBrushInInspector = null;
            }

            if (m_lastTime == 0f)
            {
                m_lastTime = Time.realtimeSinceStartup;
            }
            m_timeDt   = Time.realtimeSinceStartup - m_lastTime;
            m_lastTime = Time.realtimeSinceStartup;

            if (Tileset == null)
            {
                EditorGUILayout.HelpBox("There is no tileset selected", MessageType.Info);
                return;
            }
            else if (Tileset.AtlasTexture == null)
            {
                EditorGUILayout.HelpBox("There is no atlas texture set", MessageType.Info);
                return;
            }
            else if (Tileset.Tiles.Count == 0)
            {
                EditorGUILayout.HelpBox("There are no tiles to show in the current tileset", MessageType.Info);
                return;
            }

            if (m_scrollStyle == null)
            {
                m_scrollStyle = new GUIStyle("ScrollView");
            }

            if (m_customBox == null)
            {
                m_customBox = new GUIStyle("Box");
            }

            float visualTilePadding       = 1;
            bool  isLeftMouseReleased     = e.type == EventType.MouseUp && e.button == 0;
            bool  isRightMouseReleased    = e.type == EventType.MouseUp && e.button == 1;
            bool  isInsideTileScrollArea  = e.isMouse && m_rTileScrollArea.Contains(e.mousePosition);
            bool  isInsideBrushScrollArea = e.isMouse && m_rBrushScrollArea.Contains(e.mousePosition);

            // TileViews
            if (m_tileViewList == null || m_tileViewList.list != Tileset.TileViews)
            {
                if (e.type != EventType.Layout)
                {
                    m_tileViewList = TilesetEditor.CreateTileViewReorderableList(Tileset);
                    m_tileViewList.onSelectCallback += (ReorderableList list) =>
                    {
                        m_viewMode = eViewMode.TileView;
                        RemoveTileSelection();
                    };
                    m_tileViewList.onRemoveCallback += (ReorderableList list) =>
                    {
                        RemoveTileSelection();
                    };
                }
            }
            else
            {
                GUI.color = Color.cyan;
                GUILayout.BeginVertical(m_customBox);
                m_tileViewList.index = Mathf.Clamp(m_tileViewList.index, -1, Tileset.TileViews.Count - 1);
                m_tileViewList.DoLayoutList();
                Rect rList = GUILayoutUtility.GetLastRect();
                if (e.isMouse && !rList.Contains(e.mousePosition))
                {
                    m_tileViewList.ReleaseKeyboardFocus();
                }
                GUILayout.EndVertical();
                GUI.color = Color.white;
            }
            TileView tileView = m_tileViewList != null && m_tileViewList.index >= 0 ? Tileset.TileViews[m_tileViewList.index] : null;

            if (m_viewMode == eViewMode.Tileset)
            {
                Tileset.TileRowLength = Mathf.Clamp(EditorGUILayout.IntField("TileRowLength", Tileset.TileRowLength), 1, Tileset.Width);
            }

            m_viewMode = (eViewMode)EditorGUILayout.EnumPopup("View Mode", m_viewMode);
            if (tileView == null)
            {
                m_viewMode = eViewMode.Tileset;
            }
            if (m_viewMode != m_prevViewMode)
            {
                m_prevViewMode = m_viewMode;
                RemoveTileSelection();
            }

            // Draw Background Color Selector
            Tileset.BackgroundColor = EditorGUILayout.ColorField("Background Color", Tileset.BackgroundColor);
            if (m_prevBgColor != Tileset.BackgroundColor || m_scrollStyle.normal.background == null)
            {
                m_prevBgColor = Tileset.BackgroundColor;
                if (m_scrollStyle.normal.background == null)
                {
                    m_scrollStyle.normal.background = new Texture2D(1, 1)
                    {
                        hideFlags = HideFlags.DontSave
                    }
                }
                ;
                m_scrollStyle.normal.background.SetPixel(0, 0, Tileset.BackgroundColor);
                m_scrollStyle.normal.background.Apply();
            }
            //---

            string sTileIdLabel = Tileset.SelectedTileId != Tileset.k_TileId_Empty? " (id:" + Tileset.SelectedTileId + ")" : "";

            EditorGUILayout.LabelField("Tile Palette" + sTileIdLabel, EditorStyles.boldLabel);

            // keeps values safe
            m_tileViewRowLength = Mathf.Max(1, m_tileViewRowLength);

            float tileAreaWidth  = m_tileViewRowLength * (Tileset.VisualTileSize.x + visualTilePadding) + 4f;
            float tileAreaHeight = (Tileset.VisualTileSize.y + visualTilePadding) * (1 + (m_visibleTileCount - 1) / m_tileViewRowLength) + 4f;

            m_tileViewRowLength = m_viewMode == eViewMode.TileView && tileView != null ? tileView.tileSelection.rowLength : Tileset.TileRowLength;

            m_tilesScrollPos = EditorGUILayout.BeginScrollView(m_tilesScrollPos, m_scrollStyle);
            {
                // Scroll Moving Drag
                if (e.type == EventType.MouseDrag && (e.button == 1 || e.button == 2))
                {
                    m_tilesScrollPos -= e.delta;
                }
                else
                {
                    DoAutoScroll();
                }

                if (e.isMouse)
                {
                    m_lastTileScrollMousePos = e.mousePosition;
                }
                if (Tileset.Tiles != null)
                {
                    GUILayoutUtility.GetRect(tileAreaWidth, tileAreaHeight);
                    m_visibleTileCount = 0;
                    List <uint> visibleTileList = new List <uint>();
                    int         tileViewWidth   = m_viewMode == eViewMode.Tileset ? Tileset.Width : tileView.tileSelection.rowLength;
                    int         tileViewHeight  = m_viewMode == eViewMode.Tileset ? Tileset.Height : ((tileView.tileSelection.selectionData.Count - 1) / tileView.tileSelection.rowLength) + 1;
                    int         totalCount      = ((((tileViewWidth - 1) / m_tileViewRowLength) + 1) * m_tileViewRowLength) * tileViewHeight;
                    for (int i = 0; i < totalCount; ++i)
                    {
                        int  tileId   = GetTileIdFromIdx(i, m_tileViewRowLength, tileViewWidth, tileViewHeight);
                        uint tileData = (uint)tileId;
                        if (m_viewMode == eViewMode.TileView && tileId != Tileset.k_TileId_Empty)
                        {
                            tileData = tileView.tileSelection.selectionData[tileId];
                            tileId   = (int)(tileData & Tileset.k_TileDataMask_TileId);
                        }
                        Tile tile = tileId != Tileset.k_TileId_Empty && tileId < Tileset.Tiles.Count ? Tileset.Tiles[tileId] : null;
                        visibleTileList.Add(tileData);

                        int  tx          = m_visibleTileCount % m_tileViewRowLength;
                        int  ty          = m_visibleTileCount / m_tileViewRowLength;
                        Rect rVisualTile = new Rect(2 + tx * (Tileset.VisualTileSize.x + visualTilePadding), 2 + ty * (Tileset.VisualTileSize.y + visualTilePadding), Tileset.VisualTileSize.x, Tileset.VisualTileSize.y);

                        // Optimization, skipping not visible tiles
                        Rect rLocalVisualTile = rVisualTile; rLocalVisualTile.position -= m_tilesScrollPos;
                        if (!rLocalVisualTile.Overlaps(m_rTileScrollSize))
                        {
                            ; // Do Nothing
                        }
                        else
                        //---
                        {
                            // Draw Tile
                            if (tile == null)
                            {
                                HandlesEx.DrawRectWithOutline(rVisualTile, new Color(0f, 0f, 0f, 0.2f), new Color(0f, 0f, 0f, 0.2f));
                            }
                            else
                            {
                                HandlesEx.DrawRectWithOutline(rVisualTile, new Color(0f, 0f, 0f, 0.1f), new Color(0f, 0f, 0f, 0.1f));
                                TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, tileData, Tileset);
                            }

                            Rect rTileRect = new Rect(2 + tx * (Tileset.VisualTileSize.x + visualTilePadding), 2 + ty * (Tileset.VisualTileSize.y + visualTilePadding), (Tileset.VisualTileSize.x + visualTilePadding), (Tileset.VisualTileSize.y + visualTilePadding));
                            if (rVisualTile.Contains(e.mousePosition))
                            {
                                if (e.type == EventType.MouseDrag && e.button == 0)
                                {
                                    m_pointedTileIdxRect = new KeyValuePair <int, Rect>(m_visibleTileCount, rTileRect);
                                }
                                else if (e.type == EventType.MouseDown && e.button == 0)
                                {
                                    m_startDragTileIdxRect = m_pointedTileIdxRect = m_endDragTileIdxRect = new KeyValuePair <int, Rect>(m_visibleTileCount, rTileRect);
                                }
                                else if (e.type == EventType.MouseUp && e.button == 0)
                                {
                                    m_endDragTileIdxRect = new KeyValuePair <int, Rect>(m_visibleTileCount, rTileRect);
                                    DoSetTileSelection();
                                }
                            }

                            if ((isLeftMouseReleased || isRightMouseReleased) && isInsideTileScrollArea && rVisualTile.Contains(e.mousePosition) &&
                                (m_startDragTileIdxRect.Key == m_endDragTileIdxRect.Key) && // and there is not dragging selection
                                m_rTileScrollSize.Contains(e.mousePosition - m_tilesScrollPos))   // and it's inside the scroll area
                            {
                                Tileset.SelectedTileId = tileId;

                                //Give focus to SceneView to get key events
                                FocusSceneView();

                                if (isRightMouseReleased)
                                {
                                    TilePropertiesWindow.Show(Tileset);
                                }
                            }
                            else if (tile != null && Tileset.SelectedTileId == tileId)
                            {
                                HandlesEx.DrawRectWithOutline(rTileRect, new Color(0f, 0f, 0f, 0.1f), new Color(1f, 1f, 0f, 1f));
                            }
                        }

                        ++m_visibleTileCount;
                    }
                    m_visibleTileList = visibleTileList;

                    // Draw selection rect
                    if (m_startDragTileIdxRect.Key != m_pointedTileIdxRect.Key /*&& m_startDragTileIdxRect.Key == m_endDragTileIdxRect.Key*/)
                    {
                        Rect rSelection = new Rect(m_startDragTileIdxRect.Value.center, m_pointedTileIdxRect.Value.center - m_startDragTileIdxRect.Value.center);
                        rSelection.Set(Mathf.Min(rSelection.xMin, rSelection.xMax), Mathf.Min(rSelection.yMin, rSelection.yMax), Mathf.Abs(rSelection.width), Mathf.Abs(rSelection.height));
                        rSelection.xMin -= m_startDragTileIdxRect.Value.width / 2;
                        rSelection.xMax += m_startDragTileIdxRect.Value.width / 2;
                        rSelection.yMin -= m_startDragTileIdxRect.Value.height / 2;
                        rSelection.yMax += m_startDragTileIdxRect.Value.height / 2;
                        HandlesEx.DrawRectWithOutline(rSelection, new Color(0f, 0f, 0f, 0.1f), new Color(1f, 1f, 1f, 1f));
                    }
                }
            }
            EditorGUILayout.EndScrollView();
            if (e.type == EventType.Repaint)
            {
                m_rTileScrollArea          = GUILayoutUtility.GetLastRect();
                m_rTileScrollSize          = m_rTileScrollArea;
                m_rTileScrollSize.position = Vector2.zero; // reset position to the Contains and Overlaps inside the tile scroll view without repositioning the position of local positions
                if (tileAreaWidth > m_rTileScrollSize.width)
                {
                    m_rTileScrollSize.height -= GUI.skin.verticalScrollbar.fixedWidth;
                }
                if (tileAreaHeight > m_rTileScrollSize.height)
                {
                    m_rTileScrollSize.width -= GUI.skin.verticalScrollbar.fixedWidth;
                }
            }

            EditorGUILayout.BeginHorizontal();
            string sBrushIdLabel = Tileset.SelectedBrushId > 0 ? " (id:" + Tileset.SelectedBrushId + ")" : "";

            EditorGUILayout.LabelField("Brush Palette" + sBrushIdLabel, EditorStyles.boldLabel);
            m_displayBrushReordList = EditorUtils.DoToggleButton("Display List", m_displayBrushReordList);
            EditorGUILayout.EndHorizontal();

            int tileRowLength = (int)(m_rTileScrollSize.width / (Tileset.VisualTileSize.x + visualTilePadding));

            if (tileRowLength <= 0)
            {
                tileRowLength = 1;
            }
            float fBrushesScrollMaxHeight = Screen.height / 4;
            //commented because m_rTileScrollSize.width.height was changed to Screen.height;  fBrushesScrollMaxHeight -= fBrushesScrollMaxHeight % 2; // sometimes because size of tile scroll affects size of brush scroll, the height is dancing between +-1, so this is always taking the pair value
            float fBrushesScrollHeight = Mathf.Min(fBrushesScrollMaxHeight, 4 + (Tileset.VisualTileSize.y + visualTilePadding) * (1 + (Tileset.Brushes.Count / tileRowLength)));

            EditorGUILayout.BeginVertical(GUILayout.MinHeight(fBrushesScrollHeight));
            if (m_displayBrushReordList)
            {
                DisplayBrushReorderableList();
            }
            else
            {
                bool isRefreshBrushes = false;
                m_brushesScrollPos = EditorGUILayout.BeginScrollView(m_brushesScrollPos, m_scrollStyle);
                {
                    Rect rScrollView = new Rect(0, 0, m_rTileScrollSize.width, 0);
                    tileRowLength = Mathf.Clamp((int)rScrollView.width / (int)(Tileset.VisualTileSize.x + visualTilePadding), 1, tileRowLength);
                    if (Tileset.Brushes != null)
                    {
                        GUILayout.Space((Tileset.VisualTileSize.y + visualTilePadding) * (1 + (Tileset.Brushes.Count - 1) / tileRowLength));
                        for (int i = 0; i < Tileset.Brushes.Count; ++i)
                        {
                            Tileset.BrushContainer brushCont = Tileset.Brushes[i];
                            if (brushCont.BrushAsset == null)
                            {
                                isRefreshBrushes = true;
                                continue;
                            }

                            int  tx          = i % tileRowLength;
                            int  ty          = i / tileRowLength;
                            Rect rVisualTile = new Rect(2 + tx * (Tileset.VisualTileSize.x + visualTilePadding), 2 + ty * (Tileset.VisualTileSize.y + visualTilePadding), Tileset.VisualTileSize.x, Tileset.VisualTileSize.y);
                            //Fix Missing Tileset reference
                            if (brushCont.BrushAsset.Tileset == null)
                            {
                                Debug.LogWarning("Fixed missing tileset reference in brush " + brushCont.BrushAsset.name + " Id(" + brushCont.Id + ")");
                                brushCont.BrushAsset.Tileset = Tileset;
                            }
                            uint tileData = Tileset.k_TileData_Empty;
                            if (brushCont.BrushAsset.IsAnimated())
                            {
                                tileData = brushCont.BrushAsset.GetAnimTileData();
                            }
                            else
                            {
                                tileData = brushCont.BrushAsset.PreviewTileData();
                            }
                            TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, tileData, Tileset, brushCont.BrushAsset.GetAnimUV());
                            if ((isLeftMouseReleased || isRightMouseReleased || m_dblClick.IsDblClick) && isInsideBrushScrollArea && rVisualTile.Contains(Event.current.mousePosition))
                            {
                                Tileset.SelectedBrushId = brushCont.Id;
                                RemoveTileSelection();
                                if (m_dblClick.IsDblClick)
                                {
                                    EditorGUIUtility.PingObject(brushCont.BrushAsset);
                                    m_selectBrushInInspector = brushCont.BrushAsset;
                                }
                                if (isRightMouseReleased)
                                {
                                    TilePropertiesWindow.Show(Tileset);
                                }
                            }
                            else if (Tileset.SelectedBrushId == brushCont.Id)
                            {
                                Rect rSelection = new Rect(2 + tx * (Tileset.VisualTileSize.x + visualTilePadding), 2 + ty * (Tileset.VisualTileSize.y + visualTilePadding), (Tileset.VisualTileSize.x + visualTilePadding), (Tileset.VisualTileSize.y + visualTilePadding));
                                HandlesEx.DrawRectWithOutline(rSelection, new Color(0f, 0f, 0f, 0.1f), new Color(1f, 1f, 0f, 1f));
                            }
                        }
                    }

                    if (isRefreshBrushes)
                    {
                        Tileset.RemoveNullBrushes();
                    }
                }
                EditorGUILayout.EndScrollView();
                if (e.type == EventType.Repaint)
                {
                    m_rBrushScrollArea = GUILayoutUtility.GetLastRect();
                }
            }
            EditorGUILayout.EndVertical();

            if (GUILayout.Button("Import all brushes found"))
            {
                TilesetEditor.AddAllBrushesFoundInTheProject(Tileset);
                EditorUtility.SetDirty(Tileset);
            }
        }
示例#28
0
        // '°', '├', '═', '┤', | 0, 2, 10, 8,
        // '┬', '╔', '╦', '╗', | 4, 6, 14, 12,
        // '║', '╠', '╬', '╣', | 5, 7, 15, 13,
        // '┴', '╚', '╩', '╝', | 1, 3, 11, 9,
        public override uint[] GetSubtiles(STETilemap 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)
                {
                    aSubTileData[i] = RefreshLinkedBrush(tilemap, gridX, gridY, aSubTileData[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);
        }
        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;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        /*
         * 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);
        }