using System.Collections.Generic; using System.Linq; using Unity.Plastic.Newtonsoft.Json; using UnityEngine; public class LevelManager : Singleton { public delegate void LevelAction(ILevelObject levelObject); public delegate bool LevelPredicate(T levelObject) where T : ILevelObject; public event LevelAction Added; public event LevelAction Removed; private readonly List toAdd; private readonly List toRemove; private readonly List levelObjects; public Transform LevelTransform { get;private set; } public LevelManager() { toAdd = new List(); toRemove = new List(); levelObjects = new List(); var mgrScript = Object.FindObjectOfType(); if (!mgrScript) mgrScript = new GameObject(nameof(LevelManager)).AddComponent(); 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(LevelPredicate predicate = null) where T : ILevelObject { if (predicate == null) predicate = (generic) => true; return (T)levelObjects.Find(levelObject => levelObject is T generic && predicate(generic)); } public List GetAll(LevelPredicate predicate = null) where T : ILevelObject { if (predicate == null) predicate = (generic) => true; List ret = new(); foreach (var levelObject in levelObjects) if (levelObject is T generic && predicate(generic)) ret.Add(generic); return ret; } public int Count(LevelPredicate predicate = null) where T : ILevelObject { return GetAll(predicate).Count; } public bool Has(LevelPredicate 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(this.toAdd); toAdd.ForEach(addedObject => { this.toAdd.Remove(addedObject); levelObjects.Add(addedObject); Added?.Invoke(addedObject); addedObject.LevelStart(); }); var toRemove = new List(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(); } }