2023-08-22 19:08:45 +08:00
|
|
|
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;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
private Dictionary<int, int> _terrainTypeIndexDic = new Dictionary<int, int>();
|
|
|
|
|
|
|
|
|
|
public enum InfoMask
|
|
|
|
|
{
|
|
|
|
|
ShowCells = 1 << 0,
|
|
|
|
|
ShowTerritories = 1 << 1,
|
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
ShowAll = ShowCells | ShowTerritories
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GameObject GameObject => _gameObject;
|
|
|
|
|
public MapData MapData => _mapData;
|
|
|
|
|
public TerrainGridSystem TerrainGridSystem => _terrainGridSystem;
|
|
|
|
|
public MeshRenderer GroundMeshRenderer => _groundMeshRenderer;
|
|
|
|
|
|
|
|
|
|
public Dictionary<int, int> TerrainTypeIndexDic => _terrainTypeIndexDic;
|
|
|
|
|
|
|
|
|
|
public static Map Create(GameObject go, MapData data)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
const string ERROR_PRE = "Create Map Instance Error: {0}";
|
2023-08-22 19:08:45 +08:00
|
|
|
if (go == null)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
DebugUtil.LogError(ERROR_PRE ,"no GameObject");
|
2023-08-22 19:08:45 +08:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tgs = go.GetComponentInChildren<TerrainGridSystem>();
|
|
|
|
|
if (tgs == null)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
DebugUtil.LogError(ERROR_PRE , "GameObject has no TerrainGridSystem Component");
|
2023-08-22 19:08:45 +08:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var meshRenderer = tgs.GetComponent<MeshRenderer>();
|
|
|
|
|
if (meshRenderer == null)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
DebugUtil.LogError(ERROR_PRE ,"GameObject has no MeshRenderer Component");
|
2023-08-22 19:08:45 +08:00
|
|
|
//return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var map = new Map
|
|
|
|
|
{
|
|
|
|
|
_terrainGridSystem = tgs,
|
|
|
|
|
_gameObject = go,
|
|
|
|
|
_mapData = data,
|
2023-10-19 15:00:19 +08:00
|
|
|
_groundMeshRenderer = meshRenderer
|
2023-08-22 19:08:45 +08:00
|
|
|
};
|
|
|
|
|
map.ResetByData();
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Destroy()
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
Object.DestroyImmediate(GameObject);
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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<int> cellIndexs, bool show, Color color)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
for (var i = 0; i < cellIndexs.Count; i++)
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
|
|
|
|
var cellIndex = cellIndexs[i];
|
|
|
|
|
if (show)
|
|
|
|
|
{
|
|
|
|
|
_terrainGridSystem.CellSetColor(cellIndex, color);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_terrainGridSystem.CellSetColor(cellIndex, Color.clear);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetBlocksColor(List<Vector2Int> blocks, bool show, Color color)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
for (var i = 0; i < blocks.Count; i++)
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
|
|
|
|
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();
|
2023-10-19 15:00:19 +08:00
|
|
|
for (var i = 0; i < _mapData.BlocksData.Count; i++)
|
2023-08-22 19:08:45 +08:00
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
var isError = false;
|
2023-08-22 19:08:45 +08:00
|
|
|
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;
|
2023-10-19 15:00:19 +08:00
|
|
|
DebugUtil.LogError(" UpdateTGSByData error, blockIndex: {0} terrainTypeIndex: {1}", blockIndex, mapBlockData.TerrainTypeIndex);
|
2023-08-22 19:08:45 +08:00
|
|
|
}
|
|
|
|
|
var prop = isError ? TerrainTypeConfig.DefaultTerrainTypeProperty : terrainTypeProperties[mapBlockData.TerrainTypeIndex];
|
|
|
|
|
|
|
|
|
|
// Key: mapBlockData.TerrainTypeIndex Value: tgs.territories.index
|
|
|
|
|
if (!_terrainTypeIndexDic.ContainsKey(mapBlockData.TerrainTypeIndex))
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
var territory = tgs.TerritoryCreate(cellIndex);
|
2023-08-22 19:08:45 +08:00
|
|
|
_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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|