using System.Linq; using System.Collections.Generic; using UnityEngine; using System; using System.Reflection; namespace GameplayIngredients { public abstract class Manager : MonoBehaviour { private static Dictionary s_Managers = new Dictionary(); public static bool TryGet(out T manager) where T: Manager { manager = null; if(s_Managers.ContainsKey(typeof(T))) { manager = (T)s_Managers[typeof(T)]; return true; } else return false; } public static T Get() where T: Manager { if(s_Managers.ContainsKey(typeof(T))) return (T)s_Managers[typeof(T)]; else { Debug.LogError($"Manager of type '{typeof(T)}' could not be accessed. Check the excludedManagers list in your GameplayIngredientsSettings configuration file."); return null; } } public static bool Has() where T:Manager { return(s_Managers.ContainsKey(typeof(T))); } static readonly Type[] kAllManagerTypes = GetAllManagerTypes(); [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void AutoCreateAll() { s_Managers.Clear(); var exclusionList = GameplayIngredientsSettings.currentSettings.excludedeManagers; if(GameplayIngredientsSettings.currentSettings.verboseCalls) Debug.Log("Initializing all Managers..."); foreach(var type in kAllManagerTypes) { if(exclusionList != null && exclusionList.ToList().Contains(type.Name)) { Debug.LogWarning($"Manager : {type.Name} is in GameplayIngredientSettings.excludedeManagers List: ignoring Creation"); continue; } var attrib = type.GetCustomAttribute(); GameObject gameObject; if(attrib != null) { var prefab = Resources.Load(attrib.prefab); if(prefab == null) // Try loading the "Default_" prefixed version of the prefab { prefab = Resources.Load("Default_"+attrib.prefab); } if(prefab != null) { gameObject = GameObject.Instantiate(prefab); } else { Debug.LogError($"Could not instantiate default prefab for {type.ToString()} : No prefab '{attrib.prefab}' found in resources folders. Ignoring..."); continue; } } else { gameObject = new GameObject(); gameObject.AddComponent(type); } gameObject.name = type.Name; GameObject.DontDestroyOnLoad(gameObject); var comp = (Manager)gameObject.GetComponent(type); s_Managers.Add(type,comp); if (GameplayIngredientsSettings.currentSettings.verboseCalls) Debug.Log(string.Format(" -> <{0}> OK", type.Name)); } } static Type[] GetAllManagerTypes() { List types = new List(); foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies()) { Type[] assemblyTypes = null; try { assemblyTypes = assembly.GetTypes(); } catch { Debug.LogError($"Could not load types from assembly : {assembly.FullName}"); } if(assemblyTypes != null) { foreach (Type t in assemblyTypes) { if (typeof(Manager).IsAssignableFrom(t) && !t.IsAbstract) { types.Add(t); } } } } return types.ToArray(); } } }