195 lines
7.2 KiB
C#
195 lines
7.2 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine.Tilemaps;
|
|
using UnityEngine;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Linq;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace GatherAndDefend.LevelEditor
|
|
{
|
|
[Serializable]
|
|
public class TilemapData : IEnumerable<TileData>
|
|
{
|
|
public const int INVISIBLE_LAYER = 6;
|
|
[SerializeField]
|
|
private string _key;
|
|
[SerializeField]
|
|
private List<TileData> _tiles;
|
|
[SerializeField]
|
|
private bool _isInvisible;
|
|
[SerializeField]
|
|
private bool _isCollidable;
|
|
[SerializeField]
|
|
private bool _isTrigger;
|
|
[SerializeField]
|
|
private int _renderOrder;
|
|
[SerializeField]
|
|
private string _renderLayer;
|
|
[SerializeField]
|
|
private Vector2 _position;
|
|
[SerializeField]
|
|
private Vector2 _scale;
|
|
|
|
public string Key => _key;
|
|
|
|
public void LoadToTilemap(Tilemap reference)
|
|
{
|
|
reference.transform.localPosition = _position;
|
|
reference.transform.localScale = _scale;
|
|
|
|
var rend = reference.GetComponent<TilemapRenderer>();
|
|
rend.sortingOrder = _renderOrder;
|
|
rend.sortingLayerName = _renderLayer;
|
|
if (_isInvisible) rend.gameObject.layer = INVISIBLE_LAYER;
|
|
if (_isCollidable)
|
|
{
|
|
var collision = rend.gameObject.AddComponent<TilemapCollider2D>();
|
|
collision.isTrigger = _isTrigger;
|
|
}
|
|
|
|
foreach (TileData data in _tiles)
|
|
{
|
|
reference.SetTile(data.Position, data.Tile);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// saves a tilemap into the level object
|
|
/// </summary>
|
|
/// <param name="reference"></param>
|
|
/// <returns>the bounds of the tilemap</returns>
|
|
public void SaveFromTilemap(Tilemap reference)
|
|
{
|
|
_key = reference.name;
|
|
if (_isCollidable = reference.GetComponent<TilemapCollider2D>())
|
|
{
|
|
_isTrigger = reference.GetComponent<TilemapCollider2D>().isTrigger;
|
|
}
|
|
|
|
_isInvisible = reference.gameObject.layer == INVISIBLE_LAYER;
|
|
_renderLayer = reference.GetComponent<TilemapRenderer>().sortingLayerName;
|
|
_renderOrder = reference.GetComponent<TilemapRenderer>().sortingOrder;
|
|
_position = reference.transform.localPosition;
|
|
_scale = reference.transform.localScale;
|
|
|
|
_tiles = new List<TileData>();
|
|
|
|
BoundsInt bounds = reference.cellBounds;
|
|
for (int i = bounds.xMin; i <= bounds.xMax; i++)
|
|
{
|
|
for (int j = bounds.yMin; j <= bounds.yMax; j++)
|
|
{
|
|
Vector3Int position = new Vector3Int(i, j);
|
|
TileBase tile = reference.GetTile(position);
|
|
if (!tile) continue;
|
|
var tileData = new TileData(position, tile);
|
|
_tiles.Add(tileData);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// returns a dictionary representation of the tilemap
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Dictionary<string, object> ToDictionary()
|
|
{
|
|
return new Dictionary<string, object>()
|
|
{
|
|
{nameof(_key), _key },
|
|
{nameof(_isInvisible), _isInvisible },
|
|
{nameof(_isCollidable), _isCollidable },
|
|
{nameof(_isTrigger), _isTrigger },
|
|
{nameof(_renderOrder), _renderOrder },
|
|
{nameof(_renderLayer), _renderLayer },
|
|
{nameof(_position), new float[]{_position.x, _position.y, 0 } },
|
|
{nameof(_scale), new float[]{ _scale.x, _scale.y, 0 } },
|
|
{nameof(_tiles), _tiles.FindAll(x => !(x.Tile is LevelTile))
|
|
.Select(x => new Dictionary<string, object>() {
|
|
{nameof(x.Position), new float[] { x.Position.x, x.Position.y, x.Position.z } },
|
|
{nameof(x.Tile), x.Tile.name } }).ToArray() }
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// builds a tilemap from a dictionary representation (from the save file)
|
|
/// </summary>
|
|
/// <param name="dict"></param>
|
|
/// <returns></returns>
|
|
public static Tilemap FromDictionary(Dictionary<string, object> dict)
|
|
{
|
|
//get all tilemap data
|
|
var key = dict[nameof(_key)].ToString();
|
|
var invisible = dict[nameof(_isInvisible)].ToBool();
|
|
var collidable = dict[nameof(_isCollidable)].ToBool();
|
|
var trigger = dict[nameof(_isTrigger)].ToBool();
|
|
var renderOrder = dict[nameof(_renderOrder)].ToInt();
|
|
var renderLayer = dict[nameof(_renderLayer)].ToString();
|
|
var position = dict[nameof(_position)].ToVector3();
|
|
var scale = dict[nameof(_scale)].ToVector3();
|
|
var tiles = dict[nameof(_tiles)];
|
|
|
|
//get grid
|
|
var grid = GameObject.FindObjectOfType<Grid>();
|
|
if (!grid)
|
|
{
|
|
var levelMgrScript = GameObject.FindObjectOfType<LevelManagerScript>();
|
|
grid = new GameObject("Grid").AddComponent<Grid>();
|
|
grid.transform.SetParent(levelMgrScript.transform.parent);
|
|
}
|
|
|
|
//get tilemap by name
|
|
var tilemap = grid.GetComponentInChildren<Tilemap>(key);
|
|
TilemapRenderer renderer;
|
|
if (!tilemap)
|
|
{
|
|
tilemap = new GameObject(key).AddComponent<Tilemap>();
|
|
tilemap.tileAnchor = Vector3.zero;
|
|
tilemap.gameObject.AddComponent<TilemapRenderer>();
|
|
tilemap.transform.SetParent(grid.transform);
|
|
}
|
|
tilemap.transform.localPosition = position;
|
|
tilemap.transform.localScale = scale;
|
|
renderer = tilemap.GetComponent<TilemapRenderer>();
|
|
|
|
//populate tilemap according to specs
|
|
renderer.sortingOrder = renderOrder;
|
|
renderer.sortingLayerName = renderLayer;
|
|
|
|
if (invisible) tilemap.gameObject.layer = INVISIBLE_LAYER;
|
|
if (collidable)
|
|
{
|
|
tilemap.gameObject.AddComponent<TilemapCollider2D>().isTrigger = trigger;
|
|
}
|
|
|
|
//populate tilemaps with non-LevelTile tiles
|
|
foreach (var tileObj in tiles as IEnumerable)
|
|
{
|
|
var tileDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(tileObj.ToString());
|
|
var tileName = tileDict["Tile"].ToString();
|
|
var tile = Database.Instance.ScriptableObjects[tileName];
|
|
|
|
var tilePos = tileDict["Position"].ToVector3();
|
|
|
|
tilemap.SetTile(Vector3Int.RoundToInt(tilePos), tile as TileBase);
|
|
}
|
|
|
|
return tilemap;
|
|
}
|
|
|
|
public IEnumerator<TileData> GetEnumerator()
|
|
{
|
|
return _tiles.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return _tiles.GetEnumerator();
|
|
}
|
|
|
|
public TilemapData()
|
|
{
|
|
_tiles = new List<TileData>();
|
|
}
|
|
}
|
|
} |