Rework of base interactables and managed behaviors
This commit is contained in:
committed by
Michal Pikulski
parent
00e1746ac4
commit
f88bd0e2c9
292
docs/bootstrapped_manager_initialization_review.md
Normal file
292
docs/bootstrapped_manager_initialization_review.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# Bootstrapped Manager Initialization Review - Summary
|
||||
|
||||
## Overview
|
||||
|
||||
Performed a comprehensive review of all bootstrapped singleton managers to ensure critical initialization happens in `Awake()` rather than `OnManagedAwake()`, making infrastructure available when other components' `OnManagedAwake()` runs.
|
||||
|
||||
## Key Principle
|
||||
|
||||
**Awake() = Infrastructure Setup**
|
||||
- Singleton instance registration
|
||||
- Critical service initialization (settings, scene tracking, input setup)
|
||||
- Component configuration
|
||||
- State that OTHER components depend on
|
||||
|
||||
**OnManagedAwake() = Dependent Initialization**
|
||||
- Initialization that depends on OTHER managers
|
||||
- Event subscriptions to other managers
|
||||
- Non-critical setup
|
||||
|
||||
## Managers Updated
|
||||
|
||||
### 1. GameManager (Priority 10) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- Settings provider creation
|
||||
- Settings initialization (InitializeSettings, InitializeDeveloperSettings)
|
||||
- Verbosity settings loading
|
||||
|
||||
**Rationale:** Other managers need settings in their OnManagedAwake(). Settings MUST be available early.
|
||||
|
||||
**Impact:** All other managers can now safely call `GameManager.GetSettingsObject<T>()` in their OnManagedAwake().
|
||||
|
||||
```csharp
|
||||
private new void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
// Create settings providers - CRITICAL for other managers
|
||||
SettingsProvider.Instance.gameObject.name = "Settings Provider";
|
||||
DeveloperSettingsProvider.Instance.gameObject.name = "Developer Settings Provider";
|
||||
|
||||
// Load all settings synchronously - CRITICAL infrastructure
|
||||
InitializeSettings();
|
||||
InitializeDeveloperSettings();
|
||||
|
||||
_settingsLogVerbosity = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().settingsLogVerbosity;
|
||||
_managerLogVerbosity = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().gameManagerLogVerbosity;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. SceneManagerService (Priority 15) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- Scene tracking initialization (InitializeCurrentSceneTracking)
|
||||
- Bootstrap scene loading
|
||||
|
||||
**Kept in OnManagedAwake():**
|
||||
- Loading screen reference (depends on LoadingScreenController instance)
|
||||
- Event setup (depends on loading screen)
|
||||
- Verbosity settings
|
||||
|
||||
**Rationale:** Scene tracking is critical state. Loading screen setup depends on LoadingScreenController's instance being set first.
|
||||
|
||||
```csharp
|
||||
private new void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
// Initialize current scene tracking - CRITICAL for scene management
|
||||
InitializeCurrentSceneTracking();
|
||||
|
||||
// Ensure BootstrapScene is loaded
|
||||
var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
|
||||
if (!bootstrap.isLoaded)
|
||||
{
|
||||
SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnManagedAwake()
|
||||
{
|
||||
// DEPENDS on LoadingScreenController instance
|
||||
_loadingScreen = LoadingScreenController.Instance;
|
||||
SetupLoadingScreenEvents();
|
||||
|
||||
_logVerbosity = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().sceneLogVerbosity;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. InputManager (Priority 25) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- Verbosity settings loading
|
||||
- Settings reference initialization
|
||||
- PlayerInput component setup
|
||||
- Input action subscriptions
|
||||
- Initial input mode setup
|
||||
|
||||
**Kept in OnManagedAwake():**
|
||||
- SceneManagerService event subscriptions (depends on SceneManagerService instance)
|
||||
|
||||
**Rationale:** Input system MUST be functional immediately. Event subscriptions to other managers wait until OnManagedAwake().
|
||||
|
||||
```csharp
|
||||
private new void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
// Load settings early (GameManager sets these up in its Awake)
|
||||
_logVerbosity = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().inputLogVerbosity;
|
||||
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
|
||||
|
||||
// Set up PlayerInput component and actions - CRITICAL for input to work
|
||||
playerInput = GetComponent<PlayerInput>();
|
||||
// ... set up actions and subscriptions
|
||||
|
||||
// Initialize input mode for current scene
|
||||
SwitchInputOnSceneLoaded(SceneManager.GetActiveScene().name);
|
||||
}
|
||||
|
||||
protected override void OnManagedAwake()
|
||||
{
|
||||
// DEPENDS on SceneManagerService instance
|
||||
if (SceneManagerService.Instance != null)
|
||||
{
|
||||
SceneManagerService.Instance.SceneLoadCompleted += OnSceneLoadCompleted;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. SaveLoadManager (Priority 20) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- Critical state initialization (IsSaveDataLoaded, IsRestoringState)
|
||||
|
||||
**Kept in OnManagedAwake():**
|
||||
- Discovery of saveables
|
||||
- Loading save data (depends on settings)
|
||||
|
||||
**Rationale:** State flags should be initialized immediately. Discovery and loading depend on settings and scene state.
|
||||
|
||||
```csharp
|
||||
private new void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
// Initialize critical state immediately
|
||||
IsSaveDataLoaded = false;
|
||||
IsRestoringState = false;
|
||||
}
|
||||
|
||||
protected override void OnManagedAwake()
|
||||
{
|
||||
// Discovery and loading depend on settings and scene state
|
||||
DiscoverInactiveSaveables("RestoreInEditor");
|
||||
if (DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().useSaveLoadSystem)
|
||||
{
|
||||
Load();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. LoadingScreenController (Priority 45) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- Container reference setup
|
||||
- Initial state (hidden, inactive)
|
||||
|
||||
**Rationale:** SceneManagerService (priority 15) needs to access LoadingScreenController.Instance in its OnManagedAwake(). The loading screen MUST be properly configured before that.
|
||||
|
||||
```csharp
|
||||
private new void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
// Set up container reference early
|
||||
if (loadingScreenContainer == null)
|
||||
loadingScreenContainer = gameObject;
|
||||
|
||||
// Ensure the loading screen is initially hidden
|
||||
if (loadingScreenContainer != null)
|
||||
{
|
||||
loadingScreenContainer.SetActive(false);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. PauseMenu (Priority 55) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- CanvasGroup component setup
|
||||
- Initial state (hidden, non-interactive)
|
||||
|
||||
**Kept in OnSceneReady():**
|
||||
- Event subscriptions to SceneManagerService and UIPageController
|
||||
|
||||
**Rationale:** Component configuration should happen immediately. Event subscriptions wait for scene ready.
|
||||
|
||||
### 7. SceneOrientationEnforcer (Priority 70) ✅
|
||||
|
||||
**Moved to Awake():**
|
||||
- Verbosity settings loading
|
||||
- Scene loaded event subscription
|
||||
- Initial orientation enforcement
|
||||
|
||||
**Rationale:** Orientation enforcement should start immediately when scenes load.
|
||||
|
||||
## Critical Dependencies Resolved
|
||||
|
||||
### Before This Review
|
||||
```
|
||||
SceneManagerService.OnManagedAwake() → tries to access LoadingScreenController.Instance
|
||||
→ NULL if LoadingScreenController.OnManagedAwake() hasn't run yet!
|
||||
```
|
||||
|
||||
### After This Review
|
||||
```
|
||||
All Awake() methods run (order doesn't matter):
|
||||
- GameManager.Awake() → Sets up settings
|
||||
- SceneManagerService.Awake() → Sets up scene tracking
|
||||
- InputManager.Awake() → Sets up input system
|
||||
- LoadingScreenController.Awake() → Sets up loading screen
|
||||
- etc.
|
||||
|
||||
Then OnManagedAwake() runs in priority order:
|
||||
- GameManager.OnManagedAwake() (10)
|
||||
- SceneManagerService.OnManagedAwake() (15) → LoadingScreenController.Instance is GUARANTEED available
|
||||
- InputManager.OnManagedAwake() (25) → SceneManagerService.Instance is GUARANTEED available
|
||||
- etc.
|
||||
```
|
||||
|
||||
## Design Guidelines Established
|
||||
|
||||
### What Goes in Awake()
|
||||
1. ✅ Singleton instance assignment (`_instance = this`)
|
||||
2. ✅ Critical infrastructure (settings, scene tracking)
|
||||
3. ✅ Component setup (`GetComponent`, initial state)
|
||||
4. ✅ State initialization that others depend on
|
||||
5. ✅ Subscriptions to Unity events (SceneManager.sceneLoaded)
|
||||
|
||||
### What Goes in OnManagedAwake()
|
||||
1. ✅ Event subscriptions to OTHER managers
|
||||
2. ✅ Initialization that depends on settings
|
||||
3. ✅ Non-critical setup
|
||||
4. ✅ Logging (depends on settings)
|
||||
|
||||
### What Stays in OnSceneReady()
|
||||
1. ✅ Scene-specific initialization
|
||||
2. ✅ Event subscriptions that are scene-dependent
|
||||
|
||||
## Compilation Status
|
||||
|
||||
✅ **No compilation errors**
|
||||
⚠️ **Only pre-existing naming convention warnings**
|
||||
|
||||
## Impact
|
||||
|
||||
### Before
|
||||
- Race conditions possible if managers accessed each other's instances
|
||||
- Settings might not be available when needed
|
||||
- Input system might not be configured when accessed
|
||||
- Loading screen might not be set up when SceneManagerService needs it
|
||||
|
||||
### After
|
||||
- All critical infrastructure guaranteed available in OnManagedAwake()
|
||||
- Settings always available for all managers
|
||||
- Input system always functional
|
||||
- Loading screen always configured
|
||||
- Clean separation: Awake = infrastructure, OnManagedAwake = orchestration
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
1. ✅ Test boot sequence from StartingScene
|
||||
2. ✅ Test level switching via LevelSwitch
|
||||
3. ✅ Verify loading screen shows correctly
|
||||
4. ✅ Verify input works after scene loads
|
||||
5. ✅ Check console for any null reference exceptions
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. GameManager.cs
|
||||
2. SceneManagerService.cs
|
||||
3. InputManager.cs
|
||||
4. SaveLoadManager.cs
|
||||
5. LoadingScreenController.cs
|
||||
6. PauseMenu.cs
|
||||
7. SceneOrientationEnforcer.cs
|
||||
|
||||
---
|
||||
|
||||
**Status**: ✅ COMPLETE - All bootstrapped managers properly initialized with correct Awake/OnManagedAwake separation
|
||||
|
||||
Reference in New Issue
Block a user