public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (m_prevTileset != m_brush.Tileset)
            {
                OnDisable();
                OnEnable();
            }
            m_prevTileset = m_brush.Tileset;

            base.OnInspectorGUI();
            if (!m_brush.Tileset)
            {
                return;
            }

            Vector2 visualTileSize = m_brush.Tileset.VisualTileSize;

            EditorGUILayout.Space();

            GUILayoutUtility.GetRect(1f, 1f, GUILayout.Width(visualTileSize.x), GUILayout.Height(visualTileSize.y));
            Rect rSelectedTile = GUILayoutUtility.GetLastRect();
            uint tileData      = m_brush.GetAnimTileData();

            if (tileData != Tileset.k_TileData_Empty)
            {
                rSelectedTile.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, rSelectedTile.center.y);
                GUI.Box(new Rect(rSelectedTile.position - Vector2.one, rSelectedTile.size + 2 * Vector2.one), "");
                TilesetEditor.DoGUIDrawTileFromTileData(rSelectedTile, tileData, m_brush.Tileset);
            }

            EditorGUILayout.Space();
            uint brushTileData = m_randTileList.index >= 0 ? m_brush.RandomTiles[m_randTileList.index] : Tileset.k_TileData_Empty;

            brushTileData = BrushTileGridControl.DoTileDataPropertiesLayout(brushTileData, m_brush.Tileset, false);
            if (m_randTileList.index >= 0)
            {
                m_brush.RandomTiles[m_randTileList.index] = brushTileData;
            }
            EditorGUILayout.Space();

            // Draw List
            m_randTileList.elementHeight = visualTileSize.y + 10f;
            m_randTileList.DoLayoutList();

            EditorGUILayout.HelpBox("Select a tile from list and then select a tile from tile selection window.", MessageType.Info);
            EditorGUILayout.HelpBox("Add and Remove tiles with '+' and '-' buttons.", MessageType.Info);

            Repaint();
            serializedObject.ApplyModifiedProperties();
            if (GUI.changed)
            {
                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);
                }
            }
        }
        public override void OnEnable()
        {
            base.OnEnable();
            m_brush = (RandomBrush)target;
            if (m_brush.Tileset != null)
            {
                m_brush.Tileset.OnTileSelected += OnTileSelected;
            }

            m_randTileList = new ReorderableList(serializedObject, serializedObject.FindProperty("RandomTiles"), 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.RandomTiles[index];
                int  tileId   = (int)(tileData & Tileset.k_TileDataMask_TileId);
                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 + 20; rTileId.width -= rTile.width + 20;
                rTileId.height = rect.height / 2;
                GUI.Label(rTileId, "Id(" + tileId + ")");

                if (GUI.Button(new Rect(rect.x + rect.width - 50f, rect.y, 50f, EditorGUIUtility.singleLineHeight), "Empty"))
                {
                    m_brush.RandomTiles[index] = 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);
                }
            };
        }
示例#4
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);

            TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, (uint)property.intValue, 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);
        }
示例#5
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.
            uint         tileData = (uint)property.intValue;
            TilesetBrush brush    = tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData));

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

            TilesetEditor.DoGUIDrawTileFromTileData(position, tileData, tileset);
            if (isLeftMouseReleased && position.Contains(e.mousePosition))
            {
                EditorWindow wnd = EditorWindow.focusedWindow;
                TileSelectionWindow.Show(tileset, property);
                TileSelectionWindow.Instance.Ping();
                wnd.Focus();
                GUI.FocusControl("");
            }
        }
示例#6
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();
            }
        }
示例#7
0
        private void DisplayParameters()
        {
            Event         e             = Event.current;
            TileSelection tileSelection = Tileset.TileSelection;

            if (tileSelection != null)
            {
                EditorGUILayout.LabelField("Multi-tile editing not allowed", EditorStyles.boldLabel);
            }
            else
            {
                UnityEngine.Object prevOwner = m_parameterListOwner;
                if (Tileset.SelectedBrushId != Tileset.k_BrushId_Default)
                {
                    m_parameterListOwner = Tileset.FindBrush(Tileset.SelectedBrushId);
                }
                else
                {
                    m_parameterListOwner = Tileset;
                }

                if (m_parameterListOwner != null)
                {
                    if (prevOwner != m_parameterListOwner || Tileset.SelectedTileId != m_prevSelectedTileId || m_tileParameterList == null)
                    {
                        m_prevSelectedTileId = Tileset.SelectedTileId;
                        m_tileParameterList  = CreateParameterReorderableList(m_parameterListOwner is Tileset ?
                                                                              ((Tileset)m_parameterListOwner).SelectedTile.paramContainer :
                                                                              ((TilesetBrush)m_parameterListOwner).Params);
                        m_tileParameterList.onChangedCallback += (ReorderableList list) =>
                        {
                            EditorUtility.SetDirty(m_parameterListOwner);
                        };
                    }

                    GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y));
                    uint tilePreviewData = m_parameterListOwner is Tileset ?
                                           (uint)(((Tileset)m_parameterListOwner).SelectedTileId & Tileset.k_TileDataMask_TileId)
                        :
                                           ((TilesetBrush)m_parameterListOwner).GetAnimTileData();
                    Rect customUV = m_parameterListOwner is Tileset ? default(Rect) : ((TilesetBrush)m_parameterListOwner).GetAnimUV();
                    GUI.color = Tileset.BackgroundColor;
                    GUI.DrawTexture(GUILayoutUtility.GetLastRect(), EditorGUIUtility.whiteTexture);
                    GUI.color = Color.white;
                    TilesetEditor.DoGUIDrawTileFromTileData(GUILayoutUtility.GetLastRect(), tilePreviewData, Tileset, customUV);

                    m_tileParamScrollViewPos = EditorGUILayout.BeginScrollView(m_tileParamScrollViewPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
                    EditorGUI.BeginChangeCheck();
                    m_tileParameterList.DoLayoutList();
                    Rect rList = GUILayoutUtility.GetLastRect();
                    if (e.isMouse && !rList.Contains(e.mousePosition))
                    {
                        m_tileParameterList.ReleaseKeyboardFocus();
                        m_tileParameterList.index = -1;
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        EditorUtility.SetDirty(m_parameterListOwner);
                    }
                    EditorGUILayout.EndScrollView();
                }
            }
        }
        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);
                }
            };
        }
示例#9
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);
            }
        }
 public void Refresh()
 {
     m_tilePropertiesControl.Tileset = TilesetEditor.GetSelectedTileset();
     Repaint();
 }
示例#11
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (m_prevTileset != m_brush.Tileset)
            {
                if (m_prevTileset)
                {
                    m_prevTileset.OnBrushSelected -= OnBrushSelected;
                    m_prevTileset.OnTileSelected  -= OnTileSelected;
                }
                OnDisable();
                OnEnable();
            }
            m_prevTileset = m_brush.Tileset;

            base.OnInspectorGUI();
            if (!m_brush.Tileset)
            {
                return;
            }

            Vector2 visualTileSize = m_brush.Tileset.VisualTileSize;

            EditorGUILayout.Space();

            GUILayoutUtility.GetRect(1f, 1f, GUILayout.Width(visualTileSize.x), GUILayout.Height(visualTileSize.y));
            Rect rSelectedTile = GUILayoutUtility.GetLastRect();
            uint tileData      = m_brush.GetAnimTileData();

            if (tileData != Tileset.k_TileData_Empty)
            {
                rSelectedTile.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, rSelectedTile.center.y);
                GUI.Box(new Rect(rSelectedTile.position - Vector2.one, rSelectedTile.size + 2 * Vector2.one), "");
                TilesetEditor.DoGUIDrawTileFromTileData(rSelectedTile, tileData, m_brush.Tileset);
            }

            EditorGUILayout.Space();

            SerializedProperty randomFlagMaskProperty = serializedObject.FindProperty("RandomizeFlagMask");

            System.Enum enumNew = EditorGUILayout.EnumMaskField(new GUIContent("Random Flags", "Applies random flags when painting tiles"), (eRandomFlags)(randomFlagMaskProperty.longValue >> 29));
            randomFlagMaskProperty.longValue = ((long)System.Convert.ChangeType(enumNew, typeof(long)) & 0x7) << 29;

            uint brushTileData = m_randTileList.index >= 0 ? m_brush.RandomTileList[m_randTileList.index].tileData : Tileset.k_TileData_Empty;

            brushTileData = BrushTileGridControl.DoTileDataPropertiesLayout(brushTileData, m_brush.Tileset, false);
            if (m_randTileList.index >= 0)
            {
                m_brush.RandomTileList[m_randTileList.index].tileData = brushTileData;
            }
            EditorGUILayout.Space();
            EditorGUILayout.HelpBox("Activate this to use animated brushes as random tiles", MessageType.Info);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("RemoveBrushIdAfterRefresh"));

            // Draw List
            m_randTileList.elementHeight = visualTileSize.y + 35f;
            m_randTileList.DoLayoutList();
            if (Event.current.type == EventType.Repaint)
            {
                m_randTileListHasFocus = m_randTileList.HasKeyboardControl();
            }

            TileSelection tileSelection = ((TilesetBrush)target).Tileset.TileSelection;

            if (tileSelection != null)
            {
                if (GUILayout.Button("Add tiles from tile selection"))
                {
                    m_brush.RandomTileList.AddRange(tileSelection.selectionData.Select(x => new RandomBrush.RandomTileData()
                    {
                        tileData = x, probabilityFactor = 1f
                    }));
                }
            }

            EditorGUILayout.HelpBox("Select a tile from list and then select a tile from tile selection window.", MessageType.Info);
            EditorGUILayout.HelpBox("Add and Remove tiles with '+' and '-' buttons.", MessageType.Info);

            Repaint();
            serializedObject.ApplyModifiedProperties();
            if (GUI.changed)
            {
                m_brush.InvalidateSortedList();
                EditorUtility.SetDirty(target);
            }
        }
        void OnGUI()
        {
            m_serializedObject.Update();
            m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos, GUIStyle.none, GUI.skin.verticalScrollbar);
            {
                EditorGUILayout.Space();
                EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                {
                    EditorGUILayout.LabelField("Atlas Texture:", EditorStyles.boldLabel);
                    EditorGUI.indentLevel += 1;
                    m_tileset              = (Tileset)EditorGUILayout.ObjectField("Tileset (optional)", m_tileset, typeof(Tileset), false);
                    if (!m_tileset)
                    {
                        if (GUILayout.Button("Create Tileset"))
                        {
                            m_tileset = TilesetEditor.CreateTileset();
                        }
                    }
                    // Read Data From Tileset
                    if (m_tileset)
                    {
                        m_atlasTexture = m_tileset.AtlasTexture;
                    }
                    m_atlasTexture         = (Texture2D)EditorGUILayout.ObjectField("Atlas texture", m_atlasTexture, typeof(Texture2D), false);
                    EditorGUI.indentLevel -= 1;
                }
                EditorGUILayout.EndHorizontal();

                //GUI.enabled = m_atlasTexture != null;
                EditorGUILayout.Space();
                EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                {
                    EditorGUILayout.LabelField("Atlas Settings:", EditorStyles.boldLabel);
                    EditorGUI.indentLevel += 1;
                    EditorGUILayout.PropertyField(m_serializedObject.FindProperty("m_tileTextures"), true);
                    if (GUILayout.Button("Sort by Name"))
                    {
                        m_tileTextures = m_tileTextures.Where(x => x != null).OrderBy(x => x.name).ToArray();
                    }
                    m_padding        = EditorGUILayout.IntField("Padding", m_padding);
                    m_maxTextureSize = (eMaxTextureSize)EditorGUILayout.EnumPopup("Max. Texture Size", m_maxTextureSize);
                    if (m_tileset && GUILayout.Button("Create Atlas & Update Tileset") || !m_tileset && GUILayout.Button("Create Atlas"))
                    {
                        if (!m_atlasTexture)
                        {
                            m_atlasTexture = new Texture2D((int)m_maxTextureSize, (int)m_maxTextureSize, TextureFormat.ARGB32, false);
                        }
                        foreach (Texture2D tileTexture in m_tileTextures)
                        {
                            TilemapUtilsEditor.MakeTextureReadable(tileTexture);
                        }
                        TilemapUtilsEditor.MakeTextureReadable(m_atlasTexture);
                        Rect[] tileRects      = m_atlasTexture.PackTextures(m_tileTextures, m_padding, (int)m_maxTextureSize, false);
                        string atlasAssetPath = AssetDatabase.GetAssetPath(m_atlasTexture);
                        if (string.IsNullOrEmpty(atlasAssetPath))
                        {
                            atlasAssetPath = EditorUtility.SaveFilePanelInProject("Save atlas texture", m_tileset.name + "Atlas", "png", "Save the atlas texture");
                        }
                        if (!string.IsNullOrEmpty(atlasAssetPath))
                        {
                            File.WriteAllBytes(atlasAssetPath, m_atlasTexture.EncodeToPNG());
                            AssetDatabase.ImportAsset(atlasAssetPath, ImportAssetOptions.ForceSynchronousImport);
                            TilesetEditor.OptimizeTextureImportSettings(m_atlasTexture);
                            AssetDatabase.Refresh();
                            m_atlasTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(atlasAssetPath);
                            if (m_tileset && tileRects.Length > 0)
                            {
                                m_tileset.AtlasTexture = m_atlasTexture;
                                m_tileset.TilePxSize   = new Vector2(tileRects[0].size.x * m_atlasTexture.width, tileRects[0].size.y * m_atlasTexture.height);
                                int idx;
                                for (idx = 0; idx < tileRects.Length; ++idx)
                                {
                                    Rect uv = tileRects[idx];
                                    if (idx < m_tileset.Tiles.Count)
                                    {
                                        m_tileset.Tiles[idx].uv = uv;
                                    }
                                    else
                                    {
                                        m_tileset.Tiles.Add(new Tile()
                                        {
                                            uv = uv
                                        });
                                    }
                                }
                                m_tileset.Tiles.RemoveRange(idx, m_tileset.Tiles.Count - idx);
                            }
                        }
                    }
                    EditorGUI.indentLevel -= 1;
                }
                EditorGUILayout.EndVertical();
                const string sHelpInfo = "1. Create a tileset or drag a tileset into the Tileset field.\n" +
                                         "2. Drag the tile textures into the Tile Textures field.\n" +
                                         "3. Optionally sort by name the textures, to make sure the tile order will be the same if later you add new tile textures.\n" +
                                         "4. Press Create Atlas and Update Tileset";
                EditorGUILayout.HelpBox(sHelpInfo, MessageType.Info);

                GUI.enabled = true;
            }
            EditorGUILayout.EndScrollView();

            if (GUI.changed)
            {
                if (m_tileset)
                {
                    EditorUtility.SetDirty(m_tileset);
                }
                m_serializedObject.ApplyModifiedProperties();
            }
        }
示例#13
0
        private void DisplayParameters()
        {
            Event         e             = Event.current;
            TileSelection tileSelection = Tileset.TileSelection;

            if (tileSelection != null)
            {
                EditorGUILayout.LabelField("Multi-tile editing. Only merge allowed.", EditorStyles.boldLabel);
                EditorGUILayout.Space();
                EditorGUILayout.HelpBox("This will combine all the parameters found in the tile selection so if a parameter is missing in a tile, it will add the parameter, but if it has it already, it won't change the value.", MessageType.Info);
                if (GUILayout.Button("Merge Tile Parameters"))
                {
                    MergeTileParameters(tileSelection.selectionData);
                }
                EditorGUILayout.Space();
            }
            else
            {
                UnityEngine.Object prevOwner = m_parameterListOwner;
                if (Tileset.SelectedBrushId != Tileset.k_BrushId_Default)
                {
                    m_parameterListOwner = Tileset.FindBrush(Tileset.SelectedBrushId);
                }
                else
                {
                    m_parameterListOwner = Tileset;
                }

                if (m_parameterListOwner != null)
                {
                    if (prevOwner != m_parameterListOwner || Tileset.SelectedTileId != m_prevSelectedTileId || m_tileParameterList == null)
                    {
                        m_prevSelectedTileId = Tileset.SelectedTileId;
                        m_tileParameterList  = CreateParameterReorderableList(m_parameterListOwner is Tileset ?
                                                                              ((Tileset)m_parameterListOwner).SelectedTile.paramContainer :
                                                                              ((TilesetBrush)m_parameterListOwner).Params);
                        m_tileParameterList.onChangedCallback += (ReorderableList list) =>
                        {
                            EditorUtility.SetDirty(m_parameterListOwner);
                        };
                    }

                    GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y));
                    uint tilePreviewData = m_parameterListOwner is Tileset ?
                                           (uint)(((Tileset)m_parameterListOwner).SelectedTileId & Tileset.k_TileDataMask_TileId)
                        :
                                           ((TilesetBrush)m_parameterListOwner).GetAnimTileData();
                    Rect customUV = m_parameterListOwner is Tileset ? default(Rect) : ((TilesetBrush)m_parameterListOwner).GetAnimUV();
                    GUI.color = Tileset.BackgroundColor;
                    GUI.DrawTexture(GUILayoutUtility.GetLastRect(), EditorGUIUtility.whiteTexture);
                    GUI.color = Color.white;
                    TilesetEditor.DoGUIDrawTileFromTileData(GUILayoutUtility.GetLastRect(), tilePreviewData, Tileset, customUV);

                    m_tileParamScrollViewPos = EditorGUILayout.BeginScrollView(m_tileParamScrollViewPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
                    EditorGUI.BeginChangeCheck();
                    m_tileParameterList.DoLayoutList();
                    Rect rList = GUILayoutUtility.GetLastRect();
                    if (e.type == EventType.MouseDown && !rList.Contains(e.mousePosition))
                    {
                        m_tileParameterList.ReleaseKeyboardFocus();
                        m_tileParameterList.index = -1;
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        EditorUtility.SetDirty(m_parameterListOwner);
                    }
                    EditorGUILayout.EndScrollView();
                }
            }
        }
示例#14
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);
            }
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (m_prevTileset != m_brush.Tileset)
            {
                if (m_prevTileset)
                {
                    m_prevTileset.OnTileSelected -= OnTileSelected;
                }
                OnDisable();
                OnEnable();
            }
            m_prevTileset = m_brush.Tileset;

            base.OnInspectorGUI();
            if (!m_brush.Tileset)
            {
                return;
            }

            Vector2 visualTileSize = m_brush.Tileset.VisualTileSize;

            EditorGUILayout.PropertyField(serializedObject.FindProperty("AnimFPS"));

            TileSelection tileSelection = ((TilesetBrush)target).Tileset.TileSelection;

            if (tileSelection != null)
            {
                if (GUILayout.Button("Add tile selection as animation frames"))
                {
                    ((AnimBrush)target).AnimFrames.AddRange(tileSelection.selectionData.Select(x => new AnimBrush.TileAnimFrame()
                    {
                        tileId = x
                    }));
                }
            }

            EditorGUILayout.Space();

            // Draw animation
            GUILayoutUtility.GetRect(1f, 1f, GUILayout.Width(visualTileSize.x), GUILayout.Height(visualTileSize.y));
            Rect rAnimFrame = GUILayoutUtility.GetLastRect();
            uint tileData   = m_brush.GetAnimTileData();

            rAnimFrame.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, rAnimFrame.center.y);
            GUI.Box(new Rect(rAnimFrame.position - Vector2.one, rAnimFrame.size + 2 * Vector2.one), "");
            TilesetEditor.DoGUIDrawTileFromTileData(rAnimFrame, tileData, m_brush.Tileset, m_brush.GetAnimUV());

            EditorGUILayout.Space();
            uint brushTileData = m_frameList.index >= 0 ? m_brush.AnimFrames[m_frameList.index].tileId : Tileset.k_TileData_Empty;

            brushTileData = BrushTileGridControl.DoTileDataPropertiesLayout(brushTileData, m_brush.Tileset, false);
            if (m_frameList.index >= 0)
            {
                m_brush.AnimFrames[m_frameList.index].tileId = brushTileData;
            }
            EditorGUILayout.Space();

            // Draw Frames List
            m_frameList.elementHeight = visualTileSize.y + 10f;
            m_frameList.DoLayoutList();

            EditorGUILayout.HelpBox("Select a frame from list and then select a tile from tile selection window.", MessageType.Info);
            EditorGUILayout.HelpBox("Add and Remove tiles with '+' and '-' buttons.", MessageType.Info);

            Repaint();
            serializedObject.ApplyModifiedProperties();
            if (GUI.changed)
            {
                EditorUtility.SetDirty(target);
            }
        }
示例#16
0
        public void Display()
        {
            AssetPreview.SetPreviewTextureCacheSize(256); //FIX clickeing issues when displaying multiple prefab previews (when a tile has a prefab attached
            Event e = Event.current;

            m_dblClick.Update();

            //FIX: when a tileset is changed, the layout change and during some frames, the BeginScrollView could return wrong values
            // This will make sure the scroll position is updated after mouse is over the control
            if (e.isMouse || e.type == EventType.ScrollWheel)
            {
                m_updateScrollPos = true;
            }

            // 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;
            }

            m_sharedData = GetSharedTilesetData(Tileset);

            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);

            // Create TileView ReorderableList
            if (m_sharedData.tileViewList == null || m_sharedData.tileViewList.list != Tileset.TileViews)
            {
                m_sharedData.tileViewList = TilesetEditor.CreateTileViewReorderableList(Tileset);
                m_sharedData.tileViewList.onSelectCallback += (ReorderableList list) =>
                {
                    /* NOTE: this will select the tileview for the painting brush. Commented just in case.
                     * if(list.index >= 0)
                     * {
                     *  TileSelection tileSelection = Tileset.TileViews[list.index].tileSelection.Clone();
                     *  tileSelection.FlipVertical();
                     *  Tileset.TileSelection = tileSelection;
                     * }
                     * else*/
                    RemoveTileSelection();
                };
                m_sharedData.tileViewList.onRemoveCallback += (ReorderableList list) =>
                {
                    RemoveTileSelection();
                };
            }

            // Draw TileView ReorderableList
            {
                GUI.color = Color.cyan;
                GUILayout.BeginVertical(Styles.Instance.customBox);
                m_sharedData.tileViewList.index = Mathf.Clamp(m_sharedData.tileViewList.index, -1, Tileset.TileViews.Count - 1);
                m_sharedData.tileViewList.DoLayoutList();
                Rect rList = GUILayoutUtility.GetLastRect();
                if (e.isMouse && !rList.Contains(e.mousePosition))
                {
                    m_sharedData.tileViewList.ReleaseKeyboardFocus();
                }
                GUILayout.EndVertical();
                GUI.color = Color.white;
            }
            TileView tileView = m_sharedData.tileViewList != null && m_sharedData.tileViewList.index >= 0 ? Tileset.TileViews[m_sharedData.tileViewList.index] : null;

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


            List <string> viewNameList = new List <string>()
            {
                "(All)"
            };

            viewNameList.AddRange(Tileset.TileViews.Select(x => x.name));
            string[] tileViewNames  = viewNameList.ToArray();
            int[]    tileViewValues = Enumerable.Range(-1, Tileset.TileViews.Count + 1).ToArray();
            EditorGUI.BeginChangeCheck();
            m_sharedData.tileViewList.index = EditorGUILayout.IntPopup("Tileset View", m_sharedData.tileViewList.index, tileViewNames, tileViewValues);
            if (EditorGUI.EndChangeCheck())
            {
                RemoveTileSelection();
            }

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

            // Draw Zoom Selector
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label(EditorGUIUtility.FindTexture("ViewToolZoom"), GUILayout.Width(35f));
            float visualTileZoom = EditorGUILayout.Slider(Tileset.VisualTileSize.x / Tileset.TilePxSize.x, 0.25f, 4f);

            Tileset.VisualTileSize = visualTileZoom * Tileset.TilePxSize;
            if (GUILayout.Button("Reset", GUILayout.Width(50f)))
            {
                Tileset.VisualTileSize = new Vector2(32f * Tileset.TilePxSize.x / Tileset.TilePxSize.y, 32f);
            }
            EditorGUILayout.EndHorizontal();
            //---

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

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

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

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

            m_sharedData.tileViewRowLength = tileView != null ? tileView.tileSelection.rowLength : Tileset.TileRowLength;

            //float minTileScrollHeight = (Tileset.VisualTileSize.y + visualTilePadding) * 6f;// NOTE: GUILayout.MinHeight is not working with BeginScrollView
            Vector2 tilesScrollPos = EditorGUILayout.BeginScrollView(m_sharedData.tilesScrollPos, Styles.Instance.scrollStyle /*, GUILayout.MinHeight(minTileScrollHeight)*/);

            if (m_updateScrollPos)
            {
                m_sharedData.tilesScrollPos = tilesScrollPos;
            }
            {
                // Scroll Moving Drag
                if (e.type == EventType.MouseDrag && (e.button == 1 || e.button == 2))
                {
                    m_sharedData.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   = tileView != null ? tileView.tileSelection.rowLength : Tileset.Width;
                    int         tileViewHeight  = tileView != null ? ((tileView.tileSelection.selectionData.Count - 1) / tileView.tileSelection.rowLength) + 1 : Tileset.Height;
                    int         totalCount      = ((((tileViewWidth - 1) / m_sharedData.tileViewRowLength) + 1) * m_sharedData.tileViewRowLength) * tileViewHeight;
                    for (int i = 0; i < totalCount; ++i)
                    {
                        int  tileId   = GetTileIdFromIdx(i, m_sharedData.tileViewRowLength, tileViewWidth, tileViewHeight);
                        uint tileData = (uint)tileId;
                        if (tileView != null && tileId != Tileset.k_TileId_Empty)
                        {
                            tileData = tileView.tileSelection.selectionData[tileId];
                            tileId   = (int)(tileData & Tileset.k_TileDataMask_TileId);
                        }
                        Tile tile = Tileset.GetTile(tileId);
                        visibleTileList.Add(tileData);

                        int  tx          = m_visibleTileCount % m_sharedData.tileViewRowLength;
                        int  ty          = m_visibleTileCount / m_sharedData.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_sharedData.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_sharedData.pointedTileIdxRect = new KeyValuePair <int, Rect>(m_visibleTileCount, rTileRect);
                                }
                                else if (e.type == EventType.MouseDown && e.button == 0)
                                {
                                    m_sharedData.startDragTileIdxRect = m_sharedData.pointedTileIdxRect = m_sharedData.endDragTileIdxRect = new KeyValuePair <int, Rect>(m_visibleTileCount, rTileRect);
                                }
                                else if (e.type == EventType.MouseUp && e.button == 0)
                                {
                                    m_sharedData.endDragTileIdxRect = new KeyValuePair <int, Rect>(m_visibleTileCount, rTileRect);
                                    DoSetTileSelection();
                                }
                            }

                            if ((isLeftMouseReleased || isRightMouseReleased) && isInsideTileScrollArea && rVisualTile.Contains(e.mousePosition) &&
                                (m_sharedData.startDragTileIdxRect.Key == m_sharedData.endDragTileIdxRect.Key) && // and there is not dragging selection
                                m_rTileScrollSize.Contains(e.mousePosition - m_sharedData.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_sharedData.startDragTileIdxRect.Key != m_sharedData.pointedTileIdxRect.Key /*&& m_startDragTileIdxRect.Key == m_endDragTileIdxRect.Key*/)
                    {
                        Rect rSelection = new Rect(m_sharedData.startDragTileIdxRect.Value.center, m_sharedData.pointedTileIdxRect.Value.center - m_sharedData.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_sharedData.startDragTileIdxRect.Value.width / 2;
                        rSelection.xMax += m_sharedData.startDragTileIdxRect.Value.width / 2;
                        rSelection.yMin -= m_sharedData.startDragTileIdxRect.Value.height / 2;
                        rSelection.yMax += m_sharedData.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();
            Tileset.BrushTypeMask = EditorGUILayout.MaskField("Brush Mask", Tileset.BrushTypeMask, Tileset.GetBrushTypeArray());

            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    refreshBrushes   = false;
                Vector2 brushesScrollPos = EditorGUILayout.BeginScrollView(m_sharedData.brushesScrollPos, Styles.Instance.scrollStyle);
                if (m_updateScrollPos)
                {
                    m_sharedData.brushesScrollPos = brushesScrollPos;
                }
                {
                    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, idx = 0; i < Tileset.Brushes.Count; ++i, ++idx)
                        {
                            Tileset.BrushContainer brushCont = Tileset.Brushes[i];
                            if (brushCont.BrushAsset == null || brushCont.BrushAsset.Tileset != Tileset)
                            {
                                refreshBrushes = true;
                                continue;
                            }
                            if (!brushCont.BrushAsset.ShowInPalette || !Tileset.IsBrushVisibleByTypeMask(brushCont.BrushAsset))
                            {
                                --idx;
                                continue;
                            }

                            int  tx          = idx % tileRowLength;
                            int  ty          = idx / 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 (refreshBrushes)
                    {
                        Tileset.RemoveInvalidBrushes();
                        Tileset.UpdateBrushTypeArray();
                    }
                }
                EditorGUILayout.EndScrollView();
                if (e.type == EventType.Repaint)
                {
                    m_rBrushScrollArea = GUILayoutUtility.GetLastRect();
                }
            }
            EditorGUILayout.EndVertical();

            if (GUILayout.Button("Import all brushes found in the project"))
            {
                TilesetEditor.AddAllBrushesFoundInTheProject(Tileset);
                EditorUtility.SetDirty(Tileset);
            }
        }
        private bool m_displayAutocompleteBtn = false; // fix gui warning when button appears
        public void Display(Object target, uint[] aTileData, int[] tileIdxMap, int gridWidth, int gridHeight, Vector2 visualTileSize, int[] symbolIdxMap)
        {
            GUI.changed = m_hasChanged;
            m_hasChanged = false;
            m_target = target;
            m_aBrushTileData = aTileData;
            Event e = Event.current;
            bool isRightMouseReleased = e.type == EventType.MouseUp && e.button == 0;
            if (isRightMouseReleased && !m_tileSelectionRect.Contains(e.mousePosition))
            {
                m_selectedTileIdx = -1;
            }

            GUILayout.BeginHorizontal();

            // Draw Autotile Combination Control
            GUI.backgroundColor = Tileset.BackgroundColor;
            GUILayout.BeginScrollView(Vector2.zero, (GUIStyle)"Button", GUILayout.Width(visualTileSize.x * gridWidth), GUILayout.Height(visualTileSize.y * gridHeight + 1f));
            GUI.backgroundColor = Color.white;
            for (int i = 0; i < gridWidth * gridHeight; ++i)
            {
                int gx = i % gridWidth;
                int gy = i / gridHeight;
                int tileIdx = tileIdxMap[i];
                Rect rVisualTile = new Rect(gx * visualTileSize.x, gy * visualTileSize.y, visualTileSize.x, visualTileSize.y);

                int tileId = (int)(m_aBrushTileData[tileIdx] & Tileset.k_TileDataMask_TileId);
                if (tileId != Tileset.k_TileId_Empty)
                {
                    //Rect tileUV = Tileset.Tiles[tileId].uv;
                    //GUI.DrawTextureWithTexCoords(rVisualTile, Tileset.AtlasTexture, tileUV, true);
                    TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, m_aBrushTileData[tileIdx], Tileset);
                }
                else if (symbolIdxMap != null)
                {
                    GUI.DrawTexture(rVisualTile, GetTileSymbolTexture((byte)symbolIdxMap[i]), ScaleMode.ScaleToFit, true);
                }

                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 ? new Color(1f, 1f, 0f, 1f) : bgColor);

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

            uint brushTileData = m_selectedTileIdx >= 0 ? m_aBrushTileData[m_selectedTileIdx] : Tileset.k_TileData_Empty;
            brushTileData = DoTileDataPropertiesLayout(brushTileData, Tileset);
            if (m_selectedTileIdx >= 0)
            {
                m_aBrushTileData[m_selectedTileIdx] = brushTileData;
            }

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

            bool hasEmptyTiles = ArrayUtility.Contains<uint>(m_aBrushTileData, Tileset.k_TileData_Empty);
            m_displayAutocompleteBtn = e.type == EventType.Layout ? !hasEmptyTiles && m_tileIdOff != 0 : m_displayAutocompleteBtn;
            if (m_displayAutocompleteBtn && GUILayout.Button("Autocomplete relative to last change"))
            {
                Undo.RecordObject(m_target, "MultipleTileChanged");
                for (int i = 0; i < tileIdxMap.Length; ++i)
                {
                    int tileIdx = tileIdxMap[i];
                    if (tileIdx != m_tileIdOffSkipIdx)
                    {
                        int brushTileId = (int)(m_aBrushTileData[tileIdx] & Tileset.k_TileDataMask_TileId);
                        brushTileId += m_tileIdOff;
                        if (brushTileId < 0 || brushTileId >= m_tileset.Tiles.Count)
                        {
                            m_aBrushTileData[tileIdx] = Tileset.k_TileData_Empty;
                        }
                        else
                        {
                            m_aBrushTileData[tileIdx] &= ~Tileset.k_TileDataMask_TileId;
                            m_aBrushTileData[tileIdx] |= (uint)(brushTileId & Tileset.k_TileDataMask_TileId);
                        }
                    }
                }
                m_tileIdOff = 0;
                EditorUtility.SetDirty(m_target);
            }

            if (ShowHelpBox)
            {
                EditorGUILayout.HelpBox("Select  a tile from the grid, then select a tile from Tile Selection Window to change the tile.", MessageType.Info);
            }
        }
        public override void OnEnable()
        {
            base.OnEnable();
            m_brush = (AnimBrush)target;
            if (m_brush.Tileset != null)
            {
                m_brush.Tileset.OnTileSelected += OnTileSelected;
            }

            m_frameList = new ReorderableList(serializedObject, serializedObject.FindProperty("AnimFrames"), true, true, true, true);
            m_frameList.drawHeaderCallback += (Rect rect) =>
            {
                EditorGUI.LabelField(rect, "Anim Frames", EditorStyles.boldLabel);
            };
            m_frameList.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.AnimFrames[index].tileId;
                int  tileId   = (int)(tileData & Tileset.k_TileDataMask_TileId);
                if (tileId != Tileset.k_TileId_Empty)
                {
                    Rect tileUV = m_brush.Tileset.Tiles[tileId].uv;
                    tileUV.position += m_brush.AnimFrames[index].UVOffset;
                    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 + 20; rTileId.width -= rTile.width + 20;
                rTileId.height = rect.height / 2;
                GUI.Label(rTileId, "Id(" + tileId + ")");
                Vector2 uvOffset   = m_brush.AnimFrames[index].UVOffset;
                Vector2 UvPxOffset = new Vector2(uvOffset.x / m_brush.Tileset.AtlasTexture.texelSize.x, uvOffset.y / m_brush.Tileset.AtlasTexture.texelSize.y);
                rTileId.y += rTileId.height;
                GUI.Label(rTileId, "UVOffset(" + UvPxOffset.x + "," + UvPxOffset.y + ")");

                int   btnIdx  = 0;
                float btnSize = rect.height / 2;
                for (int gy = 0; gy < 2; ++gy)
                {
                    for (int gx = 0; gx < 3; ++gx, ++btnIdx)
                    {
                        Rect btnRect = new Rect(rect.x + rect.width - (gx + 1) * btnSize, rect.y + gy * rect.height / 2f, btnSize, btnSize);
                        switch (btnIdx)
                        {
                        case 0: if (GUI.Button(btnRect, "R"))
                            {
                                uvOffset = Vector2.zero;
                            }
                            break;

                        case 1: if (GUI.Button(btnRect, "▲"))
                            {
                                uvOffset.y -= m_brush.Tileset.AtlasTexture.texelSize.y;
                            }
                            break;

                        case 3: if (GUI.Button(btnRect, "▶"))
                            {
                                uvOffset.x -= m_brush.Tileset.AtlasTexture.texelSize.x;
                            }
                            break;

                        case 4: if (GUI.Button(btnRect, "▼"))
                            {
                                uvOffset.y += m_brush.Tileset.AtlasTexture.texelSize.y;
                            }
                            break;

                        case 5: if (GUI.Button(btnRect, "◀"))
                            {
                                uvOffset.x += m_brush.Tileset.AtlasTexture.texelSize.x;
                            }
                            break;
                        }
                    }
                }
                m_brush.AnimFrames[index].UVOffset = uvOffset;
            };
            m_frameList.onSelectCallback += (ReorderableList list) =>
            {
                TileSelectionWindow.Show(m_brush.Tileset);
                TileSelectionWindow.Instance.Ping();
            };
        }