Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditor / tileView / EditorTileMap.cs
@小李xl 小李xl on 9 Jan 2024 42 KB 存储和读取房间Tile数据
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Godot;
  5. using Godot.Collections;
  6. using UI.MapEditorTools;
  7.  
  8. namespace UI.MapEditor;
  9.  
  10. public partial class EditorTileMap : TileMap, IUiNodeScript
  11. {
  12. public enum MouseButtonType
  13. {
  14. /// <summary>
  15. /// 无状态
  16. /// </summary>
  17. None,
  18. /// <summary>
  19. /// 拖拽模式
  20. /// </summary>
  21. Drag,
  22. /// <summary>
  23. /// 笔
  24. /// </summary>
  25. Pen,
  26. /// <summary>
  27. /// 绘制区域模式
  28. /// </summary>
  29. Area,
  30. /// <summary>
  31. /// 编辑工具模式
  32. /// </summary>
  33. Edit,
  34. }
  35. /// <summary>
  36. /// 自动图块地板层
  37. /// </summary>
  38. public const int AutoFloorLayer = 0;
  39. /// <summary>
  40. /// 自定义图块地板层
  41. /// </summary>
  42. public const int CustomFloorLayer = 1;
  43. /// <summary>
  44. /// 自动图块中间层
  45. /// </summary>
  46. public const int AutoMiddleLayer = 2;
  47. /// <summary>
  48. /// 自定义图块中间层
  49. /// </summary>
  50. public const int CustomMiddleLayer = 3;
  51. /// <summary>
  52. /// 自动图块顶层
  53. /// </summary>
  54. public const int AutoTopLayer = 4;
  55. /// <summary>
  56. /// 自定义图块顶层
  57. /// </summary>
  58. public const int CustomTopLayer = 5;
  59. /// <summary>
  60. /// 标记数据层
  61. /// </summary>
  62. public const int MarkLayer = 10;
  63. /// <summary>
  64. /// 所属地图编辑器UI
  65. /// </summary>
  66. public MapEditorPanel MapEditorPanel { get; private set; }
  67. /// <summary>
  68. /// 编辑器工具UI
  69. /// </summary>
  70. public MapEditorToolsPanel MapEditorToolsPanel { get; set; }
  71. /// <summary>
  72. /// 左键功能
  73. /// </summary>
  74. public MouseButtonType MouseType { get; private set; } = MouseButtonType.Pen;
  75. //鼠标坐标
  76. private Vector2 _mousePosition;
  77. //鼠标所在的cell坐标
  78. private Vector2I _mouseCellPosition;
  79. //上一帧鼠标所在的cell坐标
  80. private Vector2I _prevMouseCellPosition = new Vector2I(-99999, -99999);
  81. //单次绘制是否改变过tile数据
  82. private bool _changeFlag = false;
  83. //左键开始按下时鼠标所在的坐标
  84. private Vector2I _mouseStartCellPosition;
  85. //鼠标中建是否按下
  86. private bool _isMiddlePressed = false;
  87. private Vector2 _moveOffset;
  88. //左键是否按下
  89. private bool _isLeftPressed = false;
  90. //右键是否按下
  91. private bool _isRightPressed = false;
  92. //绘制填充区域
  93. private bool _drawFullRect = false;
  94. //负责存储自动图块数据
  95. private InfiniteGrid<bool> _autoCellLayerGrid = new InfiniteGrid<bool>();
  96. //停止绘制多久后开始执行生成操作
  97. private float _generateInterval = 3f;
  98. //生成自动图块和导航网格的计时器
  99. private float _generateTimer = -1;
  100. //检测地形结果
  101. private bool _checkTerrainFlag = true;
  102. //错误地形位置
  103. private Vector2I _checkTerrainErrorPosition = Vector2I.Zero;
  104. //是否执行生成地形成功
  105. private bool _isGenerateTerrain = true;
  106. //导航网格数据
  107. private Vector2[][] _polygonData;
  108. private bool _initLayer = false;
  109.  
  110. //--------- 配置数据 -------------
  111. private int _sourceId = 0;
  112. private int _terrainSet = 0;
  113. private int _terrain = 0;
  114. private AutoTileConfig _autoTileConfig;
  115.  
  116. /// <summary>
  117. /// 正在编辑的房间数据
  118. /// </summary>
  119. public DungeonRoomSplit CurrRoomSplit;
  120. /// <summary>
  121. /// 数据是否脏了, 也就是是否有修改
  122. /// </summary>
  123. public bool IsDirty { get; private set; }
  124.  
  125. /// <summary>
  126. /// 地图是否有绘制错误
  127. /// </summary>
  128. public bool HasTerrainError => !_isGenerateTerrain;
  129.  
  130. //变动过的数据
  131. /// <summary>
  132. /// 地图位置, 单位: 格
  133. /// </summary>
  134. public Vector2I CurrRoomPosition { get; private set; }
  135. /// <summary>
  136. /// 当前地图大小, 单位: 格
  137. /// </summary>
  138. public Vector2I CurrRoomSize { get; private set; }
  139. /// <summary>
  140. /// 当前编辑的门数据
  141. /// </summary>
  142. public List<DoorAreaInfo> CurrDoorConfigs { get; } = new List<DoorAreaInfo>();
  143. //-------------------------------
  144. private MapEditor.TileMap _editorTileMap;
  145. private EventFactory _eventFactory;
  146. /// <summary>
  147. /// 初始化图块集。
  148. /// </summary>
  149. /// <param name="tileSetSplit">要初始化的图块集</param>
  150. public void InitTileSet(TileSetSplit tileSetSplit)
  151. {
  152. TileSet = tileSetSplit.GetTileSet();
  153.  
  154. // 创建AutoTileConfig对象
  155. // 使用第一个图块集源作为参数
  156. _autoTileConfig = new AutoTileConfig(0, tileSetSplit.TileSetInfo.Sources[0].Terrain);
  157. }
  158. public void SetUiNode(IUiNode uiNode)
  159. {
  160. _editorTileMap = (MapEditor.TileMap)uiNode;
  161. MapEditorPanel = _editorTileMap.UiPanel;
  162. MapEditorToolsPanel = _editorTileMap.UiPanel.S_MapEditorTools.Instance;
  163.  
  164. _editorTileMap.L_Brush.Instance.Draw += DrawGuides;
  165. _eventFactory = EventManager.CreateEventFactory();
  166. _eventFactory.AddEventListener(EventEnum.OnSelectDragTool, OnSelectHandTool);
  167. _eventFactory.AddEventListener(EventEnum.OnSelectPenTool, OnSelectPenTool);
  168. _eventFactory.AddEventListener(EventEnum.OnSelectRectTool, OnSelectRectTool);
  169. _eventFactory.AddEventListener(EventEnum.OnSelectEditTool, OnSelectEditTool);
  170. _eventFactory.AddEventListener(EventEnum.OnClickCenterTool, OnClickCenterTool);
  171. _eventFactory.AddEventListener(EventEnum.OnTileMapDirty, OnEditorDirty);
  172.  
  173. RenderingServer.FramePostDraw += OnFramePostDraw;
  174. var navigationRegion = _editorTileMap.L_NavigationRegion.Instance;
  175. navigationRegion.Visible = false;
  176. navigationRegion.NavigationPolygon.AgentRadius = GameConfig.NavigationAgentRadius;
  177. navigationRegion.BakeFinished += OnBakeFinished;
  178. }
  179.  
  180. public void OnDestroy()
  181. {
  182. _eventFactory.RemoveAllEventListener();
  183. RenderingServer.FramePostDraw -= OnFramePostDraw;
  184. }
  185. public override void _Ready()
  186. {
  187. InitLayer();
  188. }
  189.  
  190. public override void _Process(double delta)
  191. {
  192. //触发绘制辅助线
  193. _editorTileMap.L_Brush.Instance.QueueRedraw();
  194. var newDelta = (float)delta;
  195. _drawFullRect = false;
  196. var position = GetLocalMousePosition();
  197. _mouseCellPosition = LocalToMap(position);
  198. _mousePosition = new Vector2(
  199. _mouseCellPosition.X * GameConfig.TileCellSize,
  200. _mouseCellPosition.Y * GameConfig.TileCellSize
  201. );
  202. if (!MapEditorToolsPanel.S_HBoxContainer.Instance.IsPositionOver(GetGlobalMousePosition())) //不在Ui节点上
  203. {
  204. //左键绘制
  205. if (_isLeftPressed)
  206. {
  207. if (MouseType == MouseButtonType.Pen) //绘制单格
  208. {
  209. if (_prevMouseCellPosition != _mouseCellPosition || !_changeFlag) //鼠标位置变过
  210. {
  211. _changeFlag = true;
  212. _prevMouseCellPosition = _mouseCellPosition;
  213. //绘制自动图块
  214. SetSingleAutoCell(_mouseCellPosition);
  215. }
  216. }
  217. else if (MouseType == MouseButtonType.Area) //绘制区域
  218. {
  219. _drawFullRect = true;
  220. }
  221. else if (MouseType == MouseButtonType.Drag) //拖拽
  222. {
  223. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  224. }
  225. }
  226. else if (_isRightPressed) //右键擦除
  227. {
  228. if (MouseType == MouseButtonType.Pen) //绘制单格
  229. {
  230. if (_prevMouseCellPosition != _mouseCellPosition || !_changeFlag) //鼠标位置变过
  231. {
  232. _changeFlag = true;
  233. _prevMouseCellPosition = _mouseCellPosition;
  234. EraseSingleAutoCell(_mouseCellPosition);
  235. }
  236. }
  237. else if (MouseType == MouseButtonType.Area) //绘制区域
  238. {
  239. _drawFullRect = true;
  240. }
  241. else if (MouseType == MouseButtonType.Drag) //拖拽
  242. {
  243. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  244. }
  245. }
  246. else if (_isMiddlePressed) //中键移动
  247. {
  248. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  249. }
  250. }
  251.  
  252. //绘制停止指定时间后, 生成导航网格
  253. if (_generateTimer > 0)
  254. {
  255. _generateTimer -= newDelta;
  256. if (_generateTimer <= 0)
  257. {
  258. //检测地形
  259. RunCheckHandler();
  260. }
  261. }
  262. }
  263.  
  264. /// <summary>
  265. /// 绘制辅助线
  266. /// </summary>
  267. public void DrawGuides()
  268. {
  269. if (_hasPreviewImage)
  270. {
  271. return;
  272. }
  273. CanvasItem canvasItem = _editorTileMap.L_Brush.Instance;
  274. //轴线
  275. canvasItem.DrawLine(new Vector2(0, 2000), new Vector2(0, -2000), Colors.Green);
  276. canvasItem.DrawLine(new Vector2(2000, 0), new Vector2( -2000, 0), Colors.Red);
  277. //绘制房间区域
  278. if (CurrRoomSize.X != 0 && CurrRoomSize.Y != 0)
  279. {
  280. canvasItem.DrawRect(
  281. new Rect2(
  282. (CurrRoomPosition + new Vector2I(1, 2)) * GameConfig.TileCellSize,
  283. (CurrRoomSize - new Vector2I(2, 3)) * GameConfig.TileCellSize
  284. ),
  285. Colors.Aqua, false, 5f / Scale.X
  286. );
  287. }
  288.  
  289. //绘制导航网格
  290. if (_checkTerrainFlag && _isGenerateTerrain && _polygonData != null)
  291. {
  292. foreach (var vector2s in _polygonData)
  293. {
  294. canvasItem.DrawPolygon(vector2s, new Color(0,1,1, 0.3f).MakeArray(vector2s.Length));
  295. }
  296. }
  297.  
  298. if (MouseType == MouseButtonType.Pen || MouseType == MouseButtonType.Area)
  299. {
  300. if (_drawFullRect) //绘制填充矩形
  301. {
  302. var size = TileSet.TileSize;
  303. var cellPos = _mouseStartCellPosition;
  304. var temp = size;
  305. if (_mouseStartCellPosition.X > _mouseCellPosition.X)
  306. {
  307. cellPos.X += 1;
  308. temp.X -= size.X;
  309. }
  310. if (_mouseStartCellPosition.Y > _mouseCellPosition.Y)
  311. {
  312. cellPos.Y += 1;
  313. temp.Y -= size.Y;
  314. }
  315.  
  316. var pos = cellPos * size;
  317. canvasItem.DrawRect(new Rect2(pos, _mousePosition - pos + temp), Colors.White, false, 2f / Scale.X);
  318. }
  319. else //绘制单格
  320. {
  321. canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.White, false, 2f / Scale.X);
  322. }
  323. }
  324. }
  325.  
  326. public override void _Input(InputEvent @event)
  327. {
  328. if (@event is InputEventMouseButton mouseButton)
  329. {
  330. if (mouseButton.ButtonIndex == MouseButton.Left) //左键
  331. {
  332. if (mouseButton.Pressed) //按下
  333. {
  334. _moveOffset = Position - GetGlobalMousePosition();
  335. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  336. }
  337. else
  338. {
  339. _changeFlag = false;
  340. if (_drawFullRect) //松开, 提交绘制的矩形区域
  341. {
  342. SetRectAutoCell(_mouseStartCellPosition, _mouseCellPosition);
  343. _drawFullRect = false;
  344. }
  345. }
  346.  
  347. _isLeftPressed = mouseButton.Pressed;
  348. }
  349. else if (mouseButton.ButtonIndex == MouseButton.Right) //右键
  350. {
  351. if (mouseButton.Pressed) //按下
  352. {
  353. _moveOffset = Position - GetGlobalMousePosition();
  354. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  355. }
  356. else
  357. {
  358. _changeFlag = false;
  359. if (_drawFullRect) //松开, 提交擦除的矩形区域
  360. {
  361. EraseRectAutoCell(_mouseStartCellPosition, _mouseCellPosition);
  362. _drawFullRect = false;
  363. }
  364. }
  365. _isRightPressed = mouseButton.Pressed;
  366. }
  367. else if (mouseButton.ButtonIndex == MouseButton.WheelDown)
  368. {
  369. //缩小
  370. Shrink();
  371. }
  372. else if (mouseButton.ButtonIndex == MouseButton.WheelUp)
  373. {
  374. //放大
  375. Magnify();
  376. }
  377. else if (mouseButton.ButtonIndex == MouseButton.Middle)
  378. {
  379. _isMiddlePressed = mouseButton.Pressed;
  380. if (_isMiddlePressed)
  381. {
  382. _moveOffset = Position - GetGlobalMousePosition();
  383. }
  384. }
  385. }
  386. }
  387.  
  388. /// <summary>
  389. /// 尝试运行检查, 如果已经运行过了, 则没有效果
  390. /// </summary>
  391. public void TryRunCheckHandler()
  392. {
  393. if (_generateTimer > 0)
  394. {
  395. _generateTimer = -1;
  396. RunCheckHandler();
  397. }
  398. }
  399. //执行检测地形操作
  400. private void RunCheckHandler()
  401. {
  402. _isGenerateTerrain = false;
  403. //计算区域
  404. CalcTileRect(false);
  405. Debug.Log("开始检测是否可以生成地形...");
  406. if (CheckTerrain())
  407. {
  408. Debug.Log("开始绘制自动贴图...");
  409. GenerateTerrain();
  410. _isGenerateTerrain = true;
  411. }
  412. else
  413. {
  414. SetErrorCell(_checkTerrainErrorPosition);
  415. }
  416. }
  417.  
  418. //将指定自动地形层数据存入list中
  419. private void PushAutoLayerDataToList(int layer, int sourceId, List<int> list)
  420. {
  421. var layerArray = GetUsedCellsById(layer, sourceId);
  422. foreach (var pos in layerArray)
  423. {
  424. var atlasCoords = GetCellAtlasCoords(layer, pos);
  425. var tileCellData = _autoTileConfig.GetCellData(atlasCoords);
  426. if (tileCellData != null)
  427. {
  428. list.Add(pos.X);
  429. list.Add(pos.Y);
  430. list.Add((int)tileCellData.TerrainPeering);
  431. list.Add(tileCellData.TerrainType);
  432. }
  433. }
  434. }
  435.  
  436. //设置自动地形层的数据
  437. private void SetAutoLayerDataFromList(int layer, List<int> list)
  438. {
  439. var terrainInfo = _autoTileConfig.TerrainInfo;
  440. var sourceId = _autoTileConfig.SourceId;
  441. for (var i = 0; i < list.Count; i += 4)
  442. {
  443. var pos = new Vector2I(list[i], list[i + 1]);
  444. var bit = (uint)list[i + 2];
  445. var type = (byte)list[i + 3];
  446. var index = terrainInfo.TerrainBitToIndex(bit, type);
  447. var terrainCell = terrainInfo.GetTerrainCell(index, type);
  448. var atlasCoords = terrainInfo.GetPosition(terrainCell);
  449. SetCell(layer, pos, sourceId, atlasCoords);
  450. if (layer == AutoFloorLayer)
  451. {
  452. _autoCellLayerGrid.Set(pos, true);
  453. }
  454. }
  455. }
  456.  
  457. /// <summary>
  458. /// 触发保存地图数据
  459. /// </summary>
  460. public void TriggerSave(RoomErrorType errorType, Action finish)
  461. {
  462. Debug.Log("保存地牢房间数据...");
  463. //执行创建预览图流程
  464. RunSavePreviewImage(() =>
  465. {
  466. //执行保存数据流程
  467. CurrRoomSplit.ErrorType = errorType;
  468. SaveRoomInfoConfig();
  469. SaveTileInfoConfig();
  470. SavePreinstallConfig();
  471. IsDirty = false;
  472. MapEditorPanel.SetTitleDirty(false);
  473. //派发保存事件
  474. EventManager.EmitEvent(EventEnum.OnTileMapSave);
  475. if (finish != null)
  476. {
  477. finish();
  478. }
  479. });
  480. }
  481.  
  482. /// <summary>
  483. /// 加载地牢, 返回是否加载成功
  484. /// </summary>
  485. public bool Load(DungeonRoomSplit roomSplit)
  486. {
  487. //重新加载数据
  488. roomSplit.ReloadRoomInfo();
  489. roomSplit.ReloadTileInfo();
  490. roomSplit.ReloadPreinstall();
  491. CurrRoomSplit = roomSplit;
  492. var roomInfo = roomSplit.RoomInfo;
  493. var tileInfo = roomSplit.TileInfo;
  494.  
  495. CurrRoomPosition = roomInfo.Position.AsVector2I();
  496. SetMapSize(roomInfo.Size.AsVector2I(), true);
  497. CurrDoorConfigs.Clear();
  498. foreach (var doorAreaInfo in roomInfo.DoorAreaInfos)
  499. {
  500. CurrDoorConfigs.Add(doorAreaInfo.Clone());
  501. }
  502.  
  503. //初始化层级数据
  504. InitLayer();
  505. //地块数据
  506. SetAutoLayerDataFromList(AutoFloorLayer, tileInfo.Floor);
  507. SetAutoLayerDataFromList(AutoMiddleLayer, tileInfo.Middle);
  508. SetAutoLayerDataFromList(AutoTopLayer, tileInfo.Top);
  509.  
  510. //如果有图块错误, 则找出错误的点位
  511. if (roomSplit.ErrorType == RoomErrorType.TileError)
  512. {
  513. RunCheckHandler();
  514. }
  515. else
  516. {
  517. //导航网格
  518. if (tileInfo.NavigationPolygon != null && tileInfo.NavigationVertices != null)
  519. {
  520. var polygon = _editorTileMap.L_NavigationRegion.Instance.NavigationPolygon;
  521. polygon.Vertices = tileInfo.NavigationVertices.Select(v => v.AsVector2()).ToArray();
  522. foreach (var p in tileInfo.NavigationPolygon)
  523. {
  524. polygon.AddPolygon(p);
  525. }
  526.  
  527. OnBakeFinished();
  528. }
  529. }
  530. //聚焦
  531. //MapEditorPanel.CallDelay(0.1f, OnClickCenterTool);
  532. //CallDeferred(nameof(OnClickCenterTool), null);
  533. //加载门编辑区域
  534. foreach (var doorAreaInfo in CurrDoorConfigs)
  535. {
  536. MapEditorToolsPanel.CreateDoorTool(doorAreaInfo);
  537. }
  538. //聚焦
  539. OnClickCenterTool(null);
  540. return true;
  541. }
  542.  
  543. private void InitLayer()
  544. {
  545. if (_initLayer)
  546. {
  547. return;
  548. }
  549.  
  550. _initLayer = true;
  551. //初始化层级数据
  552. AddLayer(CustomFloorLayer);
  553. SetLayerZIndex(CustomFloorLayer, CustomFloorLayer);
  554. AddLayer(AutoMiddleLayer);
  555. SetLayerZIndex(AutoMiddleLayer, AutoMiddleLayer);
  556. AddLayer(CustomMiddleLayer);
  557. SetLayerZIndex(CustomMiddleLayer, CustomMiddleLayer);
  558. AddLayer(AutoTopLayer);
  559. SetLayerZIndex(AutoTopLayer, AutoTopLayer);
  560. AddLayer(CustomTopLayer);
  561. SetLayerZIndex(CustomTopLayer, CustomTopLayer);
  562. }
  563.  
  564. //缩小
  565. private void Shrink()
  566. {
  567. var pos = GetLocalMousePosition();
  568. var scale = Scale / 1.1f;
  569. if (scale.LengthSquared() >= 0.5f)
  570. {
  571. Scale = scale;
  572. SetMapPosition(Position + pos * 0.1f * scale);
  573. }
  574. }
  575. //放大
  576. private void Magnify()
  577. {
  578. var pos = GetLocalMousePosition();
  579. var prevScale = Scale;
  580. var scale = prevScale * 1.1f;
  581. if (scale.LengthSquared() <= 2000)
  582. {
  583. Scale = scale;
  584. SetMapPosition(Position - pos * 0.1f * prevScale);
  585. }
  586. }
  587.  
  588. //绘制单个自动贴图
  589. private void SetSingleAutoCell(Vector2I position)
  590. {
  591. var tileCellData = _autoTileConfig.Floor;
  592. SetCell(GetFloorLayer(), position, tileCellData.SourceId, tileCellData.AutoTileCoords);
  593. //SetCell(GetFloorLayer(), position, _sourceId, _autoTileConfig.Floor.AutoTileCoords);
  594. if (!_autoCellLayerGrid.Contains(position.X, position.Y))
  595. {
  596. ResetGenerateTimer();
  597. _autoCellLayerGrid.Set(position.X, position.Y, true);
  598. }
  599. }
  600. //绘制区域自动贴图
  601. private void SetRectAutoCell(Vector2I start, Vector2I end)
  602. {
  603. ResetGenerateTimer();
  604. if (start.X > end.X)
  605. {
  606. var temp = end.X;
  607. end.X = start.X;
  608. start.X = temp;
  609. }
  610. if (start.Y > end.Y)
  611. {
  612. var temp = end.Y;
  613. end.Y = start.Y;
  614. start.Y = temp;
  615. }
  616.  
  617. var width = end.X - start.X + 1;
  618. var height = end.Y - start.Y + 1;
  619. for (var i = 0; i < width; i++)
  620. {
  621. for (var j = 0; j < height; j++)
  622. {
  623. var tileCellData = _autoTileConfig.Floor;
  624. SetCell(GetFloorLayer(), new Vector2I(start.X + i, start.Y + j), tileCellData.SourceId, tileCellData.AutoTileCoords);
  625. }
  626. }
  627.  
  628. _autoCellLayerGrid.SetRect(start, new Vector2I(width, height), true);
  629. }
  630.  
  631. //擦除单个自动图块
  632. private void EraseSingleAutoCell(Vector2I position)
  633. {
  634. EraseCell(GetFloorLayer(), position);
  635. if (_autoCellLayerGrid.Remove(position.X, position.Y))
  636. {
  637. ResetGenerateTimer();
  638. }
  639. }
  640. //擦除一个区域内的自动贴图
  641. private void EraseRectAutoCell(Vector2I start, Vector2I end)
  642. {
  643. ResetGenerateTimer();
  644. if (start.X > end.X)
  645. {
  646. var temp = end.X;
  647. end.X = start.X;
  648. start.X = temp;
  649. }
  650. if (start.Y > end.Y)
  651. {
  652. var temp = end.Y;
  653. end.Y = start.Y;
  654. start.Y = temp;
  655. }
  656.  
  657. var width = end.X - start.X + 1;
  658. var height = end.Y - start.Y + 1;
  659. for (var i = 0; i < width; i++)
  660. {
  661. for (var j = 0; j < height; j++)
  662. {
  663. EraseCell(GetFloorLayer(), new Vector2I(start.X + i, start.Y + j));
  664. }
  665. }
  666. _autoCellLayerGrid.RemoveRect(start, new Vector2I(width, height));
  667. }
  668.  
  669. //重置计时器
  670. private void ResetGenerateTimer()
  671. {
  672. _generateTimer = _generateInterval;
  673. _isGenerateTerrain = false;
  674. ClearLayer(AutoTopLayer);
  675. ClearLayer(AutoMiddleLayer);
  676. CloseErrorCell();
  677. //标记有修改数据
  678. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  679. }
  680.  
  681. //重新计算房间区域
  682. private void CalcTileRect(bool refreshDoorTrans)
  683. {
  684. var rect = GetUsedRect();
  685. CurrRoomPosition = rect.Position;
  686. SetMapSize(rect.Size, refreshDoorTrans);
  687. }
  688. //检测是否有不合规的图块, 返回true表示图块正常
  689. private bool CheckTerrain()
  690. {
  691. _checkTerrainFlag = true;
  692. _autoCellLayerGrid.ForEach((x, y, flag) =>
  693. {
  694. if (flag)
  695. {
  696. if (!_autoCellLayerGrid.Contains(x, y + 1) && _autoCellLayerGrid.Contains(x, y + 2))
  697. {
  698. _checkTerrainFlag = false;
  699. _checkTerrainErrorPosition = new Vector2I(x, y + 1);
  700. return false;
  701. }
  702. }
  703.  
  704. return true;
  705. });
  706. return _checkTerrainFlag;
  707. }
  708. //生成自动图块 (地形)
  709. private void GenerateTerrain()
  710. {
  711. //ClearLayer(AutoFloorLayer);
  712. var list = new List<Vector2I>();
  713. var xStart = int.MaxValue;
  714. var yStart = int.MaxValue;
  715. var xEnd = int.MinValue;
  716. var yEnd = int.MinValue;
  717. _autoCellLayerGrid.ForEach((x, y, flag) =>
  718. {
  719. if (flag)
  720. {
  721. //计算范围
  722. if (x < xStart)
  723. xStart = x;
  724. else if (x > xEnd)
  725. xEnd = x;
  726.  
  727. if (y < yStart)
  728. yStart = y;
  729. else if (y > yEnd)
  730. yEnd = y;
  731. //填充墙壁
  732. if (!_autoCellLayerGrid.Contains(x, y - 1))
  733. {
  734. var left = _autoCellLayerGrid.Contains(x - 1, y - 1);
  735. var right = _autoCellLayerGrid.Contains(x + 1, y - 1);
  736. TileCellData tileCellData;
  737. if (left && right)
  738. {
  739. tileCellData = _autoTileConfig.Wall_Vertical_Single;
  740. }
  741. else if (left)
  742. {
  743. tileCellData = _autoTileConfig.Wall_Vertical_Left;
  744. }
  745. else if (right)
  746. {
  747. tileCellData = _autoTileConfig.Wall_Vertical_Right;
  748. }
  749. else
  750. {
  751. tileCellData = _autoTileConfig.Wall_Vertical_Center;
  752. }
  753. SetCell(GetFloorLayer(), new Vector2I(x, y - 1), tileCellData.SourceId, tileCellData.AutoTileCoords);
  754. }
  755. }
  756.  
  757. return true;
  758. });
  759. //绘制临时边界
  760. var temp1 = new List<Vector2I>();
  761. for (var x = xStart - 3; x <= xEnd + 3; x++)
  762. {
  763. var p1 = new Vector2I(x, yStart - 4);
  764. var p2 = new Vector2I(x, yEnd + 3);
  765. temp1.Add(p1);
  766. temp1.Add(p2);
  767. //上横
  768. SetCell(GetFloorLayer(), p1, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  769. //下横
  770. SetCell(GetFloorLayer(), p2, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  771. }
  772. for (var y = yStart - 4; y <= yEnd + 3; y++)
  773. {
  774. var p1 = new Vector2I(xStart - 3, y);
  775. var p2 = new Vector2I(xEnd + 3, y);
  776. temp1.Add(p1);
  777. temp1.Add(p2);
  778. //左竖
  779. SetCell(GetFloorLayer(), p1, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  780. //右竖
  781. SetCell(GetFloorLayer(), p2, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  782. }
  783. //计算需要绘制的图块
  784. var temp2 = new List<Vector2I>();
  785. for (var x = xStart - 2; x <= xEnd + 2; x++)
  786. {
  787. for (var y = yStart - 3; y <= yEnd + 2; y++)
  788. {
  789. if (!_autoCellLayerGrid.Contains(x, y) && !_autoCellLayerGrid.Contains(x, y + 1))
  790. {
  791. list.Add(new Vector2I(x, y));
  792. if (!IsMaskCollisionGround(_autoCellLayerGrid, x, y))
  793. {
  794. temp2.Add(new Vector2I(x, y));
  795. }
  796. }
  797. }
  798. }
  799. var arr = new Array<Vector2I>(list);
  800. //绘制自动图块
  801. SetCellsTerrainConnect(AutoFloorLayer, arr, _terrainSet, _terrain, false);
  802. //擦除临时边界
  803. for (var i = 0; i < temp1.Count; i++)
  804. {
  805. EraseCell(GetFloorLayer(), temp1[i]);
  806. }
  807.  
  808. //计算区域
  809. CalcTileRect(true);
  810. //开始绘制导航网格
  811. GenerateNavigation();
  812.  
  813. //擦除临时边界2
  814. for (var i = 0; i < temp2.Count; i++)
  815. {
  816. EraseCell(GetFloorLayer(), temp2[i]);
  817. }
  818. //将墙壁移动到指定层
  819. MoveTerrainCell();
  820. }
  821.  
  822. private bool IsMaskCollisionGround(InfiniteGrid<bool> autoCellLayerGrid, int x, int y)
  823. {
  824. for (var i = -2; i <= 2; i++)
  825. {
  826. for (var j = -2; j <= 3; j++)
  827. {
  828. if (autoCellLayerGrid.Contains(x + i, y + j))
  829. {
  830. return true;
  831. }
  832. }
  833. }
  834.  
  835. return false;
  836. }
  837. //将自动生成的图块从 AutoFloorLayer 移动到指定图层中
  838. private void MoveTerrainCell()
  839. {
  840. ClearLayer(AutoTopLayer);
  841. ClearLayer(AutoMiddleLayer);
  842. var x = CurrRoomPosition.X;
  843. var y = CurrRoomPosition.Y;
  844. var w = CurrRoomSize.X;
  845. var h = CurrRoomSize.Y;
  846.  
  847. for (var i = 0; i < w; i++)
  848. {
  849. for (var j = 0; j < h; j++)
  850. {
  851. var pos = new Vector2I(x + i, y + j);
  852. if (!_autoCellLayerGrid.Contains(pos) && GetCellSourceId(AutoFloorLayer, pos) != -1)
  853. {
  854. var atlasCoords = GetCellAtlasCoords(AutoFloorLayer, pos);
  855. var layer = _autoTileConfig.GetLayer(atlasCoords);
  856. if (layer == GameConfig.MiddleMapLayer)
  857. {
  858. layer = AutoMiddleLayer;
  859. }
  860. else if (layer == GameConfig.TopMapLayer)
  861. {
  862. layer = AutoTopLayer;
  863. }
  864. else
  865. {
  866. Debug.LogError($"异常图块: {pos}, 这个图块的图集坐标'{atlasCoords}'不属于'MiddleMapLayer'和'TopMapLayer'!");
  867. continue;
  868. }
  869. EraseCell(AutoFloorLayer, pos);
  870. SetCell(layer, pos, _sourceId, atlasCoords);
  871. }
  872. }
  873. }
  874. }
  875.  
  876. //生成导航网格
  877. private void GenerateNavigation()
  878. {
  879. var navigationRegion = _editorTileMap.L_NavigationRegion.Instance;
  880. var navigationPolygon = navigationRegion.NavigationPolygon;
  881. navigationPolygon.Clear();
  882. navigationPolygon.ClearPolygons();
  883. navigationPolygon.ClearOutlines();
  884. var endPos = CurrRoomPosition + CurrRoomSize;
  885. navigationPolygon.AddOutline(new []
  886. {
  887. CurrRoomPosition * GameConfig.TileCellSize,
  888. new Vector2(endPos.X, CurrRoomPosition.Y) * GameConfig.TileCellSize,
  889. endPos * GameConfig.TileCellSize,
  890. new Vector2(CurrRoomPosition.X, endPos.Y) * GameConfig.TileCellSize
  891. });
  892. navigationRegion.BakeNavigationPolygon(false);
  893. }
  894.  
  895. //设置显示的错误cell, 会标记上红色的闪烁动画
  896. private void SetErrorCell(Vector2I pos)
  897. {
  898. MapEditorPanel.S_ErrorCell.Instance.Position = pos * GameConfig.TileCellSize;
  899. MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Play(AnimatorNames.Show);
  900. }
  901.  
  902. //关闭显示的错误cell
  903. private void CloseErrorCell()
  904. {
  905. MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Stop();
  906. }
  907.  
  908. private int GetFloorLayer()
  909. {
  910. return AutoFloorLayer;
  911. }
  912.  
  913. private int GetMiddleLayer()
  914. {
  915. return AutoMiddleLayer;
  916. }
  917.  
  918. private int GetTopLayer()
  919. {
  920. return AutoTopLayer;
  921. }
  922.  
  923. /// <summary>
  924. /// 选中拖拽功能
  925. /// </summary>
  926. private void OnSelectHandTool(object arg)
  927. {
  928. MouseType = MouseButtonType.Drag;
  929. }
  930. /// <summary>
  931. /// 选中画笔攻击
  932. /// </summary>
  933. private void OnSelectPenTool(object arg)
  934. {
  935. MouseType = MouseButtonType.Pen;
  936. }
  937.  
  938. /// <summary>
  939. /// 选中绘制区域功能
  940. /// </summary>
  941. private void OnSelectRectTool(object arg)
  942. {
  943. MouseType = MouseButtonType.Area;
  944. }
  945.  
  946. /// <summary>
  947. /// 选择编辑门区域
  948. /// </summary>
  949. private void OnSelectEditTool(object arg)
  950. {
  951. MouseType = MouseButtonType.Edit;
  952. }
  953.  
  954. /// <summary>
  955. /// 聚焦
  956. /// </summary>
  957. private void OnClickCenterTool(object arg)
  958. {
  959. var pos = MapEditorPanel.S_SubViewport.Instance.Size / 2;
  960. if (CurrRoomSize.X == 0 && CurrRoomSize.Y == 0) //聚焦原点
  961. {
  962. SetMapPosition(pos);
  963. }
  964. else //聚焦地图中心点
  965. {
  966. SetMapPosition(pos - (CurrRoomPosition + CurrRoomSize / 2) * TileSet.TileSize * Scale);
  967. }
  968. }
  969. //房间数据有修改
  970. private void OnEditorDirty(object obj)
  971. {
  972. IsDirty = true;
  973. MapEditorPanel.SetTitleDirty(true);
  974. }
  975.  
  976. /// <summary>
  977. /// 创建地牢房间门区域
  978. /// </summary>
  979. /// <param name="direction">门方向</param>
  980. /// <param name="start">起始坐标, 单位: 像素</param>
  981. /// <param name="end">结束坐标, 单位: 像素</param>
  982. public DoorAreaInfo CreateDoorArea(DoorDirection direction, int start, int end)
  983. {
  984. var doorAreaInfo = new DoorAreaInfo();
  985. doorAreaInfo.Direction = direction;
  986. doorAreaInfo.Start = start;
  987. doorAreaInfo.End = end;
  988. //doorAreaInfo.CalcPosition(_roomPosition, _roomSize);
  989. CurrDoorConfigs.Add(doorAreaInfo);
  990. return doorAreaInfo;
  991. }
  992.  
  993. /// <summary>
  994. /// 检测门区域数据是否可以提交
  995. /// </summary>
  996. /// <param name="direction">门方向</param>
  997. /// <param name="start">起始坐标, 单位: 像素</param>
  998. /// <param name="end">结束坐标, 单位: 像素</param>
  999. /// <returns></returns>
  1000. public bool CheckDoorArea(DoorDirection direction, int start, int end)
  1001. {
  1002. foreach (var item in CurrDoorConfigs)
  1003. {
  1004. if (item.Direction == direction)
  1005. {
  1006. if (CheckValueCollision(item.Start, item.End, start, end))
  1007. {
  1008. return false;
  1009. }
  1010. }
  1011. }
  1012.  
  1013. return true;
  1014. }
  1015. /// <summary>
  1016. /// 检测门区域数据是否可以提交
  1017. /// </summary>
  1018. /// <param name="target">需要检测的门</param>
  1019. /// <param name="start">起始坐标, 单位: 像素</param>
  1020. /// <param name="end">结束坐标, 单位: 像素</param>
  1021. public bool CheckDoorArea(DoorAreaInfo target, int start, int end)
  1022. {
  1023. foreach (var item in CurrDoorConfigs)
  1024. {
  1025. if (item.Direction == target.Direction && item != target)
  1026. {
  1027. if (CheckValueCollision(item.Start, item.End, start, end))
  1028. {
  1029. return false;
  1030. }
  1031. }
  1032. }
  1033.  
  1034. return true;
  1035. }
  1036. private bool CheckValueCollision(float o1, float o2, float h1, float h2)
  1037. {
  1038. var size = GameConfig.TileCellSize;
  1039. return !(h2 < o1 - 3 * size || o2 + 3 * size < h1);
  1040. }
  1041.  
  1042. /// <summary>
  1043. /// 移除门区域数据
  1044. /// </summary>
  1045. public void RemoveDoorArea(DoorAreaInfo doorAreaInfo)
  1046. {
  1047. CurrDoorConfigs.Remove(doorAreaInfo);
  1048. }
  1049. //保存房间配置
  1050. private void SaveRoomInfoConfig()
  1051. {
  1052. //存入本地
  1053. var roomInfo = CurrRoomSplit.RoomInfo;
  1054. if (!HasTerrainError) //没有绘制错误
  1055. {
  1056. roomInfo.Size = new SerializeVector2(CurrRoomSize);
  1057. roomInfo.Position = new SerializeVector2(CurrRoomPosition);
  1058. }
  1059. else
  1060. {
  1061. roomInfo.Position = new SerializeVector2(CurrRoomPosition - Vector2I.One);
  1062. roomInfo.Size = new SerializeVector2(CurrRoomSize + new Vector2I(2, 2));
  1063. }
  1064.  
  1065. roomInfo.DoorAreaInfos.Clear();
  1066. roomInfo.DoorAreaInfos.AddRange(CurrDoorConfigs);
  1067. roomInfo.ClearCompletionDoorArea();
  1068. MapProjectManager.SaveRoomInfo(CurrRoomSplit);
  1069. }
  1070.  
  1071. //保存地块数据
  1072. public void SaveTileInfoConfig()
  1073. {
  1074. //存入本地
  1075. var tileInfo = CurrRoomSplit.TileInfo;
  1076. if (tileInfo.NavigationPolygon == null)
  1077. {
  1078. tileInfo.NavigationPolygon = new List<int[]>();
  1079. }
  1080. else
  1081. {
  1082. tileInfo.NavigationPolygon.Clear();
  1083. }
  1084. if (tileInfo.NavigationVertices == null)
  1085. {
  1086. tileInfo.NavigationVertices = new List<SerializeVector2>();
  1087. }
  1088. else
  1089. {
  1090. tileInfo.NavigationVertices.Clear();
  1091. }
  1092. var polygon = _editorTileMap.L_NavigationRegion.Instance.NavigationPolygon;
  1093. tileInfo.NavigationPolygon.AddRange(polygon.Polygons);
  1094. tileInfo.NavigationVertices.AddRange(polygon.Vertices.Select(v => new SerializeVector2(v)));
  1095. tileInfo.Floor.Clear();
  1096. tileInfo.Middle.Clear();
  1097. tileInfo.Top.Clear();
  1098.  
  1099. PushAutoLayerDataToList(AutoFloorLayer, _sourceId, tileInfo.Floor);
  1100. PushAutoLayerDataToList(AutoMiddleLayer, _sourceId, tileInfo.Middle);
  1101. PushAutoLayerDataToList(AutoTopLayer, _sourceId, tileInfo.Top);
  1102. MapProjectManager.SaveRoomTileInfo(CurrRoomSplit);
  1103. }
  1104.  
  1105. /// <summary>
  1106. /// 保存预设数据
  1107. /// </summary>
  1108. public void SavePreinstallConfig()
  1109. {
  1110. //存入本地
  1111. MapProjectManager.SaveRoomPreinstall(CurrRoomSplit);
  1112. }
  1113.  
  1114. /// <summary>
  1115. /// 获取相机中心点坐标
  1116. /// </summary>
  1117. public Vector2I GetCenterPosition()
  1118. {
  1119. var pos = ToLocal(MapEditorPanel.S_SubViewport.Instance.Size / 2);
  1120. return new Vector2I((int)pos.X, (int)pos.Y);
  1121. }
  1122. /// <summary>
  1123. /// 设置相机看向的点
  1124. /// </summary>
  1125. public void SetLookPosition(Vector2 pos)
  1126. {
  1127. SetMapPosition(-pos * Scale + MapEditorPanel.S_SubViewport.Instance.Size / 2);
  1128. //SetMapPosition(pos * Scale);
  1129. //SetMapPosition(pos + MapEditorPanel.S_SubViewport.Instance.Size / 2);
  1130. }
  1131. /// <summary>
  1132. /// 设置地图坐标
  1133. /// </summary>
  1134. public void SetMapPosition(Vector2 pos)
  1135. {
  1136. Position = pos;
  1137. MapEditorToolsPanel.SetToolTransform(pos, Scale);
  1138. }
  1139.  
  1140. //设置地图大小
  1141. private void SetMapSize(Vector2I size, bool refreshDoorTrans)
  1142. {
  1143. if (CurrRoomSize != size)
  1144. {
  1145. CurrRoomSize = size;
  1146.  
  1147. if (refreshDoorTrans)
  1148. {
  1149. MapEditorToolsPanel.SetDoorHoverToolTransform(CurrRoomPosition, CurrRoomSize);
  1150. }
  1151. }
  1152. }
  1153.  
  1154. private bool _hasPreviewImage = false;
  1155. private Action _previewFinish;
  1156. private int _previewIndex = 0;
  1157. private Vector2I _tempViewportSize;
  1158. private Vector2 _tempMapPos;
  1159. private Vector2 _tempMapScale;
  1160. private bool _tempAutoFloorLayer;
  1161. private bool _tempCustomFloorLayer;
  1162. private bool _tempAutoMiddleLayer;
  1163. private bool _tempCustomMiddleLayer;
  1164. private bool _tempAutoTopLayer;
  1165. private bool _tempCustomTopLayer;
  1166.  
  1167. private void RunSavePreviewImage(Action action)
  1168. {
  1169. if (_hasPreviewImage)
  1170. {
  1171. return;
  1172. }
  1173.  
  1174. _previewIndex = 0;
  1175. _previewFinish = action;
  1176. _hasPreviewImage = true;
  1177. //先截图, 将图像数据放置到 S_MapView2 节点上
  1178. var subViewport = MapEditorPanel.S_SubViewport.Instance;
  1179. var viewportTexture = subViewport.GetTexture();
  1180. var tex = ImageTexture.CreateFromImage(viewportTexture.GetImage());
  1181. var textureRect = MapEditorPanel.S_MapView2.Instance;
  1182. textureRect.Texture = tex;
  1183. textureRect.Visible = true;
  1184. //调整绘制视图大小
  1185. _tempViewportSize = subViewport.Size;
  1186. subViewport.Size = new Vector2I(GameConfig.PreviewImageSize, GameConfig.PreviewImageSize);
  1187. //调整tileMap
  1188. _tempMapPos = Position;
  1189. _tempMapScale = Scale;
  1190. //中心点
  1191. var pos = new Vector2(GameConfig.PreviewImageSize / 2f, GameConfig.PreviewImageSize / 2f);
  1192. if (CurrRoomSize.X == 0 && CurrRoomSize.Y == 0) //聚焦原点
  1193. {
  1194. Position = pos;
  1195. }
  1196. else //聚焦地图中心点
  1197. {
  1198. var tempPos = new Vector2(CurrRoomSize.X, CurrRoomSize.Y);
  1199. //var tempPos = new Vector2(CurrRoomSize.X + 2, CurrRoomSize.Y + 2);
  1200. var mapSize = tempPos * TileSet.TileSize;
  1201. var axis = Mathf.Max(mapSize.X, mapSize.Y);
  1202. var targetScale = GameConfig.PreviewImageSize / axis;
  1203. Scale = new Vector2(targetScale, targetScale);
  1204. Position = pos - (CurrRoomPosition + tempPos / 2f) * TileSet.TileSize * targetScale;
  1205. }
  1206. //隐藏工具栏
  1207. MapEditorToolsPanel.Visible = false;
  1208. //显示所有层级
  1209. _tempAutoFloorLayer = IsLayerEnabled(AutoFloorLayer);
  1210. _tempCustomFloorLayer = IsLayerEnabled(CustomFloorLayer);
  1211. _tempAutoMiddleLayer = IsLayerEnabled(AutoMiddleLayer);
  1212. _tempCustomMiddleLayer = IsLayerEnabled(CustomMiddleLayer);
  1213. _tempAutoTopLayer = IsLayerEnabled(AutoTopLayer);
  1214. _tempCustomTopLayer = IsLayerEnabled(CustomTopLayer);
  1215.  
  1216. SetLayerEnabled(AutoFloorLayer, true);
  1217. SetLayerEnabled(CustomFloorLayer, true);
  1218. SetLayerEnabled(AutoMiddleLayer, true);
  1219. SetLayerEnabled(CustomMiddleLayer, true);
  1220. SetLayerEnabled(AutoTopLayer, true);
  1221. SetLayerEnabled(CustomTopLayer, true);
  1222. }
  1223.  
  1224. private void OnFramePostDraw()
  1225. {
  1226. if (_hasPreviewImage)
  1227. {
  1228. _previewIndex++;
  1229. if (_previewIndex == 2)
  1230. {
  1231. var textureRect = MapEditorPanel.S_MapView2.Instance;
  1232. var texture = textureRect.Texture;
  1233. textureRect.Texture = null;
  1234. texture.Dispose();
  1235. textureRect.Visible = false;
  1236. //还原工具栏
  1237. MapEditorToolsPanel.Visible = true;
  1238. //还原层级显示
  1239. SetLayerEnabled(AutoFloorLayer, _tempAutoFloorLayer);
  1240. SetLayerEnabled(CustomFloorLayer, _tempCustomFloorLayer);
  1241. SetLayerEnabled(AutoMiddleLayer, _tempAutoMiddleLayer);
  1242. SetLayerEnabled(CustomMiddleLayer, _tempCustomMiddleLayer);
  1243. SetLayerEnabled(AutoTopLayer, _tempAutoTopLayer);
  1244. SetLayerEnabled(CustomTopLayer, _tempCustomTopLayer);
  1245.  
  1246. //保存预览图
  1247. var subViewport = MapEditorPanel.S_SubViewport.Instance;
  1248. var viewportTexture = subViewport.GetTexture();
  1249. var image = viewportTexture.GetImage();
  1250. image.Resize(GameConfig.PreviewImageSize, GameConfig.PreviewImageSize, Image.Interpolation.Nearest);
  1251. CurrRoomSplit.PreviewImage = ImageTexture.CreateFromImage(image);
  1252. MapProjectManager.SaveRoomPreviewImage(CurrRoomSplit, image);
  1253. //还原tileMap
  1254. Position = _tempMapPos;
  1255. Scale = _tempMapScale;
  1256. //还原绘制视图
  1257. subViewport.Size = _tempViewportSize;
  1258. _previewFinish();
  1259. _hasPreviewImage = false;
  1260. }
  1261. }
  1262. }
  1263. private void OnBakeFinished()
  1264. {
  1265. var polygonData = _editorTileMap.L_NavigationRegion.Instance.NavigationPolygon;
  1266. var polygons = polygonData.Polygons;
  1267. var vertices = polygonData.Vertices;
  1268. _polygonData = new Vector2[polygons.Count][];
  1269. for (var i = 0; i < polygons.Count; i++)
  1270. {
  1271. var polygon = polygons[i];
  1272. var v2Array = new Vector2[polygon.Length];
  1273. for (var j = 0; j < polygon.Length; j++)
  1274. {
  1275. v2Array[j] = vertices[polygon[j]];
  1276. }
  1277. _polygonData[i] = v2Array;
  1278. }
  1279. }
  1280. }