From 9a6914b9bd92fb850e47a8e19b0488468655251f Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Tue, 11 Nov 2025 10:53:09 +0100 Subject: [PATCH] Final touchups to the lifecycle management --- .../Scripts/Bootstrap/BootSceneController.cs | 6 +- .../Scripts/Cinematics/CinematicsManager.cs | 2 - Assets/Scripts/Cinematics/SkipCinematic.cs | 6 +- Assets/Scripts/Core/GameManager.cs | 2 - Assets/Scripts/Core/ItemManager.cs | 6 +- .../Scripts/Core/Lifecycle/LifecycleEnums.cs | 9 ++- .../Core/Lifecycle/LifecycleManager.cs | 73 ++++--------------- .../Core/Lifecycle/ManagedBehaviour.cs | 64 ++++------------ Assets/Scripts/Core/QuickAccess.cs | 3 - .../Scripts/Core/SaveLoad/SaveLoadManager.cs | 6 +- .../Scripts/Core/SaveablePlayableDirector.cs | 4 +- Assets/Scripts/Core/SceneManagerService.cs | 4 +- .../Scripts/Core/SceneOrientationEnforcer.cs | 7 +- .../Data/CardSystem/CardSystemManager.cs | 2 - Assets/Scripts/Dialogue/DialogueComponent.cs | 7 +- Assets/Scripts/Input/InputManager.cs | 5 +- Assets/Scripts/Input/PlayerTouchController.cs | 1 - Assets/Scripts/Interactions/Interactable.cs | 3 - Assets/Scripts/Interactions/ItemSlot.cs | 4 +- Assets/Scripts/Interactions/Pickup.cs | 4 +- Assets/Scripts/Levels/MinigameSwitch.cs | 4 +- .../DivingForPictures/DivingGameManager.cs | 5 +- Assets/Scripts/Movement/FollowerController.cs | 2 - .../Scripts/PuzzleS/ObjectiveStepBehaviour.cs | 4 +- Assets/Scripts/PuzzleS/PuzzleManager.cs | 6 +- Assets/Scripts/Sound/AudioManager.cs | 2 - Assets/Scripts/UI/AppSwitcher.cs | 4 +- Assets/Scripts/UI/CardSystem/AlbumViewPage.cs | 5 +- .../UI/CardSystem/BoosterNotificationDot.cs | 5 +- .../UI/CardSystem/BoosterOpeningPage.cs | 4 +- .../CardSystem/DragDrop/BoosterPackVisual.cs | 4 +- .../DragDrop/CardDraggableVisual.cs | 4 +- Assets/Scripts/UI/Core/UIPage.cs | 3 - Assets/Scripts/UI/Core/UIPageController.cs | 6 +- Assets/Scripts/UI/LoadingScreenController.cs | 3 - Assets/Scripts/UI/PauseMenu.cs | 7 +- Assets/Scripts/UI/PlayerHudManager.cs | 4 +- Assets/Scripts/UI/Tutorial/DivingTutorial.cs | 1 - 38 files changed, 62 insertions(+), 229 deletions(-) diff --git a/Assets/Scripts/Bootstrap/BootSceneController.cs b/Assets/Scripts/Bootstrap/BootSceneController.cs index 6878413e..95f0ae86 100644 --- a/Assets/Scripts/Bootstrap/BootSceneController.cs +++ b/Assets/Scripts/Bootstrap/BootSceneController.cs @@ -30,8 +30,6 @@ namespace Bootstrap private float _sceneLoadingProgress = 0f; private LogVerbosity _logVerbosity = LogVerbosity.Warning; - // Run very early - need to set up loading screen before other systems initialize - public override int ManagedAwakePriority => 5; internal override void OnManagedAwake() { @@ -83,10 +81,8 @@ namespace Bootstrap Invoke(nameof(StartLoadingMainMenu), minDelayAfterBoot); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Manual cleanup for events if (initialLoadingScreen != null) { diff --git a/Assets/Scripts/Cinematics/CinematicsManager.cs b/Assets/Scripts/Cinematics/CinematicsManager.cs index 1f39000f..553a8324 100644 --- a/Assets/Scripts/Cinematics/CinematicsManager.cs +++ b/Assets/Scripts/Cinematics/CinematicsManager.cs @@ -37,8 +37,6 @@ namespace Cinematics public PlayableDirector playableDirector; - public override int ManagedAwakePriority => 170; // Cinematic systems - internal override void OnManagedAwake() { // Set instance immediately (early initialization) diff --git a/Assets/Scripts/Cinematics/SkipCinematic.cs b/Assets/Scripts/Cinematics/SkipCinematic.cs index 0135f773..23ed0613 100644 --- a/Assets/Scripts/Cinematics/SkipCinematic.cs +++ b/Assets/Scripts/Cinematics/SkipCinematic.cs @@ -15,8 +15,6 @@ namespace Cinematics private float _holdStartTime; private bool _isHolding; private bool _skipPerformed; - - public override int ManagedAwakePriority => 180; // Cinematic UI internal override void OnManagedStart() { @@ -32,10 +30,8 @@ namespace Cinematics Logging.Debug("[SkipCinematic] Initialized"); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Clean up subscriptions UnsubscribeFromCinematicsEvents(); } diff --git a/Assets/Scripts/Core/GameManager.cs b/Assets/Scripts/Core/GameManager.cs index 686c46e1..6ccd6750 100644 --- a/Assets/Scripts/Core/GameManager.cs +++ b/Assets/Scripts/Core/GameManager.cs @@ -34,8 +34,6 @@ namespace Core public event Action OnGamePaused; public event Action OnGameResumed; - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 10; // Core infrastructure - runs early internal override void OnManagedAwake() { diff --git a/Assets/Scripts/Core/ItemManager.cs b/Assets/Scripts/Core/ItemManager.cs index 8c6e269b..0979df76 100644 --- a/Assets/Scripts/Core/ItemManager.cs +++ b/Assets/Scripts/Core/ItemManager.cs @@ -47,8 +47,6 @@ namespace Core // Broadcasts when any two items are successfully combined // Args: first item data, second item data, result item data public event Action OnItemsCombined; - - public override int ManagedAwakePriority => 75; // Item registry internal override void OnManagedAwake() { @@ -67,10 +65,8 @@ namespace Core ClearAllRegistrations(); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Ensure we clean up any subscriptions from registered items when the manager is destroyed ClearAllRegistrations(); } diff --git a/Assets/Scripts/Core/Lifecycle/LifecycleEnums.cs b/Assets/Scripts/Core/Lifecycle/LifecycleEnums.cs index 54c3b391..09517170 100644 --- a/Assets/Scripts/Core/Lifecycle/LifecycleEnums.cs +++ b/Assets/Scripts/Core/Lifecycle/LifecycleEnums.cs @@ -6,12 +6,19 @@ /// public enum LifecyclePhase { + /// + /// Called immediately during registration (during Awake). + /// Use for early initialization such as setting singleton instances. + /// NOT ordered - fires whenever Unity calls this component's Awake(). + /// + ManagedAwake, + /// /// Called once per component after bootstrap completes. /// Guaranteed to be called after all bootstrap resources are loaded. /// For late-registered components, called immediately upon registration. /// - ManagedAwake, + ManagedStart, /// /// Called before a scene is unloaded. diff --git a/Assets/Scripts/Core/Lifecycle/LifecycleManager.cs b/Assets/Scripts/Core/Lifecycle/LifecycleManager.cs index eb2ba3c5..87788e1c 100644 --- a/Assets/Scripts/Core/Lifecycle/LifecycleManager.cs +++ b/Assets/Scripts/Core/Lifecycle/LifecycleManager.cs @@ -59,11 +59,11 @@ namespace Core.Lifecycle #region State Flags - private bool isBootComplete = false; + private bool isBootComplete; private string currentSceneReady = ""; // Scene loading state tracking - private bool isLoadingScene = false; + private bool isLoadingScene; private string sceneBeingLoaded = ""; private List pendingSceneComponents = new List(); @@ -120,17 +120,13 @@ namespace Core.Lifecycle // Track which scene this component belongs to componentScenes[component] = sceneName; - // ALWAYS add to managedAwakeList - this is the master list used for save/load - InsertSorted(managedAwakeList, component, component.ManagedAwakePriority); - - // Register for all scene lifecycle hooks - InsertSorted(sceneUnloadingList, component, component.SceneUnloadingPriority); - InsertSorted(sceneReadyList, component, component.SceneReadyPriority); - InsertSorted(saveRequestedList, component, component.SavePriority); - InsertSorted(restoreRequestedList, component, component.RestorePriority); - InsertSorted(destroyList, component, component.DestroyPriority); - - // Call OnManagedAwake immediately after registration (early initialization hook) + // Add to all lifecycle lists (order of registration determines execution order) + managedAwakeList.Add(component); + sceneUnloadingList.Add(component); + sceneReadyList.Add(component); + saveRequestedList.Add(component); + restoreRequestedList.Add(component); + destroyList.Add(component); try { component.OnManagedAwake(); @@ -146,7 +142,7 @@ namespace Core.Lifecycle // Check if we're currently loading a scene if (isLoadingScene && sceneName == sceneBeingLoaded) { - // Batch this component - will be processed in priority order when scene load completes + // Batch this component - will be processed when scene load completes pendingSceneComponents.Add(component); LogDebug($"Batched component for scene load: {component.gameObject.name} (Scene: {sceneName})"); } @@ -282,10 +278,7 @@ namespace Core.Lifecycle LogDebug($"Processing {pendingSceneComponents.Count} batched components for scene: {sceneBeingLoaded}"); - // Sort by ManagedAwake priority (lower values first) - pendingSceneComponents.Sort((a, b) => a.ManagedAwakePriority.CompareTo(b.ManagedAwakePriority)); - - // Call OnManagedStart in priority order + // Call OnManagedStart in registration order foreach (var component in pendingSceneComponents) { if (component == null) continue; @@ -294,7 +287,7 @@ namespace Core.Lifecycle { component.OnManagedStart(); HandleAutoRegistrations(component); - LogDebug($"Processed batched component: {component.gameObject.name} (Priority: {component.ManagedAwakePriority})"); + LogDebug($"Processed batched component: {component.gameObject.name}"); } catch (Exception ex) { @@ -309,7 +302,7 @@ namespace Core.Lifecycle } /// - /// Broadcast OnSceneUnloading to components in the specified scene (reverse priority order). + /// Broadcast OnSceneUnloading to components in the specified scene. /// public void BroadcastSceneUnloading(string sceneName) { @@ -336,8 +329,8 @@ namespace Core.Lifecycle } /// - /// Broadcast OnSceneReady to components in the specified scene (priority order). - /// If scene loading mode is active, processes batched components first. + /// Broadcast OnSceneReady to components in the specified scene. + /// Processes batched components first, then calls OnSceneReady on all components in that scene. /// public void BroadcastSceneReady(string sceneName) { @@ -621,42 +614,6 @@ namespace Core.Lifecycle #endregion #region Helper Methods - - /// - /// Insert component into list maintaining sorted order by priority. - /// Uses binary search for efficient insertion. - /// - private void InsertSorted(List list, ManagedBehaviour component, int priority) - { - // Simple linear insertion for now (can optimize with binary search later if needed) - int index = 0; - for (int i = 0; i < list.Count; i++) - { - int existingPriority = GetPriorityForList(list[i], list); - if (priority < existingPriority) - { - index = i; - break; - } - index = i + 1; - } - - list.Insert(index, component); - } - - /// - /// Get the priority value for a component based on which list it's in. - /// - private int GetPriorityForList(ManagedBehaviour component, List list) - { - if (list == managedAwakeList) return component.ManagedAwakePriority; - if (list == sceneUnloadingList) return component.SceneUnloadingPriority; - if (list == sceneReadyList) return component.SceneReadyPriority; - if (list == saveRequestedList) return component.SavePriority; - if (list == restoreRequestedList) return component.RestorePriority; - if (list == destroyList) return component.DestroyPriority; - return 100; - } /// /// Log debug message if debug logging is enabled. diff --git a/Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs b/Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs index 0fe6d79e..e857a359 100644 --- a/Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs +++ b/Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs @@ -8,46 +8,6 @@ namespace Core.Lifecycle /// public abstract class ManagedBehaviour : MonoBehaviour { - #region Priority Properties - - /// - /// Priority for OnManagedStart (lower values execute first). - /// Default: 100 - /// - public virtual int ManagedAwakePriority => 100; - - /// - /// Priority for OnSceneUnloading (executed in reverse: higher values execute first). - /// Default: 100 - /// - public virtual int SceneUnloadingPriority => 100; - - /// - /// Priority for OnSceneReady (lower values execute first). - /// Default: 100 - /// - public virtual int SceneReadyPriority => 100; - - /// - /// Priority for OnSaveRequested (executed in reverse: higher values execute first). - /// Default: 100 - /// - public virtual int SavePriority => 100; - - /// - /// Priority for OnRestoreRequested (lower values execute first). - /// Default: 100 - /// - public virtual int RestorePriority => 100; - - /// - /// Priority for OnManagedDestroy (executed in reverse: higher values execute first). - /// Default: 100 - /// - public virtual int DestroyPriority => 100; - - #endregion - #region Configuration Properties /// @@ -67,14 +27,19 @@ namespace Core.Lifecycle /// Unique identifier for this component in the save system. /// Default: "SceneName/GameObjectName/ComponentType" /// Override ONLY for special cases (e.g., singletons like "PlayerController", or custom IDs). + /// Cached on first access to avoid runtime allocation. /// public virtual string SaveId { get { - string sceneName = gameObject.scene.IsValid() ? gameObject.scene.name : "UnknownScene"; - string componentType = GetType().Name; - return $"{sceneName}/{gameObject.name}/{componentType}"; + if (_cachedSaveId == null) + { + string sceneName = gameObject.scene.IsValid() ? gameObject.scene.name : "UnknownScene"; + string componentType = GetType().Name; + _cachedSaveId = $"{sceneName}/{gameObject.name}/{componentType}"; + } + return _cachedSaveId; } } @@ -83,6 +48,7 @@ namespace Core.Lifecycle #region Private Fields private bool _isRegistered; + private string _cachedSaveId; #endregion @@ -107,13 +73,16 @@ namespace Core.Lifecycle /// /// Unity OnDestroy - automatically unregisters and cleans up. - /// IMPORTANT: Derived classes that override OnDestroy MUST call base.OnDestroy() + /// SEALED: Cannot be overridden. Use OnManagedDestroy() for custom cleanup logic. /// - protected virtual void OnDestroy() + private void OnDestroy() { if (!_isRegistered) return; + // Call managed destroy hook + OnManagedDestroy(); + // Unregister from LifecycleManager if (LifecycleManager.Instance != null) { @@ -149,7 +118,7 @@ namespace Core.Lifecycle /// /// Called once per component after bootstrap completes. /// GUARANTEE: Bootstrap resources are available, all managers are initialized. - /// For boot-time components: Called during LifecycleManager.BroadcastManagedStart (priority ordered). + /// For boot-time components: Called during LifecycleManager.BroadcastManagedStart (registration order). /// For late-registered components: Called immediately upon registration (bootstrap already complete). /// Use for initialization that depends on other systems. /// NOTE: Internal visibility allows LifecycleManager to call directly. Override in derived classes. @@ -161,7 +130,6 @@ namespace Core.Lifecycle /// /// Called before the scene this component belongs to is unloaded. - /// Called in REVERSE priority order (higher values execute first). /// Use for scene-specific cleanup. /// NOTE: Internal visibility allows LifecycleManager to call directly. Override in derived classes. /// @@ -172,7 +140,6 @@ namespace Core.Lifecycle /// /// Called after the scene this component belongs to has finished loading. - /// Called in priority order (lower values execute first). /// Use for scene-specific initialization. /// NOTE: Internal visibility allows LifecycleManager to call directly. Override in derived classes. /// @@ -312,7 +279,6 @@ namespace Core.Lifecycle /// /// Called during OnDestroy before component is destroyed. - /// Called in REVERSE priority order (higher values execute first). /// NOTE: Most cleanup is automatic (managed events, auto-registrations). /// Only override if you need custom cleanup logic. /// Internal visibility allows LifecycleManager to call directly. Override in derived classes. diff --git a/Assets/Scripts/Core/QuickAccess.cs b/Assets/Scripts/Core/QuickAccess.cs index f086e3b6..f86d4b05 100644 --- a/Assets/Scripts/Core/QuickAccess.cs +++ b/Assets/Scripts/Core/QuickAccess.cs @@ -24,9 +24,6 @@ namespace AppleHills.Core #endregion Singleton Setup - // Very early initialization - QuickAccess should be available immediately - public override int ManagedAwakePriority => 5; - #region Manager Instances // Core Managers diff --git a/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs b/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs index d43c736e..a5563ba0 100644 --- a/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs +++ b/Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs @@ -43,8 +43,6 @@ namespace Core.SaveLoad public event Action OnLoadCompleted; public event Action OnParticipantStatesRestored; - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 20; // After GameManager and SceneManagerService internal override void OnManagedAwake() { @@ -95,10 +93,8 @@ namespace Core.SaveLoad // ...existing code... - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); // Important: call base to unregister from LifecycleManager - if (_instance == this) { _instance = null; diff --git a/Assets/Scripts/Core/SaveablePlayableDirector.cs b/Assets/Scripts/Core/SaveablePlayableDirector.cs index 13bf74c3..8d87b748 100644 --- a/Assets/Scripts/Core/SaveablePlayableDirector.cs +++ b/Assets/Scripts/Core/SaveablePlayableDirector.cs @@ -42,10 +42,8 @@ namespace Core } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - if (_director != null) { _director.stopped -= OnDirectorStopped; diff --git a/Assets/Scripts/Core/SceneManagerService.cs b/Assets/Scripts/Core/SceneManagerService.cs index 028f67bb..ecdd9377 100644 --- a/Assets/Scripts/Core/SceneManagerService.cs +++ b/Assets/Scripts/Core/SceneManagerService.cs @@ -44,8 +44,6 @@ namespace Core private LogVerbosity _logVerbosity = LogVerbosity.Debug; private const string BootstrapSceneName = "BootstrapScene"; - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 15; // Core infrastructure, after GameManager internal override void OnManagedAwake() { @@ -369,7 +367,7 @@ namespace Core await LoadSceneAsync(newSceneName, progress); CurrentGameplayScene = newSceneName; - // PHASE 10: Broadcast scene ready - processes batched components in priority order, then calls OnSceneReady + // PHASE 10: Broadcast scene ready - processes batched components, then calls OnSceneReady Logging.Debug($"Broadcasting OnSceneReady for: {newSceneName}"); LifecycleManager.Instance?.BroadcastSceneReady(newSceneName); diff --git a/Assets/Scripts/Core/SceneOrientationEnforcer.cs b/Assets/Scripts/Core/SceneOrientationEnforcer.cs index cebea931..f3c32079 100644 --- a/Assets/Scripts/Core/SceneOrientationEnforcer.cs +++ b/Assets/Scripts/Core/SceneOrientationEnforcer.cs @@ -18,9 +18,6 @@ namespace Core public GameObject orientationPromptPrefab; private LogVerbosity _logVerbosity = LogVerbosity.Warning; - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 70; // Platform-specific utility - internal override void OnManagedAwake() { // Set instance immediately (early initialization) @@ -103,15 +100,13 @@ namespace Core } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { // Unsubscribe from events to prevent memory leaks if (SceneManagerService.Instance != null) { SceneManagerService.Instance.SceneLoadCompleted -= OnSceneLoadCompleted; } - - base.OnDestroy(); // Important: call base } /// diff --git a/Assets/Scripts/Data/CardSystem/CardSystemManager.cs b/Assets/Scripts/Data/CardSystem/CardSystemManager.cs index 01ecec84..df7993d7 100644 --- a/Assets/Scripts/Data/CardSystem/CardSystemManager.cs +++ b/Assets/Scripts/Data/CardSystem/CardSystemManager.cs @@ -43,8 +43,6 @@ namespace Data.CardSystem public event Action OnBoosterCountChanged; public event Action OnPendingCardAdded; public event Action OnCardPlacedInAlbum; - - public override int ManagedAwakePriority => 60; // Data systems internal override void OnManagedAwake() { diff --git a/Assets/Scripts/Dialogue/DialogueComponent.cs b/Assets/Scripts/Dialogue/DialogueComponent.cs index c84fe6fb..b4102b79 100644 --- a/Assets/Scripts/Dialogue/DialogueComponent.cs +++ b/Assets/Scripts/Dialogue/DialogueComponent.cs @@ -32,9 +32,6 @@ namespace Dialogue public bool IsCompleted { get; private set; } public string CurrentSpeakerName => dialogueGraph?.speakerName; - - public override int ManagedAwakePriority => 150; // Dialogue systems - internal override void OnManagedStart() { // Get required components @@ -184,10 +181,8 @@ namespace Dialogue return null; } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unregister from events if (PuzzleManager.Instance != null) PuzzleManager.Instance.OnStepCompleted -= OnAnyPuzzleStepCompleted; diff --git a/Assets/Scripts/Input/InputManager.cs b/Assets/Scripts/Input/InputManager.cs index dd830e99..ec1f7903 100644 --- a/Assets/Scripts/Input/InputManager.cs +++ b/Assets/Scripts/Input/InputManager.cs @@ -49,8 +49,6 @@ namespace Input private ITouchInputConsumer defaultConsumer; private bool isHoldActive; private LogVerbosity _logVerbosity = LogVerbosity.Warning; - - public override int ManagedAwakePriority => 25; // Input infrastructure internal override void OnManagedAwake() { @@ -106,7 +104,7 @@ namespace Input SwitchInputOnSceneLoaded(sceneName); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { // Unsubscribe from SceneManagerService events if (SceneManagerService.Instance != null) @@ -114,7 +112,6 @@ namespace Input SceneManagerService.Instance.SceneLoadCompleted -= OnSceneLoadCompleted; } - base.OnDestroy(); // Input action cleanup happens automatically } diff --git a/Assets/Scripts/Input/PlayerTouchController.cs b/Assets/Scripts/Input/PlayerTouchController.cs index 1f00618d..39950db1 100644 --- a/Assets/Scripts/Input/PlayerTouchController.cs +++ b/Assets/Scripts/Input/PlayerTouchController.cs @@ -70,7 +70,6 @@ namespace Input public override bool AutoRegisterForSave => true; // Scene-specific SaveId - each level has its own player state public override string SaveId => $"{gameObject.scene.name}/PlayerController"; - public override int ManagedAwakePriority => 100; // Player controller internal override void OnManagedStart() { diff --git a/Assets/Scripts/Interactions/Interactable.cs b/Assets/Scripts/Interactions/Interactable.cs index 48eab9f7..d97f7c3a 100644 --- a/Assets/Scripts/Interactions/Interactable.cs +++ b/Assets/Scripts/Interactions/Interactable.cs @@ -41,9 +41,6 @@ namespace Interactions // Action component system private List _registeredActions = new List(); - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 100; // Gameplay base classes - /// /// Register an action component with this interactable diff --git a/Assets/Scripts/Interactions/ItemSlot.cs b/Assets/Scripts/Interactions/ItemSlot.cs index 2a12a251..659a601a 100644 --- a/Assets/Scripts/Interactions/ItemSlot.cs +++ b/Assets/Scripts/Interactions/ItemSlot.cs @@ -287,10 +287,8 @@ namespace Interactions ItemManager.Instance?.RegisterItemSlot(this); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unregister from slot manager ItemManager.Instance?.UnregisterItemSlot(this); } diff --git a/Assets/Scripts/Interactions/Pickup.cs b/Assets/Scripts/Interactions/Pickup.cs index 06abf497..4d0d7316 100644 --- a/Assets/Scripts/Interactions/Pickup.cs +++ b/Assets/Scripts/Interactions/Pickup.cs @@ -50,10 +50,8 @@ namespace Interactions ItemManager.Instance?.RegisterPickup(this); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unregister from ItemManager ItemManager.Instance?.UnregisterPickup(this); } diff --git a/Assets/Scripts/Levels/MinigameSwitch.cs b/Assets/Scripts/Levels/MinigameSwitch.cs index ed5b1754..5f1af48c 100644 --- a/Assets/Scripts/Levels/MinigameSwitch.cs +++ b/Assets/Scripts/Levels/MinigameSwitch.cs @@ -80,10 +80,8 @@ namespace Levels } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - if (PuzzleManager.Instance != null) { PuzzleManager.Instance.OnAllPuzzlesComplete -= HandleAllPuzzlesComplete; diff --git a/Assets/Scripts/Minigames/DivingForPictures/DivingGameManager.cs b/Assets/Scripts/Minigames/DivingForPictures/DivingGameManager.cs index 876b23a2..9739e700 100644 --- a/Assets/Scripts/Minigames/DivingForPictures/DivingGameManager.cs +++ b/Assets/Scripts/Minigames/DivingForPictures/DivingGameManager.cs @@ -104,7 +104,6 @@ namespace Minigames.DivingForPictures public static DivingGameManager Instance => _instance; - public override int ManagedAwakePriority => 190; public override bool AutoRegisterPausable => true; // Automatic GameManager registration internal override void OnManagedAwake() @@ -162,10 +161,8 @@ namespace Minigames.DivingForPictures } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); // Handles auto-unregister from GameManager - // Unsubscribe from events when the manager is destroyed PlayerCollisionBehavior.OnDamageTaken -= OnPlayerDamageTaken; OnMonsterSpawned -= DoMonsterSpawned; diff --git a/Assets/Scripts/Movement/FollowerController.cs b/Assets/Scripts/Movement/FollowerController.cs index 6a40abfe..9378d835 100644 --- a/Assets/Scripts/Movement/FollowerController.cs +++ b/Assets/Scripts/Movement/FollowerController.cs @@ -106,8 +106,6 @@ public class FollowerController : ManagedBehaviour private bool _hasRestoredHeldItem; // Track if held item restoration completed private string _expectedHeldItemSaveId; // Expected saveId during restoration - public override int ManagedAwakePriority => 110; // Follower after player - internal override void OnManagedStart() { _aiPath = GetComponent(); diff --git a/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs b/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs index db50ac6e..60828fde 100644 --- a/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs +++ b/Assets/Scripts/PuzzleS/ObjectiveStepBehaviour.cs @@ -83,10 +83,8 @@ namespace PuzzleS } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - if (PuzzleManager.Instance != null && stepData != null) { PuzzleManager.Instance.UnregisterStepBehaviour(this); diff --git a/Assets/Scripts/PuzzleS/PuzzleManager.cs b/Assets/Scripts/PuzzleS/PuzzleManager.cs index 44f6dc4f..981abe71 100644 --- a/Assets/Scripts/PuzzleS/PuzzleManager.cs +++ b/Assets/Scripts/PuzzleS/PuzzleManager.cs @@ -93,8 +93,6 @@ namespace PuzzleS // Track pending unlocks for steps that were unlocked before their behavior registered private HashSet _pendingUnlocks = new HashSet(); - - public override int ManagedAwakePriority => 80; // Puzzle systems internal override void OnManagedAwake() { @@ -138,10 +136,8 @@ namespace PuzzleS LoadPuzzlesForScene(sceneName); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unsubscribe from SceneManagerService events if (SceneManagerService.Instance != null) { diff --git a/Assets/Scripts/Sound/AudioManager.cs b/Assets/Scripts/Sound/AudioManager.cs index 5bc74244..890a49f4 100644 --- a/Assets/Scripts/Sound/AudioManager.cs +++ b/Assets/Scripts/Sound/AudioManager.cs @@ -40,8 +40,6 @@ public class AudioManager : ManagedBehaviour, IPausable /// public static AudioManager Instance => _instance; - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 30; // Audio infrastructure public override bool AutoRegisterPausable => true; // Auto-register as IPausable internal override void OnManagedAwake() diff --git a/Assets/Scripts/UI/AppSwitcher.cs b/Assets/Scripts/UI/AppSwitcher.cs index e7083b5f..581ec73e 100644 --- a/Assets/Scripts/UI/AppSwitcher.cs +++ b/Assets/Scripts/UI/AppSwitcher.cs @@ -110,10 +110,8 @@ public class AppSwitcher : UIPage ); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Clean up tweens slideInTween?.Stop(); slideOutTween?.Stop(); diff --git a/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs b/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs index e68e727b..628d7615 100644 --- a/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs +++ b/Assets/Scripts/UI/CardSystem/AlbumViewPage.cs @@ -149,7 +149,7 @@ namespace UI.CardSystem } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { // Unsubscribe from CardSystemManager if (CardSystemManager.Instance != null) @@ -181,9 +181,6 @@ namespace UI.CardSystem // Clean up active cards CleanupActiveCards(); - - // Call base implementation - base.OnDestroy(); } private void OnExitButtonClicked() diff --git a/Assets/Scripts/UI/CardSystem/BoosterNotificationDot.cs b/Assets/Scripts/UI/CardSystem/BoosterNotificationDot.cs index 564363c8..9eb3fe11 100644 --- a/Assets/Scripts/UI/CardSystem/BoosterNotificationDot.cs +++ b/Assets/Scripts/UI/CardSystem/BoosterNotificationDot.cs @@ -70,16 +70,13 @@ namespace UI.CardSystem } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { // Unsubscribe from CardSystemManager events to prevent memory leaks if (CardSystemManager.Instance != null) { CardSystemManager.Instance.OnBoosterCountChanged -= OnBoosterCountChanged; } - - // Call base implementation - base.OnDestroy(); } /// diff --git a/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs b/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs index 5998f090..6cc1af0f 100644 --- a/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs +++ b/Assets/Scripts/UI/CardSystem/BoosterOpeningPage.cs @@ -76,10 +76,8 @@ namespace UI.CardSystem gameObject.SetActive(false); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unsubscribe from dismiss button if (_dismissButton != null) { diff --git a/Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackVisual.cs b/Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackVisual.cs index f97cbe1f..27278b5d 100644 --- a/Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackVisual.cs +++ b/Assets/Scripts/UI/CardSystem/DragDrop/BoosterPackVisual.cs @@ -308,10 +308,8 @@ namespace UI.CardSystem.DragDrop #endregion - protected override void OnDestroy() + private void OnDestroy() { - base.OnDestroy(); - if (_boosterDraggable != null) { _boosterDraggable.OnBoosterOpened -= HandleBoosterOpened; diff --git a/Assets/Scripts/UI/CardSystem/DragDrop/CardDraggableVisual.cs b/Assets/Scripts/UI/CardSystem/DragDrop/CardDraggableVisual.cs index b9938668..2d8f4f68 100644 --- a/Assets/Scripts/UI/CardSystem/DragDrop/CardDraggableVisual.cs +++ b/Assets/Scripts/UI/CardSystem/DragDrop/CardDraggableVisual.cs @@ -107,10 +107,8 @@ namespace UI.CardSystem.DragDrop // Card-specific visual effects when dragging ends } - protected override void OnDestroy() + private void OnDestroy() { - base.OnDestroy(); - if (_cardDraggable != null) { _cardDraggable.OnCardDataChanged -= HandleCardDataChanged; diff --git a/Assets/Scripts/UI/Core/UIPage.cs b/Assets/Scripts/UI/Core/UIPage.cs index 853eac06..cde1a54e 100644 --- a/Assets/Scripts/UI/Core/UIPage.cs +++ b/Assets/Scripts/UI/Core/UIPage.cs @@ -15,9 +15,6 @@ namespace UI.Core [Header("Page Settings")] public string PageName; - // UI pages load after UI infrastructure (UIPageController is priority 50) - public override int ManagedAwakePriority => 200; - // Events using System.Action instead of UnityEvents public event Action OnTransitionInStarted; public event Action OnTransitionInCompleted; diff --git a/Assets/Scripts/UI/Core/UIPageController.cs b/Assets/Scripts/UI/Core/UIPageController.cs index 43b8e40c..a2b41ea3 100644 --- a/Assets/Scripts/UI/Core/UIPageController.cs +++ b/Assets/Scripts/UI/Core/UIPageController.cs @@ -37,8 +37,6 @@ namespace UI.Core private PlayerInput _playerInput; private InputAction _cancelAction; - public override int ManagedAwakePriority => 50; // UI infrastructure - internal override void OnManagedAwake() { // Set instance immediately (early initialization) @@ -50,10 +48,8 @@ namespace UI.Core Logging.Debug("[UIPageController] Initialized"); } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Clean up cached instances foreach (var cachedPage in _prefabInstanceCache.Values) { diff --git a/Assets/Scripts/UI/LoadingScreenController.cs b/Assets/Scripts/UI/LoadingScreenController.cs index 950a5fc9..f5e13fab 100644 --- a/Assets/Scripts/UI/LoadingScreenController.cs +++ b/Assets/Scripts/UI/LoadingScreenController.cs @@ -52,9 +52,6 @@ namespace UI /// Singleton instance of the LoadingScreenController. No longer creates an instance if one doesn't exist. /// public static LoadingScreenController Instance => _instance; - - // ManagedBehaviour configuration - public override int ManagedAwakePriority => 45; // UI infrastructure, before UIPageController internal override void OnManagedAwake() { diff --git a/Assets/Scripts/UI/PauseMenu.cs b/Assets/Scripts/UI/PauseMenu.cs index c69910c4..9e2e30b5 100644 --- a/Assets/Scripts/UI/PauseMenu.cs +++ b/Assets/Scripts/UI/PauseMenu.cs @@ -27,9 +27,6 @@ namespace UI [SerializeField] private UnityEngine.UI.Button devOptionsButton; [SerializeField] private GameObject mainOptionsContainer; [SerializeField] private GameObject devOptionsContainer; - - // After UIPageController (50) - public override int ManagedAwakePriority => 55; internal override void OnManagedAwake() { @@ -76,10 +73,8 @@ namespace UI // This only fires once for DontDestroyOnLoad objects, so we handle scene loads in OnManagedAwake } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unsubscribe when destroyed if (SceneManagerService.Instance != null) { diff --git a/Assets/Scripts/UI/PlayerHudManager.cs b/Assets/Scripts/UI/PlayerHudManager.cs index 06bde44f..b363d4a0 100644 --- a/Assets/Scripts/UI/PlayerHudManager.cs +++ b/Assets/Scripts/UI/PlayerHudManager.cs @@ -172,10 +172,8 @@ namespace UI } } - protected override void OnDestroy() + internal override void OnManagedDestroy() { - base.OnDestroy(); - // Unsubscribe from events if (_uiPageController != null) { diff --git a/Assets/Scripts/UI/Tutorial/DivingTutorial.cs b/Assets/Scripts/UI/Tutorial/DivingTutorial.cs index eb9fb8b8..42a3481a 100644 --- a/Assets/Scripts/UI/Tutorial/DivingTutorial.cs +++ b/Assets/Scripts/UI/Tutorial/DivingTutorial.cs @@ -30,7 +30,6 @@ namespace UI.Tutorial private bool _canAcceptInput; private Coroutine _waitLoopCoroutine; - public override int ManagedAwakePriority => 200; // Tutorial runs late, after other systems internal override void OnManagedStart() {