using UnityEngine; using AppleHills.Core.Settings; using System; /// /// Singleton manager for global game state and settings. Provides accessors for various gameplay parameters. /// public class GameManager : MonoBehaviour { private static GameManager _instance; private static bool _isQuitting = false; /// /// Singleton instance of the GameManager. /// public static GameManager Instance { get { if (_instance == null && Application.isPlaying && !_isQuitting) { _instance = FindAnyObjectByType(); if (_instance == null) { var go = new GameObject("GameManager"); _instance = go.AddComponent(); // DontDestroyOnLoad(go); } } return _instance; } } [Header("Settings Status")] [SerializeField] private bool _settingsLoaded = false; [SerializeField] private bool _developerSettingsLoaded = false; public bool SettingsLoaded => _settingsLoaded; public bool DeveloperSettingsLoaded => _developerSettingsLoaded; void Awake() { _instance = this; // Create settings provider if it doesn't exist SettingsProvider.Instance.gameObject.name = "Settings Provider"; // Create developer settings provider if it doesn't exist DeveloperSettingsProvider.Instance.gameObject.name = "Developer Settings Provider"; // Load all settings synchronously during Awake InitializeSettings(); InitializeDeveloperSettings(); // DontDestroyOnLoad(gameObject); } private void InitializeSettings() { Debug.Log("Starting settings initialization..."); // Load settings synchronously var playerSettings = SettingsProvider.Instance.LoadSettingsSynchronous(); var interactionSettings = SettingsProvider.Instance.LoadSettingsSynchronous(); var minigameSettings = SettingsProvider.Instance.LoadSettingsSynchronous(); // Register settings with service locator if (playerSettings != null) { ServiceLocator.Register(playerSettings); Debug.Log("PlayerFollowerSettings registered successfully"); } else { Debug.LogError("Failed to load PlayerFollowerSettings"); } if (interactionSettings != null) { ServiceLocator.Register(interactionSettings); Debug.Log("InteractionSettings registered successfully"); } else { Debug.LogError("Failed to load InteractionSettings"); } if (minigameSettings != null) { ServiceLocator.Register(minigameSettings); Debug.Log("MinigameSettings registered successfully"); } else { Debug.LogError("Failed to load MinigameSettings"); } // Log success _settingsLoaded = playerSettings != null && interactionSettings != null && minigameSettings != null; if (_settingsLoaded) { Debug.Log("All settings loaded and registered with ServiceLocator"); } else { Debug.LogWarning("Some settings failed to load - check that all settings assets exist and are marked as Addressables"); } } /// /// Check for and initialize developer settings. /// private void InitializeDeveloperSettings() { Debug.Log("Starting developer settings initialization..."); // Load developer settings var divingDevSettings = DeveloperSettingsProvider.Instance.GetSettings(); _developerSettingsLoaded = divingDevSettings != null; if (_developerSettingsLoaded) { Debug.Log("All developer settings loaded successfully"); } else { Debug.LogWarning("Some developer settings failed to load"); } } void OnApplicationQuit() { _isQuitting = true; ServiceLocator.Clear(); } // Helper method to get settings private T GetSettings() where T : class { return ServiceLocator.Get(); } /// /// Returns the entire settings object of specified type. /// /// Type of settings to retrieve /// The settings object or null if not found public static T GetSettingsObject() where T : class { return Instance?.GetSettings(); } /// /// Returns the developer settings object of specified type. /// /// Type of developer settings to retrieve /// The developer settings object or null if not found public static T GetDeveloperSettings() where T : BaseDeveloperSettings { return DeveloperSettingsProvider.Instance?.GetSettings(); } // LEFTOVER LEGACY SETTINGS public float PlayerStopDistance => GetSettings()?.PlayerStopDistance ?? 6.0f; public float PlayerStopDistanceDirectInteraction => GetSettings()?.PlayerStopDistanceDirectInteraction ?? 2.0f; public float DefaultPuzzlePromptRange => GetSettings()?.DefaultPuzzlePromptRange ?? 3.0f; }