Remove dependencies on legacy variables in GameManager.Instance

This commit is contained in:
Michal Pikulski
2025-10-07 10:44:26 +02:00
parent c46036dce6
commit f845673eca
9 changed files with 113 additions and 89 deletions

View File

@@ -159,72 +159,10 @@ public class GameManager : MonoBehaviour
{
return DeveloperSettingsProvider.Instance?.GetSettings<T>();
}
// PLAYER & FOLLOWER SETTINGS
// Player settings
public float MoveSpeed => GetSettings<IPlayerFollowerSettings>()?.MoveSpeed ?? 5f;
public float StopDistance => GetSettings<IPlayerFollowerSettings>()?.StopDistance ?? 0.1f;
public bool UseRigidbody => GetSettings<IPlayerFollowerSettings>()?.UseRigidbody ?? true;
public HoldMovementMode DefaultHoldMovementMode =>
GetSettings<IPlayerFollowerSettings>()?.DefaultHoldMovementMode ?? HoldMovementMode.Pathfinding;
// Follower settings
public float FollowDistance => GetSettings<IPlayerFollowerSettings>()?.FollowDistance ?? 1.5f;
public float ManualMoveSmooth => GetSettings<IPlayerFollowerSettings>()?.ManualMoveSmooth ?? 8f;
public float ThresholdFar => GetSettings<IPlayerFollowerSettings>()?.ThresholdFar ?? 2.5f;
public float ThresholdNear => GetSettings<IPlayerFollowerSettings>()?.ThresholdNear ?? 0.5f;
public float StopThreshold => GetSettings<IPlayerFollowerSettings>()?.StopThreshold ?? 0.1f;
public float FollowUpdateInterval => GetSettings<IPlayerFollowerSettings>()?.FollowUpdateInterval ?? 0.1f;
public float FollowerSpeedMultiplier => GetSettings<IPlayerFollowerSettings>()?.FollowerSpeedMultiplier ?? 1.2f;
public float HeldIconDisplayHeight => GetSettings<IPlayerFollowerSettings>()?.HeldIconDisplayHeight ?? 2.0f;
// INTERACTION SETTINGS
// LEFTOVER LEGACY SETTINGS
public float PlayerStopDistance => GetSettings<IInteractionSettings>()?.PlayerStopDistance ?? 6.0f;
public float PlayerStopDistanceDirectInteraction => GetSettings<IInteractionSettings>()?.PlayerStopDistanceDirectInteraction ?? 2.0f;
public float FollowerPickupDelay => GetSettings<IInteractionSettings>()?.FollowerPickupDelay ?? 0.2f;
public LayerMask InteractableLayerMask => GetSettings<IInteractionSettings>()?.InteractableLayerMask ?? -1;
public GameObject BasePickupPrefab => GetSettings<IInteractionSettings>()?.BasePickupPrefab;
public GameObject LevelSwitchMenuPrefab => GetSettings<IInteractionSettings>()?.LevelSwitchMenuPrefab;
// PUZZLE SETTINGS
public float DefaultPuzzlePromptRange => GetSettings<IInteractionSettings>()?.DefaultPuzzlePromptRange ?? 3.0f;
public GameObject DefaultPuzzleIndicatorPrefab => GetSettings<IInteractionSettings>()?.DefaultPuzzleIndicatorPrefab;
/// <summary>
/// Returns the combination rule for two items, if any.
/// </summary>
public CombinationRule GetCombinationRule(PickupItemData item1, PickupItemData item2)
{
var settings = GetSettings<IInteractionSettings>();
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;
}
/// <summary>
/// Returns the slot item config for a given slot item.
/// </summary>
public SlotItemConfig GetSlotItemConfig(PickupItemData slotItem)
{
var settings = GetSettings<IInteractionSettings>();
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;
}
}

View File

@@ -53,5 +53,38 @@ namespace AppleHills.Core.Settings
followerPickupDelay = Mathf.Max(0f, followerPickupDelay);
defaultPuzzlePromptRange = Mathf.Max(0.1f, defaultPuzzlePromptRange);
}
/// <summary>
/// Returns the combination rule for two items, if any.
/// </summary>
public CombinationRule GetCombinationRule(PickupItemData item1, PickupItemData item2)
{
if (combinationRules == null) return null;
foreach (var rule in 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;
}
/// <summary>
/// Returns the slot item config for a given slot item.
/// </summary>
public SlotItemConfig GetSlotItemConfig(PickupItemData slotItem)
{
if (slotItemConfigs == null || slotItem == null) return null;
foreach (var config in slotItemConfigs)
{
if (PickupItemData.AreEquivalent(slotItem, config.slotItem))
return config;
}
return null;
}
}
}

View File

@@ -43,6 +43,10 @@ namespace AppleHills.Core.Settings
// Puzzle settings
GameObject DefaultPuzzleIndicatorPrefab { get; }
float DefaultPuzzlePromptRange { get; }
// Methods to query item configurations
CombinationRule GetCombinationRule(PickupItemData item1, PickupItemData item2);
SlotItemConfig GetSlotItemConfig(PickupItemData slotItem);
}
/// <summary>

View File

@@ -3,6 +3,7 @@ using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using AppleHills.Core.Settings; // Added for IInteractionSettings
namespace Input
{
@@ -44,6 +45,9 @@ namespace Input
}
}
// Settings reference
private IInteractionSettings _interactionSettings;
private PlayerInput playerInput;
private InputAction tapMoveAction;
private InputAction holdMoveAction;
@@ -55,6 +59,10 @@ namespace Input
{
_instance = this;
// DontDestroyOnLoad(gameObject);
// Initialize settings reference
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
playerInput = GetComponent<PlayerInput>();
if (playerInput == null)
{
@@ -217,7 +225,7 @@ namespace Input
/// </summary>
private bool TryDelegateToInteractable(Vector2 worldPos)
{
LayerMask mask = GameManager.Instance != null ? GameManager.Instance.InteractableLayerMask : -1;
LayerMask mask = _interactionSettings != null ? _interactionSettings.InteractableLayerMask : -1;
Collider2D hit = Physics2D.OverlapPoint(worldPos, mask);
if (hit != null)
{

View File

@@ -3,6 +3,7 @@ using UnityEngine;
using UnityEngine.Events;
using System; // for Action<T>
using Core; // register with ItemManager
using AppleHills.Core.Settings; // Added for IInteractionSettings
namespace Interactions
{
@@ -24,6 +25,10 @@ namespace Interactions
// Tracks the current state of the slotted item
private ItemSlotState _currentState = ItemSlotState.None;
// Settings reference
private IInteractionSettings _interactionSettings;
private IPlayerFollowerSettings _playerFollowerSettings;
/// <summary>
/// Read-only access to the current slotted item state.
/// </summary>
@@ -64,13 +69,22 @@ namespace Interactions
}
}
public override void Awake()
{
base.Awake();
// Initialize settings references
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
_playerFollowerSettings = GameManager.GetSettingsObject<IPlayerFollowerSettings>();
}
protected override void OnCharacterArrived()
{
Debug.Log("[ItemSlot] OnCharacterArrived");
var heldItemData = FollowerController.CurrentlyHeldItemData;
var heldItemObj = FollowerController.GetHeldPickupObject();
var config = GameManager.Instance.GetSlotItemConfig(itemData);
var config = _interactionSettings?.GetSlotItemConfig(itemData);
var forbidden = config?.forbiddenItems ?? new List<PickupItemData>();
// Held item, slot empty -> try to slot item
@@ -120,7 +134,7 @@ namespace Interactions
{
slottedItemRenderer.sprite = _currentlySlottedItemData.mapSprite;
// Scale sprite to desired height, preserve aspect ratio, compensate for parent scale
float desiredHeight = GameManager.Instance.HeldIconDisplayHeight;
float desiredHeight = _playerFollowerSettings?.HeldIconDisplayHeight ?? 2.0f;
var sprite = _currentlySlottedItemData.mapSprite;
float spriteHeight = sprite.bounds.size.y;
float spriteWidth = sprite.bounds.size.x;
@@ -175,7 +189,7 @@ namespace Interactions
// Once an item is slotted, we know it is not forbidden, so we can skip that check, but now check if it was
// the correct item we're looking for
var config = GameManager.Instance.GetSlotItemConfig(itemData);
var config = _interactionSettings?.GetSlotItemConfig(itemData);
var allowed = config?.allowedItems ?? new List<PickupItemData>();
if (itemToSlotData != null && PickupItemData.ListContainsEquivalent(allowed, itemToSlotData))
{

View File

@@ -26,7 +26,7 @@ namespace Interactions
/// <summary>
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
/// </summary>
void Awake()
public virtual void Awake()
{
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();

View File

@@ -2,6 +2,7 @@
using Input;
using Interactions;
using UnityEngine;
using AppleHills.Core.Settings; // Added for IInteractionSettings
/// <summary>
/// Handles level switching when interacted with. Applies switch data and triggers scene transitions.
@@ -14,6 +15,9 @@ public class LevelSwitch : MonoBehaviour
public LevelSwitchData switchData;
private SpriteRenderer _iconRenderer;
private Interactable _interactable;
// Settings reference
private IInteractionSettings _interactionSettings;
private bool _isActive = true;
@@ -30,6 +34,10 @@ public class LevelSwitch : MonoBehaviour
{
_interactable.characterArrived.AddListener(OnCharacterArrived);
}
// Initialize settings reference
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
ApplySwitchData();
}
@@ -78,10 +86,10 @@ public class LevelSwitch : MonoBehaviour
if (switchData == null || string.IsNullOrEmpty(switchData.targetLevelSceneName) || !_isActive)
return;
var menuPrefab = GameManager.Instance.LevelSwitchMenuPrefab;
var menuPrefab = _interactionSettings?.LevelSwitchMenuPrefab;
if (menuPrefab == null)
{
Debug.LogError("LevelSwitchMenu prefab not assigned in GameSettings!");
Debug.LogError("LevelSwitchMenu prefab not assigned in InteractionSettings!");
return;
}
// Spawn the menu overlay (assume Canvas parent is handled in prefab setup)

View File

@@ -3,6 +3,7 @@ using UnityEngine;
using Pathfinding;
using UnityEngine.SceneManagement;
using Utils;
using AppleHills.Core.Settings;
/// <summary>
/// Controls the follower character, including following the player, handling pickups, and managing held items.
@@ -20,6 +21,10 @@ public class FollowerController: MonoBehaviour
/// </summary>
public float manualMoveSmooth = 8f;
// Settings reference
private IPlayerFollowerSettings _settings;
private IInteractionSettings _interactionSettings;
private GameObject _playerRef;
private Transform _playerTransform;
private AIPath _playerAIPath;
@@ -80,6 +85,10 @@ public class FollowerController: MonoBehaviour
_animator = GetComponentInChildren<Animator>(); // fallback
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
}
// Initialize settings references
_settings = GameManager.GetSettingsObject<IPlayerFollowerSettings>();
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
}
void OnEnable()
@@ -108,7 +117,7 @@ public class FollowerController: MonoBehaviour
}
_timer += Time.deltaTime;
if (_timer >= GameManager.Instance.FollowUpdateInterval)
if (_timer >= _settings.FollowUpdateInterval)
{
_timer = 0f;
UpdateFollowTarget();
@@ -120,24 +129,24 @@ public class FollowerController: MonoBehaviour
Vector2 target2D = new Vector2(_targetPoint.x, _targetPoint.y);
float dist = Vector2.Distance(current2D, target2D);
float minSpeed = _followerMaxSpeed * 0.3f;
float lerpFactor = GameManager.Instance.ManualMoveSmooth * Time.deltaTime;
float lerpFactor = _settings.ManualMoveSmooth * Time.deltaTime;
float targetSpeed = 0f;
if (dist > GameManager.Instance.StopThreshold)
if (dist > _settings.StopThreshold)
{
if (dist > GameManager.Instance.ThresholdFar)
if (dist > _settings.ThresholdFar)
{
targetSpeed = _followerMaxSpeed;
}
else if (dist > GameManager.Instance.ThresholdNear && dist <= GameManager.Instance.ThresholdFar)
else if (dist > _settings.ThresholdNear && dist <= _settings.ThresholdFar)
{
targetSpeed = _followerMaxSpeed;
}
else if (dist > GameManager.Instance.StopThreshold && dist <= GameManager.Instance.ThresholdNear)
else if (dist > _settings.StopThreshold && dist <= _settings.ThresholdNear)
{
targetSpeed = minSpeed;
}
_currentSpeed = Mathf.Lerp(_currentSpeed, targetSpeed, lerpFactor);
if (dist > GameManager.Instance.StopThreshold && dist <= GameManager.Instance.ThresholdNear)
if (dist > _settings.StopThreshold && dist <= _settings.ThresholdNear)
{
_currentSpeed = Mathf.Max(_currentSpeed, minSpeed);
}
@@ -215,7 +224,7 @@ public class FollowerController: MonoBehaviour
{
_playerMaxSpeed = _playerAIPath.maxSpeed;
_defaultFollowerMaxSpeed = _playerMaxSpeed;
_followerMaxSpeed = _playerMaxSpeed * GameManager.Instance.FollowerSpeedMultiplier;
_followerMaxSpeed = _playerMaxSpeed * _settings.FollowerSpeedMultiplier;
}
}
else
@@ -258,8 +267,8 @@ public class FollowerController: MonoBehaviour
{
moveDir = _lastMoveDir;
}
// Use GameSettings for followDistance
_targetPoint = playerPos - moveDir * GameManager.Instance.FollowDistance;
// Use settings for followDistance
_targetPoint = playerPos - moveDir * _settings.FollowDistance;
_targetPoint.z = 0;
if (_aiPath != null)
{
@@ -310,14 +319,14 @@ public class FollowerController: MonoBehaviour
_aiPath.destination = new Vector3(itemPosition.x, itemPosition.y, 0);
}
// Wait until follower reaches item (2D distance)
while (Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(itemPosition.x, itemPosition.y)) > GameManager.Instance.StopThreshold)
while (Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(itemPosition.x, itemPosition.y)) > _settings.StopThreshold)
{
yield return null;
}
OnPickupArrived?.Invoke();
// Wait briefly, then return to player
yield return new WaitForSeconds(0.2f);
yield return new WaitForSeconds(_interactionSettings.FollowerPickupDelay);
if (_aiPath != null && playerTransform != null)
{
_aiPath.maxSpeed = _followerMaxSpeed;
@@ -325,7 +334,7 @@ public class FollowerController: MonoBehaviour
}
_isReturningToPlayer = true;
// Wait until follower returns to player (2D distance)
while (playerTransform != null && Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(playerTransform.position.x, playerTransform.position.y)) > GameManager.Instance.StopThreshold)
while (playerTransform != null && Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(playerTransform.position.x, playerTransform.position.y)) > _settings.StopThreshold)
{
yield return null;
}
@@ -375,15 +384,18 @@ public class FollowerController: MonoBehaviour
{
return CombinationResult.NotApplicable;
}
var rule = GameManager.Instance.GetCombinationRule(pickupA.itemData, pickupB.itemData);
// Use the InteractionSettings directly instead of GameManager
CombinationRule matchingRule = _interactionSettings.GetCombinationRule(pickupA.itemData, pickupB.itemData);
Vector3 spawnPos = pickupA.gameObject.transform.position;
if (rule != null && rule.resultPrefab != null)
if (matchingRule != null && matchingRule.resultPrefab != null)
{
newItem = Instantiate(rule.resultPrefab, spawnPos, Quaternion.identity);
newItem = Instantiate(matchingRule.resultPrefab, spawnPos, Quaternion.identity);
PickupItemData itemData = newItem.GetComponent<Pickup>().itemData;
Destroy(pickupA.gameObject);
Destroy(pickupB.gameObject);
TryPickupItem(newItem,itemData);
TryPickupItem(newItem, itemData);
return CombinationResult.Successful;
}

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using AppleHills.Core.Settings; // Added for IInteractionSettings
namespace PuzzleS
{
@@ -21,6 +22,9 @@ namespace PuzzleS
private Transform _playerTransform;
private Coroutine _proximityCheckCoroutine;
// Settings reference
private IInteractionSettings _interactionSettings;
/// <summary>
/// Singleton instance of the PuzzleManager.
/// </summary>
@@ -58,6 +62,9 @@ namespace PuzzleS
_instance = this;
// DontDestroyOnLoad(gameObject);
SceneManager.sceneLoaded += OnSceneLoaded;
// Initialize settings reference
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
}
void Start()
@@ -123,8 +130,8 @@ namespace PuzzleS
{
if (_playerTransform != null)
{
// Get the proximity threshold from settings (half of the prompt range)
float proximityThreshold = GameManager.Instance.DefaultPuzzlePromptRange;
// Get the proximity threshold from settings directly using our settings reference
float proximityThreshold = _interactionSettings?.DefaultPuzzlePromptRange ?? 3.0f;
// Check distance to each step behavior
foreach (var kvp in _stepBehaviours)