using System.Collections.Generic; using TGS; using UnityEngine; namespace Gameplay { public partial class Map { private TerrainGridSystem _terrainGridSystem; private GameObject _gameObject; private MapData _mapData; private MeshRenderer _groundMeshRenderer; private int _showInfoMask; private Dictionary _terrainTypeIndexDic = new Dictionary(); public enum InfoMask { ShowCells = 1 << 0, ShowTerritories = 1 << 1, ShowAll = ShowCells | ShowTerritories } private Map() { } public GameObject GameObject => _gameObject; public MapData MapData => _mapData; public TerrainGridSystem TerrainGridSystem => _terrainGridSystem; public MeshRenderer GroundMeshRenderer => _groundMeshRenderer; public Dictionary TerrainTypeIndexDic => _terrainTypeIndexDic; public static Map Create(GameObject go, MapData data) { const string ERROR_PRE = "Create Map Instance Error: {0}"; if (go == null) { DebugUtil.LogError(ERROR_PRE ,"no GameObject"); return null; } var tgs = go.GetComponentInChildren(); if (tgs == null) { DebugUtil.LogError(ERROR_PRE , "GameObject has no TerrainGridSystem Component"); return null; } var meshRenderer = tgs.GetComponent(); if (meshRenderer == null) { DebugUtil.LogError(ERROR_PRE ,"GameObject has no MeshRenderer Component"); //return null; } var map = new Map { _terrainGridSystem = tgs, _gameObject = go, _mapData = data, _groundMeshRenderer = meshRenderer }; map.ResetByData(); return map; } public void Destroy() { Object.DestroyImmediate(GameObject); } public void SetGroundTexture(Texture2D texture) { _terrainGridSystem.canvasTexture = texture; } public void SetGroundTexture(Material material) { _groundMeshRenderer.material = material; } public void SetGroundSortingLayer(int order) { _groundMeshRenderer.sortingOrder = order; } public MapBlockData GetBlockData(Vector2Int position) { return _mapData.GetBlockData(position); } public MapBlockData GetBlockData(int cellIndex) { var vec2Pos = TGSCellIndex2BlockPosition(cellIndex); return GetBlockData(vec2Pos); } public bool CheckPosition(Vector2Int position) { return _mapData.CheckPosition(position); } public string GetMapFileName() { return _mapData.name; } public void SetTerrainType(int tgsCellIndex, int terrainTypeIndex) { var blockIndex = TGSCellIndex2BlockIndex(tgsCellIndex); _mapData.SetBlockTerrainType(blockIndex, terrainTypeIndex); } public Vector3 BlockPosition2WorldPosition(Vector2Int blockPosition) { return _terrainGridSystem.CellGetPosition(BlockPosition2TGSCellIndex(blockPosition)); } public int BlockPosition2TGSCellIndex(Vector2Int blockPosition) { return BlockIndex2TGSCellIndex(_mapData.Position2BlockIndex(blockPosition)); } public Vector3 TGSCellIndex2WorldPosition(int cellIndex) { return _terrainGridSystem.CellGetPosition(cellIndex); } public bool WorldPosition2BlockPosition(Vector3 worldPosition, out Vector2Int position) { if (WorldPosition2BlockIndex(worldPosition, out var index)) { position = _mapData.BlockIndex2Position(index); return true; } position = Vector2Int.zero; return false; } public Vector2Int TGSCellIndex2BlockPosition(int cellIndex) { return _mapData.BlockIndex2Position(TGSCellIndex2BlockIndex(cellIndex)); } public Cell GetCellByWorldPos(Vector3 worldPos) { return _terrainGridSystem.CellGetAtPosition(worldPos, true); } public bool WorldPosition2TGSCellIndex(Vector3 worldPosition, out int index) { var cell = _terrainGridSystem.CellGetAtPosition(worldPosition, true); if (cell == null) { index = -1; return false; } index = cell.index; return true; } public bool WorldPosition2BlockIndex(Vector3 worldPosition, out int index) { if (WorldPosition2TGSCellIndex(worldPosition, out var tgsCellIndex)) { index = TGSCellIndex2BlockIndex(tgsCellIndex); return true; } index = -1; return false; } public int BlockIndex2TGSCellIndex(int blockIndex) { return blockIndex; } public int TGSCellIndex2BlockIndex(int tgsCellIndex) { return tgsCellIndex; } public void SetRegionColor(int regionId, bool show, Color color) { if (regionId >= 0) { var region = _mapData.GetRegion(regionId); SetBlocksColor(region.positions, show, color); } } public void SetRegionColor(int regionId, bool show, string RGBAColor) { if (regionId >= 0) { var region = _mapData.GetRegion(regionId); SetBlocksColor(region.positions, show, MapUtils.GetRGBAColor(RGBAColor)); } } public void ShowInfo(int mask) { _showInfoMask = mask; UpdateShowInfo(); } public void ShowInfo(InfoMask mask, bool show) { if (show) { _showInfoMask = _showInfoMask | (int)mask; } else { _showInfoMask = _showInfoMask & ~(int)mask; } UpdateShowInfo(); } public void SetBlockColor(int cellIndex, bool show, Color color) { if (show) { _terrainGridSystem.CellSetColor(cellIndex, color); } else { _terrainGridSystem.CellSetColor(cellIndex, Color.clear); } } public void SetBlocksColor(List cellIndexs, bool show, Color color) { for (var i = 0; i < cellIndexs.Count; i++) { var cellIndex = cellIndexs[i]; if (show) { _terrainGridSystem.CellSetColor(cellIndex, color); } else { _terrainGridSystem.CellSetColor(cellIndex, Color.clear); } } } public void SetBlocksColor(List blocks, bool show, Color color) { for (var i = 0; i < blocks.Count; i++) { var cellIndex = BlockPosition2TGSCellIndex(blocks[i]); if (show) { _terrainGridSystem.CellSetColor(cellIndex, color); } else { _terrainGridSystem.CellSetColor(cellIndex, Color.clear); } } } private void UpdateShowInfo() { _terrainGridSystem.showCells = (_showInfoMask & (int)InfoMask.ShowCells) != 0; _terrainGridSystem.colorizeTerritories = (_showInfoMask & (int)InfoMask.ShowTerritories) != 0; } private int Region2TGSTerritoryIndex(int regionId) { return regionId; } private void ResetByData() { GameObject.name = _mapData.name; _terrainGridSystem?.TerritoryDestroyAll(); _terrainTypeIndexDic.Clear(); for (var i = 0; i < _mapData.BlocksData.Count; i++) { var blockData = _mapData.BlocksData[i]; if (!blockData.IsDefaultTerrainType()) { UpdateTGSByData(_terrainGridSystem, i, blockData); } _runTimeTerrainProperty.Add(new RuntimeBlockProperty(blockData.GetTerrainTypeProperty())); } ShowInfo(0); } private void UpdateTGSByData(TerrainGridSystem tgs, int blockIndex, MapBlockData mapBlockData) { var isError = false; if (mapBlockData.IsDefaultTerrainType()) { isError = true; DebugUtil.LogG($"UpdateTGSByData error, blockIndex: {blockIndex} is default terrain type"); } var cellIndex = BlockIndex2TGSCellIndex(blockIndex); var terrainTypeProperties = TerrainTypeConfig.TerrainTypeProperties; if (mapBlockData.TerrainTypeIndex >= terrainTypeProperties.Count) { isError = true; DebugUtil.LogError(" UpdateTGSByData error, blockIndex: {0} terrainTypeIndex: {1}", blockIndex, mapBlockData.TerrainTypeIndex); } var prop = isError ? TerrainTypeConfig.DefaultTerrainTypeProperty : terrainTypeProperties[mapBlockData.TerrainTypeIndex]; // Key: mapBlockData.TerrainTypeIndex Value: tgs.territories.index if (!_terrainTypeIndexDic.ContainsKey(mapBlockData.TerrainTypeIndex)) { var territory = tgs.TerritoryCreate(cellIndex); _terrainTypeIndexDic.Add(mapBlockData.TerrainTypeIndex, _terrainTypeIndexDic.Count); territory.fillColor = prop.Color; } tgs.CellSetTerritory(cellIndex, _terrainTypeIndexDic[mapBlockData.TerrainTypeIndex]); tgs.CellSetCanCross(cellIndex, !prop.emptyBlock); } private void UpdateTGSByData(TerrainGridSystem tgs, Vector2Int position, RuntimeBlockProperty runtimeBlockProperty) { var cellIndex = BlockPosition2TGSCellIndex(position); tgs.CellSetCanCross(cellIndex, !runtimeBlockProperty.isEmptyBlock); tgs.CellSetCrossLevel(cellIndex, runtimeBlockProperty.crossLevel); // SetBlockColor(cellIndex, true, runtimeBlockProperty.canPass ? new Color(0, 0, 0, 0) : new Color(1, 0, 0, 0.5f)); } } }