using UnityEngine; using AppleHills.Core.Settings; using System.Collections; /// /// 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("Legacy Game Settings (Deprecated)")] [Tooltip("This is only used for migration to the new settings system")] public GameSettings legacyGameSettings; [Header("Settings Status")] [SerializeField] private bool _settingsLoaded = false; void Awake() { _instance = this; // Create settings provider if it doesn't exist SettingsProvider.Instance.gameObject.name = "Settings Provider"; // Load all settings StartCoroutine(InitializeSettings()); // DontDestroyOnLoad(gameObject); } private IEnumerator InitializeSettings() { // Initialize the settings provider var initComplete = false; SettingsProvider.Instance.PreloadAllSettings(() => initComplete = true); // Wait for settings to be loaded while (!initComplete) { yield return null; } // Register settings with service locator ServiceLocator.Register( SettingsProvider.Instance.GetSettings()); ServiceLocator.Register( SettingsProvider.Instance.GetSettings()); ServiceLocator.Register( SettingsProvider.Instance.GetSettings()); // Log success Debug.Log("All settings loaded and registered with ServiceLocator"); _settingsLoaded = true; // Migrate settings if needed if (legacyGameSettings != null) { MigrateFromLegacySettings(); } } private void MigrateFromLegacySettings() { // This method can be used to copy settings from the old GameSettings to the new system // Implement if needed for your production environment Debug.Log("Legacy settings migration available but not implemented."); } void OnApplicationQuit() { _isQuitting = true; ServiceLocator.Clear(); } // Helper method to get settings private T GetSettings() where T : class { return ServiceLocator.Get(); } // PLAYER & FOLLOWER SETTINGS // Player settings public float MoveSpeed => GetSettings()?.MoveSpeed ?? 5f; public float StopDistance => GetSettings()?.StopDistance ?? 0.1f; public bool UseRigidbody => GetSettings()?.UseRigidbody ?? true; public GameSettings.HoldMovementMode DefaultHoldMovementMode => GetSettings()?.DefaultHoldMovementMode ?? GameSettings.HoldMovementMode.Pathfinding; // Follower settings public float FollowDistance => GetSettings()?.FollowDistance ?? 1.5f; public float ManualMoveSmooth => GetSettings()?.ManualMoveSmooth ?? 8f; public float ThresholdFar => GetSettings()?.ThresholdFar ?? 2.5f; public float ThresholdNear => GetSettings()?.ThresholdNear ?? 0.5f; public float StopThreshold => GetSettings()?.StopThreshold ?? 0.1f; public float FollowUpdateInterval => GetSettings()?.FollowUpdateInterval ?? 0.1f; public float FollowerSpeedMultiplier => GetSettings()?.FollowerSpeedMultiplier ?? 1.2f; public float HeldIconDisplayHeight => GetSettings()?.HeldIconDisplayHeight ?? 2.0f; // INTERACTION SETTINGS public float PlayerStopDistance => GetSettings()?.PlayerStopDistance ?? 6.0f; public float PlayerStopDistanceDirectInteraction => GetSettings()?.PlayerStopDistanceDirectInteraction ?? 2.0f; public float FollowerPickupDelay => GetSettings()?.FollowerPickupDelay ?? 0.2f; public LayerMask InteractableLayerMask => GetSettings()?.InteractableLayerMask ?? -1; public GameObject BasePickupPrefab => GetSettings()?.BasePickupPrefab; public GameObject LevelSwitchMenuPrefab => GetSettings()?.LevelSwitchMenuPrefab; /// /// Returns the combination rule for two items, if any. /// public GameSettings.CombinationRule GetCombinationRule(PickupItemData item1, PickupItemData item2) { var settings = GetSettings(); if (settings == null || settings.CombinationRules == null) return null; foreach (var rule in settings.CombinationRules) { if ((PickupItemData.AreEquivalent(rule.itemA, item1) && PickupItemData.AreEquivalent(rule.itemB, item2)) || (PickupItemData.AreEquivalent(rule.itemA, item2) && PickupItemData.AreEquivalent(rule.itemB, item1))) { return rule; } } return null; } /// /// Returns the slot item config for a given slot item. /// public GameSettings.SlotItemConfig GetSlotItemConfig(PickupItemData slotItem) { var settings = GetSettings(); if (settings == null || settings.SlotItemConfigs == null || slotItem == null) return null; foreach (var config in settings.SlotItemConfigs) { if (PickupItemData.AreEquivalent(slotItem, config.slotItem)) return config; } return null; } // MINIGAME SETTINGS // Endless Descender settings public float EndlessDescenderLerpSpeed => GetSettings()?.EndlessDescenderLerpSpeed ?? 12f; public float EndlessDescenderMaxOffset => GetSettings()?.EndlessDescenderMaxOffset ?? 3f; public float EndlessDescenderClampXMin => GetSettings()?.EndlessDescenderClampXMin ?? -3.5f; public float EndlessDescenderClampXMax => GetSettings()?.EndlessDescenderClampXMax ?? 3.5f; public float EndlessDescenderSpeedExponent => GetSettings()?.EndlessDescenderSpeedExponent ?? 2.5f; }