[System.Serializable]
public class MapComponent : MonoBehaviour {
// Private variables
// PUBLIC
// Base values
public GameObject tileBasicPrefab; // Basic prefab
public GameObject tileRoadPrefab; // Single road prefab
public GameObject mapPivot; // Parent object of tiles
public enum TileState {
Exist,
Deleted,
IsRoad,
};
// Grid
public float cellSize = 5f; // Distance between tiles
public int width = 10; // Width in tiles
public int height = 10; // Height in tiles
public GameObject[,] tilesGrid = new GameObject[0, 0]; // Array of tiles
public TileState[,] tilesState = new TileState[0, 0]; // Array of tiles state
public GridCoordinates localCoordinates; // Grid of local coordinates
public volatile bool isGenerated = false;// Is generation procedure executed
/**
* On tile deletion
* @param - <INT> height in tiles
* @param - <INT> width in tiles
* @param - <FLOAT> distance between cells in units
* @return - NONE
*/
public void DestroyTile(Vector3 tilePos)
{
}
/**
* Compare tile real state with state array. Replace if needed.
* @param - NONE
* @return - NONE
*/
public void Repair()
{
bool isWrongTile;
GameObject tile;
TileState tileState;
for (int x = 0; x < width; x++) {
for (int z = 0; z < height; z++) {
tile = (tilesGrid[x, z]);
tileState = tilesState[x, z];
switch (tileState) {
case TileState.Exist:
isWrongTile = ((tile == null) || (tile != tileBasicPrefab));
if (isWrongTile) {
if (tile != null) DestroyImmediate(tile);
CreateTile(x, z);
}
break;
case TileState.Deleted:
isWrongTile = ((tile != null));
if (isWrongTile) DestroyImmediate(tile);
break;
case TileState.IsRoad:
isWrongTile = ((tile == null) || (tile != tileRoadPrefab));
if (isWrongTile) {
if (tile != null) DestroyImmediate(tile);
CreateRoad(x, z);
}
break;
default: Debug.LogError("Wrong enum arg in MapComponent"); break;
}
}
}
}
/**
* Delete previous tilemap and creates new by received arguments
* @param - <INT> height in tiles
* @param - <INT> width in tiles
* @param - <FLOAT> distance between cells in units
* @return - NONE
*/
public void Generate(int new_height, int new_width, float new_cellSize)
{
// Set new variables
height = new_height;
width = new_width;
cellSize = new_cellSize;
// Clear map pivot and childrens if exist
if (mapPivot != null) {
isGenerated = false;
DestroyImmediate(mapPivot);
}
// Create new pivot
mapPivot = new GameObject("MapPivot");
mapPivot.transform.parent = this.transform;
// Create and generate new grid
localCoordinates = new GridCoordinates(width, height, cellSize);
tilesGrid = null;
tilesGrid = new GameObject[width, height];
tilesState = null;
tilesState = new TileState[width, height];
// Fill pivot with childrens by local grid
for (int x = 0; x < localCoordinates.GetWidth(); x++) {
for (int z = 0; z < localCoordinates.GetHeight(); z++) {
CreateTile(x, z);
}
}
// Return new pivot to old one position
mapPivot.transform.position = this.gameObject.transform.position;
mapPivot.transform.rotation = this.gameObject.transform.rotation;
// Mark as generated
isGenerated = true;
// Write variables
UnityEditor.EditorUtility.SetDirty(this);
}
private GameObject CreateTile(int x, int z)
{
// Get tile local position
Vector3 spawnPos = localCoordinates.GetCoordsOf(x, z);
// Create tile by prefab
GameObject tile = Instantiate(tileBasicPrefab, spawnPos, Quaternion.identity);
// Initialize tile
tile.AddComponent<MapTileComponent>().Init(this, x, z);
// Add tile to array
tilesGrid[x, z] = tile;
// Attach tile to map pivot
tile.transform.SetParent(mapPivot.transform);
// Set local coords
tile.transform.localPosition = spawnPos;
// Set tile state
tilesState[x, z] = TileState.Exist;
return tile;
}
private GameObject CreateRoad(int x, int z)
{
// Get tile local position
Vector3 spawnPos = localCoordinates.GetCoordsOf(x, z);
// Create tile by prefab
GameObject tile = Instantiate(tileRoadPrefab, spawnPos, Quaternion.identity);
// Initialize tile
tile.AddComponent<MapTileComponent>().Init(this, x, z);
// Add tile to array
tilesGrid[x, z] = tile;
// Attach tile to map pivot
tile.transform.SetParent(mapPivot.transform);
// Set local coords
tile.transform.localPosition = spawnPos;
// Set tile state
tilesState[x, z] = TileState.IsRoad;
return tile;
}
public void SwitchType(Vector3Int tilePos)
{
GameObject tile = (tilesGrid[tilePos.x, tilePos.z]);
TileState tileState = tilesState[tilePos.x, tilePos.z];
DestroyImmediate(tile);
switch (tileState) {
case TileState.Exist:
CreateRoad(tilePos.x, tilePos.z);
tilesState[tilePos.x, tilePos.z] = TileState.IsRoad;
break;
case TileState.IsRoad:
CreateTile(tilePos.x, tilePos.z);
tilesState[tilePos.x, tilePos.z] = TileState.Exist;
break;
default: Debug.LogError("Wrong enum arg in MapComponent"); break;
}
}
}