finish to hijack update loop + serialization
problem : tiles dont have an update loop, neither do they have a start / destroy method solution : finished working on a way to create a custom start/update/destroy pipeline for the projects custom tiles. it's using LevelManagerScript as to Update. note : also created a database and a start of serialization system so we can save and load stuff.
This commit is contained in:
parent
d10677db6d
commit
ef8a70aba4
31
Assets/Database.asset
Normal file
31
Assets/Database.asset
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 8442e6f4be8799444b7bd9703a5c88dc, type: 3}
|
||||||
|
m_Name: Database
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
database:
|
||||||
|
_prefabs:
|
||||||
|
- {fileID: 6962989255644195630, guid: 6cd87b398e7a0e94580f4fcbe2fd310a, type: 3}
|
||||||
|
- {fileID: 6962989255644195630, guid: 377c7275c0001cc47a6b8926ac57d573, type: 3}
|
||||||
|
- {fileID: 6962989255644195630, guid: 869a03bba705e8d4485aa73daad773dc, type: 3}
|
||||||
|
- {fileID: 6962989255644195630, guid: 9b40c232eddfd1b469bea688e3c970c0, type: 3}
|
||||||
|
- {fileID: 4052934186652138539, guid: 8560e1f66d452b543a705c8a0f3e22fa, type: 3}
|
||||||
|
- {fileID: 3814095509541806390, guid: 9527f3a1482b90a48bb6c62acc70f986, type: 3}
|
||||||
|
_scriptableObjects:
|
||||||
|
- {fileID: 11400000, guid: 4aaf448680c7f8a438a9a5861c622a55, type: 2}
|
||||||
|
- {fileID: 11400000, guid: e715669e1ed4b294c82d07ac011e89bb, type: 2}
|
||||||
|
- {fileID: 11400000, guid: a6e34739c9325da4cac4fbaea30d052c, type: 2}
|
||||||
|
- {fileID: 11400000, guid: d37561e153d6a6448a03839488fdec5e, type: 2}
|
||||||
|
_folders:
|
||||||
|
- {fileID: 102900000, guid: f3dee7994db941e47b9445cb464c69a9, type: 3}
|
||||||
|
- {fileID: 102900000, guid: 4f8284570682f8f4c954e446b35ea0ae, type: 3}
|
||||||
|
- {fileID: 102900000, guid: 0ca30b5ca281be24bb62d7e48cc2bec8, type: 3}
|
||||||
8
Assets/Database.asset.meta
Normal file
8
Assets/Database.asset.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a4bf69f8ff62be443a8177430eb8e28a
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -121,7 +121,7 @@ Important considerations :
|
|||||||
foreach (TilemapData tilemapData in targ.Level)
|
foreach (TilemapData tilemapData in targ.Level)
|
||||||
{
|
{
|
||||||
var tilemap = new GameObject(tilemapData.Key).AddComponent<Tilemap>();
|
var tilemap = new GameObject(tilemapData.Key).AddComponent<Tilemap>();
|
||||||
var rend = tilemap.gameObject.AddComponent<TilemapRenderer>();
|
tilemap.gameObject.AddComponent<TilemapRenderer>();
|
||||||
tilemapData.LoadToTilemap(tilemap);
|
tilemapData.LoadToTilemap(tilemap);
|
||||||
tilemap.transform.SetParent(targ.transform);
|
tilemap.transform.SetParent(targ.transform);
|
||||||
}
|
}
|
||||||
|
|||||||
110
Assets/Scripts/DatabaseSO.cs
Normal file
110
Assets/Scripts/DatabaseSO.cs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
[CustomEditor(typeof(DatabaseSO))]
|
||||||
|
public class DatabaseEditor : Editor
|
||||||
|
{
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
DrawDefaultInspector();
|
||||||
|
|
||||||
|
if (GUILayout.Button("fetch assets"))
|
||||||
|
{
|
||||||
|
var targ = target as DatabaseSO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var folder in targ.Folders)
|
||||||
|
{
|
||||||
|
var path = AssetDatabase.GetAssetPath(folder);
|
||||||
|
foreach (var file in GetAllPaths(path))
|
||||||
|
{
|
||||||
|
var scriptableObject = AssetDatabase.LoadAssetAtPath<ScriptableObject>(file);
|
||||||
|
if (scriptableObject && !Database.Instance.ScriptableObjects.Contains(scriptableObject))
|
||||||
|
{
|
||||||
|
Database.Instance.ScriptableObjects.Add(scriptableObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(file);
|
||||||
|
if (prefab && !Database.Instance.Prefabs.Contains(prefab))
|
||||||
|
{
|
||||||
|
Database.Instance.Prefabs.Add(prefab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] GetAllPaths(string target)
|
||||||
|
{
|
||||||
|
var files = Directory.GetFiles(target).ToList();
|
||||||
|
foreach (var dir in Directory.GetDirectories(target))
|
||||||
|
{
|
||||||
|
files.AddRange(GetAllPaths(dir));
|
||||||
|
}
|
||||||
|
return files.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class Database : Singleton<Database>
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class DataList<T> : IEnumerable<T> where T : UnityEngine.Object
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
private List<T> elements;
|
||||||
|
public DataList() => elements = new List<T>();
|
||||||
|
|
||||||
|
public T this[string key] => elements.Find(x => x.name == key);
|
||||||
|
|
||||||
|
public void Add(T element) => elements.Add(element);
|
||||||
|
|
||||||
|
|
||||||
|
public IEnumerator<T> GetEnumerator()
|
||||||
|
{
|
||||||
|
return elements.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return elements.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator DataList<T>(List<T> list) => new DataList<T>() { elements = list };
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private List<GameObject> _prefabs;
|
||||||
|
[SerializeField]
|
||||||
|
private List<ScriptableObject> _scriptableObjects;
|
||||||
|
|
||||||
|
public DataList<GameObject> Prefabs => _prefabs;
|
||||||
|
public DataList<ScriptableObject> ScriptableObjects => _scriptableObjects;
|
||||||
|
|
||||||
|
public Database()
|
||||||
|
{
|
||||||
|
_prefabs = new List<GameObject>();
|
||||||
|
_scriptableObjects = new List<ScriptableObject>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CreateAssetMenu(menuName = "Gather And Defend/Database")]
|
||||||
|
public class DatabaseSO : ScriptableObject
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
private Database database = Database.Instance;
|
||||||
|
[Header("Editor section")]
|
||||||
|
[SerializeField]
|
||||||
|
private List<DefaultAsset> _folders;
|
||||||
|
|
||||||
|
public List<DefaultAsset> Folders => _folders;
|
||||||
|
}
|
||||||
11
Assets/Scripts/DatabaseSO.cs.meta
Normal file
11
Assets/Scripts/DatabaseSO.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8442e6f4be8799444b7bd9703a5c88dc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: b6a96c7c65795c94abf54a62adbf5c38, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,18 +1,18 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using static Extensions;
|
||||||
|
|
||||||
public class Entity : MonoBehaviour
|
public class Entity : LevelObject
|
||||||
{
|
{
|
||||||
|
|
||||||
//Attribut
|
//Attribut
|
||||||
[SerializeField]
|
[SerializeField, LevelSerialize]
|
||||||
private int _hp;
|
private int _hp;
|
||||||
[SerializeField]
|
[SerializeField, LevelSerialize]
|
||||||
private float _speed;
|
private float _speed;
|
||||||
[SerializeField]
|
[SerializeField, LevelSerialize]
|
||||||
private int _attack_damage;
|
private int _attack_damage;
|
||||||
[SerializeField]
|
[SerializeField, LevelSerialize]
|
||||||
private float _attack_speed;
|
private float _attack_speed;
|
||||||
private float _attack_speed_wait = 0f;
|
private float _attack_speed_wait = 0f;
|
||||||
|
|
||||||
@ -64,15 +64,37 @@ public class Entity : MonoBehaviour
|
|||||||
set { _enemy = value; }
|
set { _enemy = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region [LevelManager code]
|
||||||
|
public override bool Equals(ILevelObject other)
|
||||||
|
{
|
||||||
|
if (!(other is Entity)) return false;
|
||||||
|
var otherEntity = other as Entity;
|
||||||
|
return otherEntity._hp == _hp
|
||||||
|
&& otherEntity.Position == Position
|
||||||
|
&& otherEntity.Name == Name
|
||||||
|
&& otherEntity._speed == _speed
|
||||||
|
&& otherEntity._attack_speed == _attack_speed
|
||||||
|
&& otherEntity._attack_damage == _attack_damage;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
public override void LevelDestroy()
|
||||||
void Start()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
public override void LevelStart()
|
||||||
{
|
{
|
||||||
|
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
public override void LevelUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Dictionary<string, object> ToDictionary()
|
||||||
|
{
|
||||||
|
return Extensions.ToDictionary(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
#endif
|
||||||
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace GatherAndDefend.LevelEditor
|
namespace GatherAndDefend.LevelEditor
|
||||||
@ -6,8 +9,10 @@ namespace GatherAndDefend.LevelEditor
|
|||||||
[RequireComponent(typeof(Grid))]
|
[RequireComponent(typeof(Grid))]
|
||||||
public class LevelEditor : MonoBehaviour
|
public class LevelEditor : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private DefaultAsset _path;
|
private DefaultAsset _path;
|
||||||
|
#endif
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private Level _level;
|
private Level _level;
|
||||||
public Level Level
|
public Level Level
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Unity.Plastic.Newtonsoft.Json.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
[CreateAssetMenu(menuName = "Gather And Defend/Spawner Tile")]
|
[CreateAssetMenu(menuName = "Gather And Defend/Spawner Tile")]
|
||||||
public class SpawnerTile : LevelTile
|
public class SpawnerTile : LevelTile
|
||||||
{
|
{
|
||||||
[SerializeField]
|
|
||||||
private Sprite _sprite;
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private GameObject _prefab;
|
private GameObject _prefab;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
@ -32,7 +32,7 @@ public class SpawnerTile : LevelTile
|
|||||||
{
|
{
|
||||||
if (!_spawnOnStart) return;
|
if (!_spawnOnStart) return;
|
||||||
var instance = Instantiate(_prefab, Position, Quaternion.identity);
|
var instance = Instantiate(_prefab, Position, Quaternion.identity);
|
||||||
instance.transform.SetParent(LevelManager.Instance.transform);
|
instance.transform.SetParent(LevelManager.Instance.LevelTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LevelUpdate()
|
public override void LevelUpdate()
|
||||||
@ -42,6 +42,10 @@ public class SpawnerTile : LevelTile
|
|||||||
|
|
||||||
_spawnCounter = 0;
|
_spawnCounter = 0;
|
||||||
var instance = Instantiate(_prefab, Position, Quaternion.identity);
|
var instance = Instantiate(_prefab, Position, Quaternion.identity);
|
||||||
instance.transform.SetParent(LevelManager.Instance.transform);
|
instance.transform.SetParent(LevelManager.Instance.LevelTransform);
|
||||||
|
}
|
||||||
|
public override Dictionary<string, object> ToDictionary()
|
||||||
|
{
|
||||||
|
return Extensions.ToDictionary(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,9 +1,45 @@
|
|||||||
using UnityEngine;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BindingFlags = System.Reflection.BindingFlags;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
|
public enum LevelObjectType { GameObject, Tile }
|
||||||
public static bool Approximately(this Vector3 vect, Vector3 other)
|
public static bool Approximately(this Vector3 vect, Vector3 other)
|
||||||
{
|
{
|
||||||
return Mathf.Approximately(Vector3.Distance(vect, other), 0);
|
return Mathf.Approximately(Vector3.Distance(vect, other), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||||
|
public class LevelSerializeAttribute : Attribute { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// turns an object into a serializable dictionary
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Dictionary<string, object> ToDictionary<T>(this T obj) where T : ILevelObject
|
||||||
|
{
|
||||||
|
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||||
|
var toReturn = new Dictionary<string, object>();
|
||||||
|
var type = obj.GetType();
|
||||||
|
|
||||||
|
foreach (var field in type.GetFields(flags))
|
||||||
|
{
|
||||||
|
if (!Attribute.IsDefined(field, typeof(LevelSerializeAttribute))) continue;
|
||||||
|
toReturn[field.Name] = field.GetValue(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var property in type.GetProperties(flags))
|
||||||
|
{
|
||||||
|
if (!Attribute.IsDefined(property, typeof(LevelSerializeAttribute))) continue;
|
||||||
|
toReturn[property.Name] = property.GetValue(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj is LevelObject) toReturn[nameof(LevelObjectType)] = LevelObjectType.GameObject;
|
||||||
|
else toReturn[nameof(LevelObjectType)] = LevelObjectType.Tile;
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,10 +1,13 @@
|
|||||||
using UnityEngine;
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
public interface ILevelObject
|
public interface ILevelObject
|
||||||
{
|
{
|
||||||
|
string Name { get; }
|
||||||
Vector3 Position { get; }
|
Vector3 Position { get; }
|
||||||
void LevelUpdate();
|
void LevelUpdate();
|
||||||
void LevelStart();
|
void LevelStart();
|
||||||
void LevelDestroy();
|
void LevelDestroy();
|
||||||
bool Equals(ILevelObject other);
|
bool Equals(ILevelObject other);
|
||||||
|
Dictionary<string, object> ToDictionary();
|
||||||
}
|
}
|
||||||
@ -1,79 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
public class LevelManager : SingletonBehaviour<LevelManager>
|
|
||||||
{
|
|
||||||
public event Action<ILevelObject> Added;
|
|
||||||
public event Action<ILevelObject> Removed;
|
|
||||||
|
|
||||||
private List<ILevelObject> toAdd;
|
|
||||||
private List<ILevelObject> toRemove;
|
|
||||||
private List<ILevelObject> levelObjects;
|
|
||||||
public LevelManager()
|
|
||||||
{
|
|
||||||
toAdd = new List<ILevelObject>();
|
|
||||||
toRemove = new List<ILevelObject>();
|
|
||||||
levelObjects = new List<ILevelObject>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(ILevelObject levelObject)
|
|
||||||
{
|
|
||||||
if (levelObjects.Exists(obj => obj.Equals(levelObject))) return;
|
|
||||||
toAdd.Add(levelObject);
|
|
||||||
}
|
|
||||||
public void Remove(ILevelObject levelObject)
|
|
||||||
{
|
|
||||||
if (!levelObjects.Contains(levelObject)) return;
|
|
||||||
toRemove.Add(levelObject);
|
|
||||||
}
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
toAdd.Clear();
|
|
||||||
toRemove.Clear();
|
|
||||||
levelObjects.Clear();
|
|
||||||
}
|
|
||||||
public T Get<T>(Func<T, bool> predicate = null) where T : ILevelObject
|
|
||||||
{
|
|
||||||
if (predicate == null) predicate = (t) => true;
|
|
||||||
return (T)levelObjects.Find(t => t is T t1 && predicate(t1));
|
|
||||||
}
|
|
||||||
public List<T> GetAll<T>(Func<T, bool> predicate = null) where T : ILevelObject
|
|
||||||
{
|
|
||||||
if (predicate == null) predicate = (t) => true;
|
|
||||||
List<T> ret = new List<T>();
|
|
||||||
foreach (var t in levelObjects) if (t is T t1 && predicate(t1)) ret.Add(t1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count<T>(Func<T, bool> predicate = null) where T : ILevelObject
|
|
||||||
{
|
|
||||||
return GetAll(predicate).Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Has<T>(Func<T, bool> predicate = null)
|
|
||||||
{
|
|
||||||
if (predicate == null) predicate = (t) => true;
|
|
||||||
return levelObjects.Exists(t => t is T && predicate((T)t));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
levelObjects.ForEach(obj => obj.LevelUpdate());
|
|
||||||
|
|
||||||
toAdd.ForEach(tile =>
|
|
||||||
{
|
|
||||||
levelObjects.Add(tile);
|
|
||||||
Added?.Invoke(tile);
|
|
||||||
tile.LevelStart();
|
|
||||||
});
|
|
||||||
toAdd.Clear();
|
|
||||||
|
|
||||||
toRemove.ForEach(tile =>
|
|
||||||
{
|
|
||||||
levelObjects.Remove(tile);
|
|
||||||
Removed?.Invoke(tile);
|
|
||||||
tile.LevelDestroy();
|
|
||||||
});
|
|
||||||
toRemove.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
117
Assets/Scripts/LevelManager/LevelManagerScript.cs
Normal file
117
Assets/Scripts/LevelManager/LevelManagerScript.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Unity.Plastic.Newtonsoft.Json;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class LevelManager : Singleton<LevelManager>
|
||||||
|
{
|
||||||
|
public delegate void LevelAction(ILevelObject levelObject);
|
||||||
|
public delegate bool LevelPredicate<T>(T levelObject) where T : ILevelObject;
|
||||||
|
public event LevelAction Added;
|
||||||
|
public event LevelAction Removed;
|
||||||
|
|
||||||
|
private readonly List<ILevelObject> toAdd;
|
||||||
|
private readonly List<ILevelObject> toRemove;
|
||||||
|
private readonly List<ILevelObject> levelObjects;
|
||||||
|
|
||||||
|
public Transform LevelTransform
|
||||||
|
{
|
||||||
|
get;private set;
|
||||||
|
}
|
||||||
|
public LevelManager()
|
||||||
|
{
|
||||||
|
toAdd = new List<ILevelObject>();
|
||||||
|
toRemove = new List<ILevelObject>();
|
||||||
|
levelObjects = new List<ILevelObject>();
|
||||||
|
|
||||||
|
var mgrScript = Object.FindObjectOfType<LevelManagerScript>();
|
||||||
|
if (!mgrScript) mgrScript = new GameObject(nameof(LevelManager)).AddComponent<LevelManagerScript>();
|
||||||
|
LevelTransform = mgrScript.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(ILevelObject levelObject)
|
||||||
|
{
|
||||||
|
toAdd.Add(levelObject);
|
||||||
|
}
|
||||||
|
public void Remove(ILevelObject levelObject)
|
||||||
|
{
|
||||||
|
toRemove.Add(levelObject);
|
||||||
|
}
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
toAdd.Clear();
|
||||||
|
toRemove.Clear();
|
||||||
|
levelObjects.Clear();
|
||||||
|
}
|
||||||
|
public T Get<T>(LevelPredicate<T> predicate = null) where T : ILevelObject
|
||||||
|
{
|
||||||
|
if (predicate == null) predicate = (generic) => true;
|
||||||
|
return (T)levelObjects.Find(levelObject => levelObject is T generic && predicate(generic));
|
||||||
|
}
|
||||||
|
public List<T> GetAll<T>(LevelPredicate<T> predicate = null) where T : ILevelObject
|
||||||
|
{
|
||||||
|
if (predicate == null) predicate = (generic) => true;
|
||||||
|
List<T> ret = new();
|
||||||
|
foreach (var levelObject in levelObjects) if (levelObject is T generic && predicate(generic)) ret.Add(generic);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count<T>(LevelPredicate<T> predicate = null) where T : ILevelObject
|
||||||
|
{
|
||||||
|
return GetAll(predicate).Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Has<T>(LevelPredicate<T> predicate = null) where T : ILevelObject
|
||||||
|
{
|
||||||
|
if (predicate == null) predicate = (generic) => true;
|
||||||
|
return levelObjects.Exists(levelObject => levelObject is T generic && predicate(generic));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateLevel()
|
||||||
|
{
|
||||||
|
levelObjects.ForEach(levelObject => levelObject.LevelUpdate());
|
||||||
|
|
||||||
|
var toAdd = new List<ILevelObject>(this.toAdd);
|
||||||
|
toAdd.ForEach(addedObject =>
|
||||||
|
{
|
||||||
|
this.toAdd.Remove(addedObject);
|
||||||
|
levelObjects.Add(addedObject);
|
||||||
|
Added?.Invoke(addedObject);
|
||||||
|
addedObject.LevelStart();
|
||||||
|
});
|
||||||
|
|
||||||
|
var toRemove = new List<ILevelObject>(this.toRemove);
|
||||||
|
toRemove.ForEach(removedObject =>
|
||||||
|
{
|
||||||
|
this.toRemove.Remove(removedObject);
|
||||||
|
levelObjects.Remove(removedObject);
|
||||||
|
Removed?.Invoke(removedObject);
|
||||||
|
removedObject.LevelDestroy();
|
||||||
|
});
|
||||||
|
toRemove.Clear();
|
||||||
|
}
|
||||||
|
void SaveLevel()
|
||||||
|
{
|
||||||
|
var list = levelObjects.Select(obj => obj.ToDictionary()).ToList();
|
||||||
|
Debug.Log(JsonConvert.SerializeObject(list));
|
||||||
|
}
|
||||||
|
void LoadLevel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class LevelManagerScript : MonoBehaviour
|
||||||
|
{
|
||||||
|
private static LevelManagerScript _instance;
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
if (!_instance) _instance = this;
|
||||||
|
else Destroy(gameObject);
|
||||||
|
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
LevelManager.Instance.UpdateLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 1af43055ac165604e992f071c5520910
|
guid: c8f415d45fd9659408ac8c5ce2e96aba
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@ -1,6 +1,9 @@
|
|||||||
using UnityEngine;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Unity.Plastic.Newtonsoft.Json.Linq;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.Tilemaps;
|
using UnityEngine.Tilemaps;
|
||||||
|
using static Extensions;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// can be inherited by tiles in order to be added to the level manager
|
/// can be inherited by tiles in order to be added to the level manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -8,14 +11,18 @@ public abstract class LevelTile : TileBase, ILevelObject
|
|||||||
{
|
{
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private Sprite _sprite;
|
private Sprite _sprite;
|
||||||
|
[LevelSerialize]
|
||||||
public Vector3 Position { get; protected set; }
|
public Vector3 Position { get; protected set; }
|
||||||
public Tilemap Tilemap { get; private set; }
|
|
||||||
|
[LevelSerialize]
|
||||||
|
public string Tilemap { get; protected set; }
|
||||||
|
[LevelSerialize]
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
public abstract void LevelStart();
|
public abstract void LevelStart();
|
||||||
public abstract void LevelDestroy();
|
public abstract void LevelDestroy();
|
||||||
public abstract void LevelUpdate();
|
public abstract void LevelUpdate();
|
||||||
public abstract bool Equals(ILevelObject other);
|
public abstract bool Equals(ILevelObject other);
|
||||||
|
|
||||||
public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject go)
|
public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject go)
|
||||||
{
|
{
|
||||||
//only execute if application is in play mode
|
//only execute if application is in play mode
|
||||||
@ -28,16 +35,18 @@ public abstract class LevelTile : TileBase, ILevelObject
|
|||||||
|
|
||||||
//need to create an instance of the tile, otherwise the position will change for all tiles instead of only this one.
|
//need to create an instance of the tile, otherwise the position will change for all tiles instead of only this one.
|
||||||
var instance = Instantiate(this);
|
var instance = Instantiate(this);
|
||||||
|
instance.name = name;
|
||||||
instance.Position = position;
|
instance.Position = position;
|
||||||
instance.Tilemap = comp;
|
instance.Tilemap = comp.name;
|
||||||
|
|
||||||
//lambda expression to be used to check if the tile already exists
|
//lambda expression to be used to check if the tile already exists
|
||||||
bool isSameTile(LevelTile tile) => tile.Equals(instance);
|
bool isSameTile(LevelTile tile) => tile.Equals(instance);
|
||||||
|
|
||||||
//if tile is exactly the same as before, don't add.
|
//if tile is exactly the same as before, don't add.
|
||||||
if (LevelManager.Instance.Has<LevelTile>(isSameTile)) return base.StartUp(position, tilemap, go);
|
if (LevelManager.Instance.Has<LevelTile>(isSameTile))
|
||||||
|
{
|
||||||
|
return base.StartUp(position, tilemap, go);
|
||||||
|
}
|
||||||
|
|
||||||
LevelManager.Instance.Add(instance);
|
LevelManager.Instance.Add(instance);
|
||||||
return base.StartUp(position, tilemap, go);
|
return base.StartUp(position, tilemap, go);
|
||||||
@ -49,6 +58,5 @@ public abstract class LevelTile : TileBase, ILevelObject
|
|||||||
tileData.color = Color.white;
|
tileData.color = Color.white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract Dictionary<string, object> ToDictionary();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,16 +1,20 @@
|
|||||||
using UnityEngine;
|
using System.Collections.Generic;
|
||||||
using UnityEngine.Tilemaps;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using static Extensions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// can be inherited by MonoBehaviours in order to be added to the level manager
|
/// can be inherited by MonoBehaviours in order to be added to the level manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LevelObject : MonoBehaviour, ILevelObject
|
public abstract class LevelObject : MonoBehaviour, ILevelObject
|
||||||
{
|
{
|
||||||
|
[LevelSerialize]
|
||||||
public Vector3 Position => transform.position;
|
public Vector3 Position => transform.position;
|
||||||
|
[LevelSerialize]
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
if (LevelManager.Instance.Has<LevelTile>(tile => tile.Position.Approximately(Position))) return;
|
if (LevelManager.Instance.Has<LevelObject>(obj => obj.Equals(this))) return;
|
||||||
|
|
||||||
LevelManager.Instance.Add(this);
|
LevelManager.Instance.Add(this);
|
||||||
}
|
}
|
||||||
@ -18,5 +22,7 @@ public abstract class LevelObject : MonoBehaviour, ILevelObject
|
|||||||
public abstract void LevelStart();
|
public abstract void LevelStart();
|
||||||
public abstract void LevelDestroy();
|
public abstract void LevelDestroy();
|
||||||
public abstract void LevelUpdate();
|
public abstract void LevelUpdate();
|
||||||
|
|
||||||
public abstract bool Equals(ILevelObject other);
|
public abstract bool Equals(ILevelObject other);
|
||||||
|
public abstract Dictionary<string, object> ToDictionary();
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Tilemaps;
|
using UnityEngine.Tilemaps;
|
||||||
|
using static Extensions;
|
||||||
|
|
||||||
[CreateAssetMenu(menuName = "Gather And Defend/Resource Tile")]
|
[CreateAssetMenu(menuName = "Gather And Defend/Resource Tile")]
|
||||||
public class ResourceTile : LevelTile
|
public class ResourceTile : LevelTile
|
||||||
@ -10,12 +10,15 @@ public class ResourceTile : LevelTile
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("the prefab of the currency that will be spawned when mining this resource")]
|
[Tooltip("the prefab of the currency that will be spawned when mining this resource")]
|
||||||
private GameObject _yieldPrefab;
|
private GameObject _yieldPrefab;
|
||||||
|
|
||||||
|
|
||||||
[SerializeField]
|
[LevelSerialize]
|
||||||
|
private string YieldPrefabName => _yieldPrefab.name;
|
||||||
|
|
||||||
|
[SerializeField, LevelSerialize]
|
||||||
private float _yieldSpeed = 1; //resource per second
|
private float _yieldSpeed = 1; //resource per second
|
||||||
|
[LevelSerialize]
|
||||||
private float _yieldCounter = 0;
|
private float _yieldCounter = 0;
|
||||||
|
[LevelSerialize]
|
||||||
public bool Occupied { get; set; }
|
public bool Occupied { get; set; }
|
||||||
|
|
||||||
public override void LevelDestroy()
|
public override void LevelDestroy()
|
||||||
@ -38,7 +41,7 @@ public class ResourceTile : LevelTile
|
|||||||
|
|
||||||
_yieldCounter = 0;
|
_yieldCounter = 0;
|
||||||
var yielded = Instantiate(_yieldPrefab, Position, Quaternion.identity);
|
var yielded = Instantiate(_yieldPrefab, Position, Quaternion.identity);
|
||||||
yielded.transform.SetParent(LevelManager.Instance.transform);
|
yielded.transform.SetParent(LevelManager.Instance.LevelTransform);
|
||||||
}
|
}
|
||||||
public override bool Equals(ILevelObject other)
|
public override bool Equals(ILevelObject other)
|
||||||
{
|
{
|
||||||
@ -48,4 +51,8 @@ public class ResourceTile : LevelTile
|
|||||||
&& _yieldPrefab == otherRes._yieldPrefab
|
&& _yieldPrefab == otherRes._yieldPrefab
|
||||||
&& _yieldCounter == otherRes._yieldCounter;
|
&& _yieldCounter == otherRes._yieldCounter;
|
||||||
}
|
}
|
||||||
|
public override Dictionary<string, object> ToDictionary()
|
||||||
|
{
|
||||||
|
return Extensions.ToDictionary(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ public class TestLevelManager
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
new GameObject("LevelManager").AddComponent<LevelManager>();
|
new GameObject("LevelManager").AddComponent<LevelManagerScript>();
|
||||||
_farm = ScriptableObject.CreateInstance<ResourceTile>();
|
_farm = ScriptableObject.CreateInstance<ResourceTile>();
|
||||||
_farm.name = nameof(_farm);
|
_farm.name = nameof(_farm);
|
||||||
|
|
||||||
|
|||||||
@ -117,6 +117,16 @@ Tilemap:
|
|||||||
m_TileObjectToInstantiateIndex: 65535
|
m_TileObjectToInstantiateIndex: 65535
|
||||||
dummyAlignment: 0
|
dummyAlignment: 0
|
||||||
m_AllTileFlags: 0
|
m_AllTileFlags: 0
|
||||||
|
- first: {x: 0, y: 1, z: 0}
|
||||||
|
second:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_TileIndex: 3
|
||||||
|
m_TileSpriteIndex: 3
|
||||||
|
m_TileMatrixIndex: 0
|
||||||
|
m_TileColorIndex: 0
|
||||||
|
m_TileObjectToInstantiateIndex: 65535
|
||||||
|
dummyAlignment: 0
|
||||||
|
m_AllTileFlags: 0
|
||||||
m_AnimatedTiles: {}
|
m_AnimatedTiles: {}
|
||||||
m_TileAssetArray:
|
m_TileAssetArray:
|
||||||
- m_RefCount: 1
|
- m_RefCount: 1
|
||||||
@ -125,6 +135,8 @@ Tilemap:
|
|||||||
m_Data: {fileID: 11400000, guid: ef5a154519b23a34aaded32e86bf7f2f, type: 2}
|
m_Data: {fileID: 11400000, guid: ef5a154519b23a34aaded32e86bf7f2f, type: 2}
|
||||||
- m_RefCount: 1
|
- m_RefCount: 1
|
||||||
m_Data: {fileID: 11400000, guid: 4aaf448680c7f8a438a9a5861c622a55, type: 2}
|
m_Data: {fileID: 11400000, guid: 4aaf448680c7f8a438a9a5861c622a55, type: 2}
|
||||||
|
- m_RefCount: 1
|
||||||
|
m_Data: {fileID: 11400000, guid: 4002377ed7e87b34699f126f2b10c703, type: 2}
|
||||||
m_TileSpriteArray:
|
m_TileSpriteArray:
|
||||||
- m_RefCount: 1
|
- m_RefCount: 1
|
||||||
m_Data: {fileID: 21300000, guid: ccca3e050cb082b45af0a099790463f6, type: 3}
|
m_Data: {fileID: 21300000, guid: ccca3e050cb082b45af0a099790463f6, type: 3}
|
||||||
@ -132,8 +144,10 @@ Tilemap:
|
|||||||
m_Data: {fileID: 21300000, guid: 1f8a7d27b012449499d5316045662e1e, type: 3}
|
m_Data: {fileID: 21300000, guid: 1f8a7d27b012449499d5316045662e1e, type: 3}
|
||||||
- m_RefCount: 1
|
- m_RefCount: 1
|
||||||
m_Data: {fileID: 21300000, guid: 77a39e873655d3c4b93d0b7696397b83, type: 3}
|
m_Data: {fileID: 21300000, guid: 77a39e873655d3c4b93d0b7696397b83, type: 3}
|
||||||
|
- m_RefCount: 1
|
||||||
|
m_Data: {fileID: 21300000, guid: b85a4b2ec6433d04895612d791edc260, type: 3}
|
||||||
m_TileMatrixArray:
|
m_TileMatrixArray:
|
||||||
- m_RefCount: 3
|
- m_RefCount: 4
|
||||||
m_Data:
|
m_Data:
|
||||||
e00: 1
|
e00: 1
|
||||||
e01: 0
|
e01: 0
|
||||||
@ -152,7 +166,7 @@ Tilemap:
|
|||||||
e32: 0
|
e32: 0
|
||||||
e33: 1
|
e33: 1
|
||||||
m_TileColorArray:
|
m_TileColorArray:
|
||||||
- m_RefCount: 3
|
- m_RefCount: 4
|
||||||
m_Data: {r: 1, g: 1, b: 1, a: 1}
|
m_Data: {r: 1, g: 1, b: 1, a: 1}
|
||||||
m_TileObjectToInstantiateArray: []
|
m_TileObjectToInstantiateArray: []
|
||||||
m_AnimationFrameRate: 1
|
m_AnimationFrameRate: 1
|
||||||
@ -227,7 +241,7 @@ TilemapRenderer:
|
|||||||
m_Mode: 0
|
m_Mode: 0
|
||||||
m_DetectChunkCullingBounds: 0
|
m_DetectChunkCullingBounds: 0
|
||||||
m_MaskInteraction: 0
|
m_MaskInteraction: 0
|
||||||
--- !u!114 &5479319524895914250
|
--- !u!114 &2473294596980876743
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
|||||||
18
Assets/Tiles/EnemySpawner.asset
Normal file
18
Assets/Tiles/EnemySpawner.asset
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b28b3004abb3723498a355747c7cd899, type: 3}
|
||||||
|
m_Name: EnemySpawner
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_sprite: {fileID: 21300000, guid: b85a4b2ec6433d04895612d791edc260, type: 3}
|
||||||
|
_prefab: {fileID: 6962989255644195630, guid: 377c7275c0001cc47a6b8926ac57d573, type: 3}
|
||||||
|
_spawnOnStart: 1
|
||||||
|
_spawnSpeed: 0
|
||||||
8
Assets/Tiles/EnemySpawner.asset.meta
Normal file
8
Assets/Tiles/EnemySpawner.asset.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4002377ed7e87b34699f126f2b10c703
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -13,5 +13,6 @@ MonoBehaviour:
|
|||||||
m_Name: StickSpawner
|
m_Name: StickSpawner
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
_sprite: {fileID: 21300000, guid: 77a39e873655d3c4b93d0b7696397b83, type: 3}
|
_sprite: {fileID: 21300000, guid: 77a39e873655d3c4b93d0b7696397b83, type: 3}
|
||||||
_prefab: {fileID: 6962989255644195630, guid: 9b40c232eddfd1b469bea688e3c970c0, type: 3}
|
_prefab: {fileID: 6962989255644195630, guid: 6cd87b398e7a0e94580f4fcbe2fd310a, type: 3}
|
||||||
_repeat: 0
|
_spawnOnStart: 1
|
||||||
|
_spawnSpeed: 0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user