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;
}