Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditorTools / MapEditorToolsPanel.cs
@小李xl 小李xl on 17 Jul 24 KB 地牢编辑器移植完成
using System;
using System.Collections.Generic;
using Config;
using Godot;
using UI.MapEditor;

namespace UI.MapEditorTools;

public partial class MapEditorToolsPanel : MapEditorTools
{
    public class CustonObjectData
    {
        public RoomObjectInfo RoomObjectInfo;
        public ObjectTemplate Node;
        public RoomLayerEnum Layer;

        public CustonObjectData(RoomObjectInfo roomObjectInfo, ObjectTemplate node, RoomLayerEnum layer)
        {
            RoomObjectInfo = roomObjectInfo;
            Node = node;
            Layer = layer;
        }
    }
    
    /// <summary>
    /// 鼠标悬停区域
    /// </summary>
    public DoorHoverArea ActiveHoverArea { get; private set; }
    
    /// <summary>
    /// 鼠标选中的标记对象
    /// </summary>
    public MarkTool ActiveMark { get; private set; }

    /// <summary>
    /// 所属编辑器Tile对象
    /// </summary>
    public EditorTileMap EditorMap { get; private set; }
    
    /// <summary>
    /// 所属编辑器面板对象
    /// </summary>
    public MapEditorPanel MapEditorPanel { get; private set; }
    
    /// <summary>
    /// 是否打开弹窗
    /// </summary>
    public bool IsOpenPopUps { get; private set; }

    /// <summary>
    /// 当前选中的工具
    /// </summary>
    public EditorToolEnum ActiveToolType => _toolGrid != null && _toolGrid.SelectData != null ? _toolGrid.SelectData.EditorToolType : EditorToolEnum.None;
    
    /// <summary>
    /// 自定义对象普通层根节点
    /// </summary>
    public Node2D CustomNormalRoot { get; private set; }
    /// <summary>
    /// 自定义对象YSort层根节点
    /// </summary>
    public Node2D CustomYSortRoot { get; private set; }
    
    /// <summary>
    /// 自定义物体映射字典, 负责存储所有自定义物体
    /// </summary>
    public Dictionary<RoomObjectInfo, CustonObjectData> CustomObjecMapping { get; } = new Dictionary<RoomObjectInfo, CustonObjectData>();
    
    private List<DoorToolTemplate> _doorTools = new List<DoorToolTemplate>();
    private Dictionary<EditorToolEnum, EditorToolBase> _toolMapping = new Dictionary<EditorToolEnum, EditorToolBase>();
    private UiGrid<ToolButton, EditorToolBase> _toolGrid;
    //当前预设的所有标记
    private Dictionary<MarkInfo, MarkTemplate> _currMarkToolsMap = new Dictionary<MarkInfo, MarkTemplate>();
    
    //丢失的物体id
    private HashSet<string> _missingSet = new HashSet<string>();
    
    private Color _tempColor1, _tempColor2;

    public override void OnCreateUi()
    {
        MapEditorPanel = (MapEditorPanel)ParentUi;
        EditorMap = MapEditorPanel.S_TileMap.Instance;
        
        S_N_HoverArea.Instance.Init(this, DoorDirection.N);
        S_S_HoverArea.Instance.Init(this, DoorDirection.S);
        S_W_HoverArea.Instance.Init(this, DoorDirection.W);
        S_E_HoverArea.Instance.Init(this, DoorDirection.E);
        S_ToolRoot.Instance.RemoveChild(S_DoorToolTemplate.Instance);
        S_MarkTemplate.Instance.Visible = false;

        S_ObjectTemplate.Instance.Visible = false;

        //工具栏
        AddToolMapping(new EditorMove(EditorMap));
        AddToolMapping(new EditorTilePen(EditorMap));
        AddToolMapping(new EditorTileAreaPen(EditorMap));
        AddToolMapping(new EditorMarkTool(EditorMap));
        AddToolMapping(new EditorFocus(EditorMap));
        AddToolMapping(new EditorObjectPen(EditorMap));
        AddToolMapping(new EditorObjectTool(EditorMap));
        
        //工具栏网格
        _toolGrid = new UiGrid<ToolButton, EditorToolBase>(S_ToolButton, typeof(ToolButtonCell));
        _toolGrid.SetColumns(15);

        CustomNormalRoot = new Node2D();
        CustomNormalRoot.ZIndex = -1;
        EditorMap.AddChild(CustomNormalRoot);
        CustomYSortRoot = new Node2D();
        EditorMap.AddChild(CustomYSortRoot);

        //标记相关
        AddEventListener(EventEnum.OnSelectWave, OnSelectWaveTool);
        AddEventListener(EventEnum.OnCreateMark, OnCreateMarkTool);
        AddEventListener(EventEnum.OnSelectMark, OnSelectMarkTool);
        AddEventListener(EventEnum.OnDeleteMark, OnDeleteMarkTool);
        AddEventListener(EventEnum.OnSetMarkVisible, OnSetMarkVisible);
        AddEventListener(EventEnum.OnEditMark, OnEditMarkTool);
        AddEventListener(EventEnum.OnSelectPreinstall, RefreshMark);
        
        //自定义物体相关
        AddEventListener(EventEnum.OnPutObject, OnPutObject);
        AddEventListener(EventEnum.OnRemoveObject, OnRemoveObject);
        AddEventListener(EventEnum.OnSelectObject, OnSelectObject);
        
        //保存预览图相关
        AddEventListener(EventEnum.OnSavePreviewImageBegin, OnSavePreviewImageBegin);
        AddEventListener(EventEnum.OnSavePreviewImageFinish, OnSavePreviewImageFinish);
    }

    public override void OnDestroyUi()
    {
        S_DoorToolTemplate.Instance.QueueFree();
        _toolGrid.Destroy();
    }

    /// <summary>
    /// 初始化面板数据
    /// </summary>
    public void InitCustomObjectData()
    {
        var objectPanel = MapEditorPanel.S_MapEditorObject.Instance;
        foreach (var objectInfo in objectPanel.NormalLayerObjects)
        {
            OnCreateObject(objectInfo, RoomLayerEnum.NormalLayer);
        }

        foreach (var objectInfo in objectPanel.YSortLayerObjects)
        {
            OnCreateObject(objectInfo, RoomLayerEnum.YSortLayer);
        }

        if (_missingSet.Count > 0)
        {
            var str = "";
            foreach (var item in _missingSet)
            {
                if (str.Length > 0)
                {
                    str += ",";
                }
                str += item;
            }
            EditorWindowManager.ShowTips("警告", $"发现存在丢失的自定义物体,id为:{str}");
        }
    }

    public override void Process(float delta)
    {
        S_HoverPreviewRoot.Instance.Visible = ActiveHoverArea != null && !DoorHoverArea.IsDrag;
        if (EditorMap.ActiveToolType == EditorToolEnum.MarkTool)
        {
            S_ToolRoot.Instance.Modulate = new Color(1, 1, 1, 1);
        }
        else
        {
            S_ToolRoot.Instance.Modulate = new Color(1, 1, 1, 0.4f);
        }

        IsOpenPopUps = UiManager.GetUiInstanceCount(UiManager.UiNames.EditorWindow) > 0;
    }

    private void AddToolMapping(EditorToolBase toolBase)
    {
        _toolMapping.Add(toolBase.EditorToolType, toolBase);
    }

    /// <summary>
    /// 设置当前选择的工具
    /// </summary>
    public void SetActiviteTool(EditorToolEnum toolEnum)
    {
        if (IsDestroyed)
        {
            return;
        }

        if (_toolGrid == null)
        {
            this.CallDelay(0, () => { _SetActiviteTool(toolEnum); });
        }
        else
        {
            _SetActiviteTool(toolEnum);
        }
    }
    
    private void _SetActiviteTool(EditorToolEnum toolEnum)
    {
        var uiCell = _toolGrid.Find(tool => tool.Data.EditorToolType == toolEnum);
        if (uiCell != null)
        {
            uiCell.Click();
        }
    }
    
    /// <summary>
    /// 设置工具栏按钮
    /// </summary>
    public void SetToolButton(params EditorToolEnum[] toolEnum)
    {
        if (IsDestroyed)
        {
            return;
        }

        if (_toolGrid == null)
        {
            this.CallDelay(0, () => { _SetToolButton(toolEnum); });
        }
        else
        {
            _SetToolButton(toolEnum);
        }
    }

    public void _SetToolButton(params EditorToolEnum[] toolEnum)
    {
        _toolGrid.RemoveAll();
        foreach (var editorToolEnum in toolEnum)
        {
            if (_toolMapping.TryGetValue(editorToolEnum, out var tool))
            {
                _toolGrid.Add(tool);
            }
        }
    }


    //放置自定义物体
    private void OnPutObject(object obj)
    {
        var info = (RoomObjectInfo)obj;
        var layerType = MapEditorPanel.S_MapEditorObject.Instance.GetCurrentObjectLayerEnum();
        OnCreateObject(info, layerType);
    }

    /// <summary>
    /// 移除物体
    /// </summary>
    private void OnRemoveObject(object obj)
    {
        var info = (RoomObjectInfo)obj;
        if (CustomObjecMapping.TryGetValue(info, out var data))
        {
            CustomObjecMapping.Remove(info);
            data.Node.QueueFree();
        }
    }

    /// <summary>
    /// 选择物体
    /// </summary>
    private void OnSelectObject(object obj)
    {
        SetActiviteTool(EditorToolEnum.ObjectTool);
    }
    
    //创建自定义物体
    private void OnCreateObject(RoomObjectInfo info, RoomLayerEnum layerType)
    {
        if (ExcelConfig.EditorObject_Map.TryGetValue(info.Id, out var config))
        {
            var node = ResourceManager.LoadEditorObject(config);
            
            var template = S_ObjectTemplate.Clone();
            template.Instance.Visible = true;
            template.Instance.Position = new Vector2(info.X, info.Y);
            template.Instance.Init(info, node);
            template.Instance.Monitorable = (int)layerType == MapEditorPanel.S_MapEditorObject.Instance.S_LayerOption.Instance.Selected;
            
            switch (layerType)
            {
                case RoomLayerEnum.NormalLayer:
                    CustomNormalRoot.AddChild(template.Instance);
                    CustomObjecMapping.Add(info, new CustonObjectData(info, template, RoomLayerEnum.NormalLayer));
                    break;
                case RoomLayerEnum.YSortLayer:
                    CustomYSortRoot.AddChild(template.Instance);
                    CustomObjecMapping.Add(info, new CustonObjectData(info, template, RoomLayerEnum.YSortLayer));
                    break;
            }
        }
        else
        {
            Debug.LogError($"创建CustomObject没有找到物体配置: {info.Id}!");
            _missingSet.Add(info.Id);
        }
    }

    //刷新标记
    private void RefreshMark(object arg)
    {
        ActiveMark = null;
        //删除之前的数据
        foreach (var keyValuePair in _currMarkToolsMap)
        {
            keyValuePair.Value.QueueFree();
        }
        _currMarkToolsMap.Clear();
        //添加新的数据
        var selectPreinstall = EditorTileMapManager.SelectPreinstall;
        if (selectPreinstall != null)
        {
            foreach (var markInfos in selectPreinstall.WaveList)
            {
                foreach (var markInfo in markInfos)
                {
                    CreateMarkTool(markInfo);
                }
            }
        }
    }

    //选中波数
    private void OnSelectWaveTool(object arg)
    {
        //选中编辑工具
        SetActiviteTool(EditorToolEnum.MarkTool);

        var selectIndex = EditorTileMapManager.SelectWaveIndex;
        var waveList = EditorTileMapManager.SelectPreinstall.WaveList;
        for (var i = 0; i < waveList.Count; i++)
        {
            var wave = waveList[i];
            foreach (var markInfo in wave)
            {
                if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
                {
                    if (i == selectIndex) //选中当前波数, 透明度改为1
                    {
                        markTemplate.Instance.SetModulateAlpha(1f);
                    }
                    else //未选中当前波数, 透明度改为0.6
                    {
                        markTemplate.Instance.SetModulateAlpha(0.45f);
                    }
                }
            }
        }
    }
    
    //创建标记
    private void OnCreateMarkTool(object arg)
    {
        var markInfo = (MarkInfo)arg;
        CreateMarkTool(markInfo);
    }

    //创建标记
    private void CreateMarkTool(MarkInfo markInfo)
    {
        var cloneAndPut = S_MarkTemplate.CloneAndPut();
        _currMarkToolsMap.Add(markInfo, cloneAndPut);
        cloneAndPut.Instance.Visible = true;
        cloneAndPut.Instance.InitData(markInfo);
    }

    //选中标记
    private void OnSelectMarkTool(object arg)
    {
        //选中编辑工具
        SetActiviteTool(EditorToolEnum.MarkTool);
        
        if (arg is MarkInfo markInfo)
        {
            if (ActiveMark == null || markInfo != ActiveMark.MarkInfo)
            {
                if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
                {
                    SetActiveMark(markTemplate.Instance);
                }
            }
        }
        else if (arg == null && ActiveMark != null)
        {
            SetActiveMark(null);
        }
    }

    //删除标记
    private void OnDeleteMarkTool(object arg)
    {
        if (arg is MarkInfo markInfo)
        {
            if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
            {
                if (ActiveMark == markTemplate.Instance)
                {
                    SetActiveMark(null);
                }
                markTemplate.QueueFree();
                _currMarkToolsMap.Remove(markInfo);
            }
        }
    }

    //设置标记显示状态
    private void OnSetMarkVisible(object arg)
    {
        var data = (MarkInfoVisibleData)arg;
        if (_currMarkToolsMap.TryGetValue(data.MarkInfo, out var markTemplate))
        {
            markTemplate.Instance.Visible = data.Visible;
        }
    }
    
    //编辑标记
    private void OnEditMarkTool(object arg)
    {
        if (arg is MarkInfo markInfo)
        {
            if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
            {
                //刷新数据
                markTemplate.Instance.RefreshData();
            }
        }
    }
    
    /// <summary>
    /// 获取门区域对象
    /// </summary>
    public DoorHoverArea GetDoorHoverArea(DoorDirection direction)
    {
        switch (direction)
        {
            case DoorDirection.E: return S_E_HoverArea.Instance;
            case DoorDirection.N: return S_N_HoverArea.Instance;
            case DoorDirection.W: return S_W_HoverArea.Instance;
            case DoorDirection.S: return S_S_HoverArea.Instance;
        }
        return null;
    }
    
    /// <summary>
    /// 获取门区域根节点
    /// </summary>
    public Control GetDoorHoverAreaRoot(DoorDirection direction)
    {
        switch (direction)
        {
            case DoorDirection.E: return S_E_HoverRoot.Instance;
            case DoorDirection.N: return S_N_HoverRoot.Instance;
            case DoorDirection.W: return S_W_HoverRoot.Instance;
            case DoorDirection.S: return S_S_HoverRoot.Instance;
        }
        return null;
    }

    /// <summary>
    /// 设置活动的鼠标悬停的区域
    /// </summary>
    public void SetActiveHoverArea(DoorHoverArea hoverArea)
    {
        ActiveHoverArea = hoverArea;
        if (hoverArea != null)
        {
            S_HoverPreviewRoot.Instance.Reparent(hoverArea.GetParent(), false);
        }
        else
        {
            S_HoverPreviewRoot.Instance.Reparent(S_ToolRoot.Instance, false);
        }
    }

    /// <summary>
    /// 设置当前活动的标记
    /// </summary>
    public void SetActiveMark(MarkTool markTool)
    {
        if (ActiveMark == markTool)
        {
            return;
        }

        if (ActiveMark != null) //取消选中上一个
        {
            ActiveMark.OnUnSelect();
        }
        ActiveMark = markTool;
        if (markTool != null) //选中当前
        {
            ActiveMark.OnSelect();
            EditorTileMapManager.SetSelectMark(markTool.MarkInfo);
        }
        else
        {
            EditorTileMapManager.SetSelectMark(null);
        }
    }

    /// <summary>
    /// 创建门区域设置工具
    /// </summary>
    /// <param name="doorAreaInfo">门区域数据</param>
    public DoorToolTemplate CreateDoorTool(DoorAreaInfo doorAreaInfo)
    {
        var doorHoverArea = GetDoorHoverArea(doorAreaInfo.Direction);
        var inst = CreateDoorToolInstance(doorHoverArea);
        inst.Instance.DoorAreaInfo = doorAreaInfo;
        inst.Instance.SetDoorAreaPosition(GetDoorHoverAreaRoot(doorAreaInfo.Direction).Position);
        inst.Instance.SetDoorAreaRange(doorAreaInfo.Start, doorAreaInfo.End);
        return inst;
    }

    /// <summary>
    /// 创建拖拽状态下的门区域工具, 用于创建门区域
    /// </summary>
    /// <param name="doorHoverArea">悬停区域</param>
    /// <param name="start">起始位置, 单位: 像素</param>
    /// <param name="onSubmit">成功提交时回调, 参数1为方向, 参数2为起始点, 参数3为大小</param>
    /// <param name="onCancel">取消提交时调用</param>
    public DoorToolTemplate CreateDragDoorTool(DoorHoverArea doorHoverArea, int start,
        Action<DoorDirection, int, int> onSubmit, Action onCancel)
    {
        var inst = CreateDoorToolInstance(doorHoverArea);
        inst.Instance.SetDoorAreaPosition(GetDoorHoverAreaRoot(doorHoverArea.Direction).Position);
        inst.Instance.SetDoorAreaRange(start, start);
        inst.Instance.MakeDragMode(onSubmit, () =>
        {
            RemoveDoorTool(inst);
            onCancel();
        });
        return inst;
    }

    /// <summary>
    /// 移除门区域设置工具
    /// </summary>
    public void RemoveDoorTool(DoorToolTemplate toolInstance)
    {
        _doorTools.Remove(toolInstance);
        if (toolInstance.Instance.DoorAreaInfo != null)
        {
            EditorMap.RemoveDoorArea(toolInstance.Instance.DoorAreaInfo);
        }
        toolInstance.Instance.QueueFree();
        //派发修改数据修改事件
        EventManager.EmitEvent(EventEnum.OnTileMapDirty);
    }

    /// <summary>
    /// 设置工具根节点的大小和缩放
    /// </summary>
    /// <param name="pos">坐标</param>
    /// <param name="scale">缩放</param>
    public void SetToolTransform(Vector2 pos, Vector2 scale)
    {
        S_ToolRoot.Instance.Position = pos;
        S_ToolRoot.Instance.Scale = scale;
    }

    /// <summary>
    /// 设置鼠标悬停区域位置和大小
    /// </summary>
    /// <param name="position">房间起始点, 单位: 格</param>
    /// <param name="size">房间大小, 单位: 格</param>
    public void SetDoorHoverToolTransform(Vector2I position, Vector2I size)
    {
        position *= GameConfig.TileCellSize;
        size *= GameConfig.TileCellSize;

        var nPos1 = S_N_HoverRoot.Instance.Position;
        var ePos1 = S_E_HoverRoot.Instance.Position;
        var sPos1 = S_S_HoverRoot.Instance.Position;
        var wPos1 = S_W_HoverRoot.Instance.Position;
        var nPos2 = position + new Vector2I(GameConfig.TileCellSize * 2, GameConfig.TileCellSize * 3);
        var ePos2 = new Vector2(position.X + size.X - GameConfig.TileCellSize * 2, position.Y + GameConfig.TileCellSize * 3);
        var sPos2 = new Vector2(position.X + GameConfig.TileCellSize * 2, position.Y + size.Y - GameConfig.TileCellSize * 2);
        var wPos2 = position + new Vector2I(GameConfig.TileCellSize * 2, GameConfig.TileCellSize * 3);

        var nSize2 = new Vector2(size.X - GameConfig.TileCellSize * 4, S_N_HoverArea.Instance.Size.Y);
        var eSize2 = new Vector2(size.Y - GameConfig.TileCellSize * 5, S_E_HoverArea.Instance.Size.Y);
        var sSize2 = new Vector2(size.X - GameConfig.TileCellSize * 4, S_S_HoverArea.Instance.Size.Y);
        var wSize2 = new Vector2(size.Y - GameConfig.TileCellSize * 5, S_W_HoverArea.Instance.Size.Y);
        
        S_N_HoverRoot.Instance.Position = nPos2;
        S_E_HoverRoot.Instance.Position = ePos2;
        S_S_HoverRoot.Instance.Position = sPos2;
        S_W_HoverRoot.Instance.Position = wPos2;
        
        S_N_HoverArea.Instance.Size = nSize2;
        S_E_HoverArea.Instance.Size = eSize2;
        S_S_HoverArea.Instance.Size = sSize2;
        S_W_HoverArea.Instance.Size = wSize2;
        
        //调整门区域
        for (var i = 0; i < _doorTools.Count; i++)
        {
            var doorTool = _doorTools[i];
            var direction = doorTool.Instance.Direction;
            var areaRoot = GetDoorHoverAreaRoot(direction);
            var doorAreaRange = doorTool.Instance.GetDoorAreaRange();
            doorTool.Instance.SetDoorAreaPosition(areaRoot.Position);

            if (direction == DoorDirection.N)
            {
                var hOffset = (int)(nPos2.X - nPos1.X);
                doorAreaRange.X -= hOffset;
                doorAreaRange.Y -= hOffset;

                if (doorAreaRange.X >= 0 && doorAreaRange.Y <= nSize2.X) //允许提交
                {
                    doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
                    if (doorTool.Instance.DoorAreaInfo != null)
                    {
                        doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
                        doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
                    }
                }
                else //如果超出区域, 则删除
                {
                    RemoveDoorTool(doorTool);
                    i--;
                }
            }
            else if (direction == DoorDirection.S)
            {
                var hOffset = (int)(sPos2.X - sPos1.X);
                doorAreaRange.X -= hOffset;
                doorAreaRange.Y -= hOffset;

                if (doorAreaRange.X >= 0 && doorAreaRange.Y <= sSize2.X) //允许提交
                {
                    doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
                    if (doorTool.Instance.DoorAreaInfo != null)
                    {
                        doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
                        doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
                    }
                }
                else //如果超出区域, 则删除
                {
                    RemoveDoorTool(doorTool);
                    i--;
                }
            }
            else if (direction == DoorDirection.E)
            {
                var vOffset = (int)(ePos2.Y - ePos1.Y);
                doorAreaRange.X -= vOffset;
                doorAreaRange.Y -= vOffset;

                if (doorAreaRange.X >= 0 && doorAreaRange.Y <= eSize2.X) //允许提交
                {
                    doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
                    if (doorTool.Instance.DoorAreaInfo != null)
                    {
                        doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
                        doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
                    }
                }
                else //如果超出区域, 则删除
                {
                    RemoveDoorTool(doorTool);
                    i--;
                }
            }
            else if (direction == DoorDirection.W)
            {
                var vOffset = (int)(wPos2.Y - wPos1.Y);
                doorAreaRange.X -= vOffset;
                doorAreaRange.Y -= vOffset;

                if (doorAreaRange.X >= 0 && doorAreaRange.Y <= wSize2.X) //允许提交
                {
                    doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
                    if (doorTool.Instance.DoorAreaInfo != null)
                    {
                        doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
                        doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
                    }
                }
                else //如果超出区域, 则删除
                {
                    RemoveDoorTool(doorTool);
                    i--;
                }
            }
        }
    }
    
    private DoorToolTemplate CreateDoorToolInstance(DoorHoverArea doorHoverArea)
    {
        var doorTool = S_DoorToolTemplate.Clone();
        S_ToolRoot.Instance.AddChild(doorTool.Instance);
        doorTool.Instance.SetDoorDragAreaNode(doorTool);
        doorTool.L_StartBtn.Instance.SetMapEditorToolsPanel(this);
        doorTool.L_EndBtn.Instance.SetMapEditorToolsPanel(this);
        doorTool.Instance.SetDoorHoverArea(doorHoverArea);
        _doorTools.Add(doorTool);
        return doorTool;
    }
    
    private void OnSavePreviewImageBegin(object obj)
    {
        foreach (var custonObjectData in CustomObjecMapping)
        {
            custonObjectData.Value.Node.L_RectBrush.Instance.Visible = false;
        }

        _tempColor1 = CustomNormalRoot.Modulate;
        _tempColor2 = CustomYSortRoot.Modulate;

        CustomNormalRoot.Modulate = Colors.White;
        CustomYSortRoot.Modulate = Colors.White;
    }

    private void OnSavePreviewImageFinish(object obj)
    {
        foreach (var custonObjectData in CustomObjecMapping)
        {
            custonObjectData.Value.Node.L_RectBrush.Instance.Visible = true;
        }
        
        CustomNormalRoot.Modulate = _tempColor1;
        CustomYSortRoot.Modulate = _tempColor2;
    }
}