1437 lines
51 KiB
Markdown
1437 lines
51 KiB
Markdown
|
|
# ManagedBehaviour Lifecycle System - Implementation Guide
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
This document provides a step-by-step implementation plan for creating a custom lifecycle management system that extends MonoBehaviour with deterministic, ordered lifecycle hooks. The system integrates with existing bootstrap, scene management, save/load, and game state management infrastructure.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Current System Analysis
|
||
|
|
|
||
|
|
### Existing Lifecycle Flow
|
||
|
|
1. **Unity Bootstrap Phase**
|
||
|
|
- `RuntimeInitializeOnLoadMethod(BeforeSplashScreen)` → `CustomBoot.Initialise()`
|
||
|
|
- Loads CustomBootSettings via Addressables
|
||
|
|
- BootstrapScene loads with initial GameObjects
|
||
|
|
|
||
|
|
2. **Unity Standard Lifecycle**
|
||
|
|
- `Awake()` - All MonoBehaviours (unordered within frame)
|
||
|
|
- `OnEnable()` - After Awake phase
|
||
|
|
- `Start()` - After OnEnable phase
|
||
|
|
- Game loop: `Update()`, `FixedUpdate()`, `LateUpdate()`
|
||
|
|
|
||
|
|
3. **Custom Bootstrap Integration**
|
||
|
|
- Components register with `BootCompletionService.RegisterInitAction()` in `Awake()`
|
||
|
|
- `CustomBoot` completes → triggers `BootCompletionService.HandleBootCompleted()`
|
||
|
|
- `BootCompletionService` executes registered actions (priority-sorted, 0-1000+)
|
||
|
|
- Components implement `InitializePostBoot()` methods
|
||
|
|
|
||
|
|
4. **Scene Lifecycle Integration**
|
||
|
|
- `SceneManagerService` manages additive scene loading/unloading
|
||
|
|
- Components subscribe to `SceneLoadCompleted` and `SceneUnloadStarted` events
|
||
|
|
- `SceneManagerService.SwitchSceneAsync()` handles scene transitions
|
||
|
|
|
||
|
|
5. **Save/Load System**
|
||
|
|
- `SaveLoadManager` maintains registry of `ISaveParticipant` components
|
||
|
|
- Components call `RegisterParticipant()` in post-boot initialization
|
||
|
|
- Components call `UnregisterParticipant()` in `OnDestroy()`
|
||
|
|
- State restoration happens after load or when new participants register
|
||
|
|
|
||
|
|
6. **Game State Management (GameManager)**
|
||
|
|
- Pause/Resume system with counter-based requests
|
||
|
|
- `IPausable` component registration (manual Subscribe/Unsubscribe)
|
||
|
|
- Settings initialization (ServiceLocator pattern)
|
||
|
|
- Developer settings integration
|
||
|
|
|
||
|
|
### Existing Patterns
|
||
|
|
- **Singleton Pattern**: All managers use `_instance` field with `Instance` property
|
||
|
|
- **Two-Phase Init**: `Awake()` + `InitializePostBoot()`
|
||
|
|
- **Priority-Based Boot**: Components specify boot priority (10-100+, lower = earlier)
|
||
|
|
- **Manual Event Management**: Subscribe in OnEnable/Start, unsubscribe in OnDestroy
|
||
|
|
- **Inheritance Example**: `InteractionActionBase` provides `protected virtual` lifecycle hooks
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Architecture Design
|
||
|
|
|
||
|
|
### Core Components
|
||
|
|
|
||
|
|
#### 1. LifecycleManager (Singleton)
|
||
|
|
Central orchestrator that:
|
||
|
|
- Maintains registries of all ManagedBehaviours (separate lists per lifecycle phase)
|
||
|
|
- Broadcasts lifecycle events in priority-sorted order
|
||
|
|
- Integrates with BootCompletionService, SceneManagerService, SaveLoadManager, GameManager
|
||
|
|
- Handles late registration and edge cases
|
||
|
|
- Provides optional debug/profiling tools
|
||
|
|
|
||
|
|
#### 2. ManagedBehaviour (Base Class)
|
||
|
|
Enhanced MonoBehaviour providing:
|
||
|
|
- Virtual lifecycle hooks (opt-in via override)
|
||
|
|
- Automatic registration/unregistration with LifecycleManager
|
||
|
|
- Priority/ordering support via properties
|
||
|
|
- Built-in managed event subscription system (auto-cleanup)
|
||
|
|
- Optional auto-integration with SaveLoadManager and GameManager
|
||
|
|
|
||
|
|
#### 3. ManagedEvent System
|
||
|
|
Helper system for automatic event subscription cleanup:
|
||
|
|
- Stores event subscriptions internally
|
||
|
|
- Auto-unsubscribes all events on destruction
|
||
|
|
- Prevents memory leaks and manual cleanup
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Lifecycle Phases
|
||
|
|
|
||
|
|
### Complete Lifecycle Flow
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 1: UNITY ENGINE BOOTSTRAP │
|
||
|
|
│ - RuntimeInitializeOnLoadMethod (CustomBoot.Initialise) │
|
||
|
|
│ - BootstrapScene loads │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 2: UNITY STANDARD LIFECYCLE │
|
||
|
|
│ - Unity Awake() [all MonoBehaviours] │
|
||
|
|
│ └→ ManagedBehaviour.Awake() auto-registers with Manager │
|
||
|
|
│ - Unity OnEnable() │
|
||
|
|
│ - Unity Start() │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 3: MANAGED AWAKE (Deterministic) │
|
||
|
|
│ - LifecycleManager.BroadcastManagedAwake() │
|
||
|
|
│ - Calls OnManagedAwake() in priority order (0→1000) │
|
||
|
|
│ - Singleton initialization, component setup │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 4: BOOT COMPLETION │
|
||
|
|
│ - CustomBoot completes │
|
||
|
|
│ - BootCompletionService.HandleBootCompleted() │
|
||
|
|
│ - LifecycleManager.BroadcastBootComplete() │
|
||
|
|
│ - Calls OnBootComplete() in priority order │
|
||
|
|
│ - Settings loaded, services initialized │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 5: SCENE READY │
|
||
|
|
│ - SceneManagerService finishes loading │
|
||
|
|
│ - LifecycleManager.BroadcastSceneReady() │
|
||
|
|
│ - Calls OnSceneReady() for all active ManagedBehaviours │
|
||
|
|
│ - Scene-specific initialization │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 6: GAME LOOP (Runtime) │
|
||
|
|
│ - Unity Update/FixedUpdate/LateUpdate │
|
||
|
|
│ - Optional: OnManagedUpdate() (priority-ordered) │
|
||
|
|
│ - Optional: OnManagedFixedUpdate() (priority-ordered) │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 7: PAUSE/RESUME (State Change) │
|
||
|
|
│ - GameManager.RequestPause() / ReleasePause() │
|
||
|
|
│ - LifecycleManager.BroadcastPause/Resume() │
|
||
|
|
│ - Calls OnPaused() / OnResumed() for all active │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 8: SCENE UNLOADING (Transition) │
|
||
|
|
│ - SceneManagerService.SwitchSceneAsync() starts │
|
||
|
|
│ - LifecycleManager.BroadcastSceneUnloading() │
|
||
|
|
│ - Calls OnSceneUnloading() for scene-specific components │
|
||
|
|
│ - Cleanup before scene unload │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
↓
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ PHASE 9: DESTRUCTION │
|
||
|
|
│ - Unity OnDisable() │
|
||
|
|
│ - Unity OnDestroy() │
|
||
|
|
│ └→ ManagedBehaviour.OnDestroy() auto-unregisters │
|
||
|
|
│ - LifecycleManager.BroadcastManagedDestroy() │
|
||
|
|
│ - Calls OnManagedDestroy() in reverse priority order │
|
||
|
|
│ - Auto-cleanup of managed events │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### Lifecycle Hook Reference
|
||
|
|
| Hook Name | Priority Order | When Called | Use Case |
|
||
|
|
|-----------|----------------|-------------|----------|
|
||
|
|
| `OnManagedAwake()` | Low→High (0→∞) | After Unity Awake, before Start | Deterministic initialization |
|
||
|
|
| `OnBootComplete()` | Low→High (0→∞) | After CustomBoot completes | Post-boot initialization (replaces InitializePostBoot) |
|
||
|
|
| `OnSceneReady()` | Low→High (0→∞) | After scene fully loaded | Scene-specific setup |
|
||
|
|
| `OnManagedUpdate()` | Low→High (0→∞) | Every frame (optional) | Ordered per-frame logic |
|
||
|
|
| `OnManagedFixedUpdate()` | Low→High (0→∞) | Every physics frame (optional) | Ordered physics logic |
|
||
|
|
| `OnPaused()` | Low→High (0→∞) | When game pauses | Pause state handling |
|
||
|
|
| `OnResumed()` | Low→High (0→∞) | When game resumes | Resume state handling |
|
||
|
|
| `OnSceneUnloading()` | High→Low (∞→0) | Before scene unloads | Scene cleanup |
|
||
|
|
| `OnManagedDestroy()` | High→Low (∞→0) | Before Unity OnDestroy | Guaranteed cleanup |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Implementation Steps
|
||
|
|
|
||
|
|
### STEP 1: Create Core Enums and Interfaces
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleEnums.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create namespace `Core.Lifecycle`
|
||
|
|
2. Define `LifecyclePhase` enum with all phases
|
||
|
|
3. Define `LifecycleFlags` enum for component opt-in (bitflags)
|
||
|
|
4. Add XML documentation for each value
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- LifecyclePhase: ManagedAwake, BootComplete, SceneReady, Update, FixedUpdate, Paused, Resumed, SceneUnloading, ManagedDestroy
|
||
|
|
- LifecycleFlags: None, ManagedAwake, BootComplete, SceneReady, ManagedUpdate, ManagedFixedUpdate, Pause, SceneUnloading, ManagedDestroy, All (bitwise OR of all)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 2: Create ManagedEvent System
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/ManagedEventSubscription.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create internal struct `ManagedEventSubscription` to store event delegate and target
|
||
|
|
2. Create class `ManagedEventManager` with:
|
||
|
|
- List of subscriptions per ManagedBehaviour
|
||
|
|
- `RegisterEvent<T>(target, action)` method
|
||
|
|
- `UnregisterAllEvents()` method that invokes `-=` on all stored subscriptions
|
||
|
|
3. Handle both `Action` and generic `Action<T>` delegates
|
||
|
|
4. Use reflection to dynamically unsubscribe
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Store event info as: object target (event owner), Delegate handler, string eventName
|
||
|
|
- Support common Unity event patterns (Action, Action\<T\>, UnityEvent, etc.)
|
||
|
|
- Provide safe null checks before unsubscribing
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 3: Create ManagedBehaviour Base Class (Structure)
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create abstract class `ManagedBehaviour : MonoBehaviour`
|
||
|
|
2. Add virtual properties for priorities:
|
||
|
|
- `ManagedAwakePriority` (default 100)
|
||
|
|
- `BootCompletePriority` (default 100)
|
||
|
|
- `SceneReadyPriority` (default 100)
|
||
|
|
- `UpdatePriority` (default 100)
|
||
|
|
- `DestroyPriority` (default 100)
|
||
|
|
3. Add property `ActiveLifecyclePhases` (returns LifecycleFlags, default None)
|
||
|
|
4. Add property `AutoRegisterSaveParticipant` (default false)
|
||
|
|
5. Add property `AutoRegisterPausable` (default false)
|
||
|
|
6. Add property `IsPersistent` (default false) - survives scene changes
|
||
|
|
7. Add private field `ManagedEventManager _eventManager`
|
||
|
|
8. Add private bool `_isRegistered` to track registration state
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- All priority properties are virtual so subclasses can override
|
||
|
|
- ActiveLifecyclePhases determines which hooks are called (opt-in)
|
||
|
|
- IsPersistent flag controls whether component persists across scenes
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 4: Implement ManagedBehaviour Lifecycle Hooks (Virtual Methods)
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Add virtual protected methods (empty by default):
|
||
|
|
- `OnManagedAwake()`
|
||
|
|
- `OnBootComplete()`
|
||
|
|
- `OnSceneReady()`
|
||
|
|
- `OnManagedUpdate()`
|
||
|
|
- `OnManagedFixedUpdate()`
|
||
|
|
- `OnPaused()`
|
||
|
|
- `OnResumed()`
|
||
|
|
- `OnSceneUnloading()`
|
||
|
|
- `OnManagedDestroy()`
|
||
|
|
2. Add XML documentation for each method
|
||
|
|
3. Add protected helper methods:
|
||
|
|
- `RegisterManagedEvent<T>(target, action)` - wraps _eventManager
|
||
|
|
- `IsLifecyclePhaseActive(LifecyclePhase)` - checks flags
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- All hooks are `protected virtual void` (no return value)
|
||
|
|
- Empty implementations allow opt-in override pattern
|
||
|
|
- Use `[Conditional("UNITY_EDITOR")]` attribute for debug-only hooks if needed
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 5: Implement ManagedBehaviour Unity Integration
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Implement `protected virtual void Awake()`:
|
||
|
|
- Initialize _eventManager
|
||
|
|
- Register with LifecycleManager (call `LifecycleManager.Instance.Register(this)`)
|
||
|
|
- Set _isRegistered = true
|
||
|
|
2. Implement `protected virtual void OnDestroy()`:
|
||
|
|
- Unregister from LifecycleManager (call `LifecycleManager.Instance.Unregister(this)`)
|
||
|
|
- Call _eventManager.UnregisterAllEvents()
|
||
|
|
- Auto-unregister from SaveLoadManager and GameManager if applicable
|
||
|
|
- Set _isRegistered = false
|
||
|
|
3. Make both methods call base implementation warning (for subclasses)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Use null checks for LifecycleManager.Instance (may not exist during shutdown)
|
||
|
|
- Provide clear error logging if registration fails
|
||
|
|
- Support scenario where subclass overrides Awake/OnDestroy (must call base)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 6: Create LifecycleManager (Structure)
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create class `LifecycleManager : MonoBehaviour`
|
||
|
|
2. Implement singleton pattern (private static _instance, public static Instance)
|
||
|
|
3. Add separate `List<ManagedBehaviour>` for each lifecycle phase:
|
||
|
|
- `_managedAwakeList`
|
||
|
|
- `_bootCompleteList`
|
||
|
|
- `_sceneReadyList`
|
||
|
|
- `_updateList`
|
||
|
|
- `_fixedUpdateList`
|
||
|
|
- `_pauseList`
|
||
|
|
- `_sceneUnloadingList`
|
||
|
|
- `_destroyList`
|
||
|
|
4. Add Dictionary<ManagedBehaviour, int> for tracking which lists each component is in (bitmask)
|
||
|
|
5. Add bool flags: `_isBootComplete`, `_isSceneReady`, `_isPaused`
|
||
|
|
6. Add queue for late registrations: `Queue<ManagedBehaviour> _pendingRegistrations`
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Each list must be kept sorted by priority
|
||
|
|
- Use SortedList or List with manual sorting after registration
|
||
|
|
- Dictionary tracks which phases each component participates in
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 7: Implement LifecycleManager Registration System
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Implement `public void Register(ManagedBehaviour component)`:
|
||
|
|
- Check component.ActiveLifecyclePhases flags
|
||
|
|
- Add to appropriate lists based on flags
|
||
|
|
- Insert in priority-sorted position
|
||
|
|
- Handle auto-registration with SaveLoadManager if component is ISaveParticipant && AutoRegisterSaveParticipant
|
||
|
|
- Handle auto-registration with GameManager if component is IPausable && AutoRegisterPausable
|
||
|
|
- If boot already complete and component has BootComplete flag, immediately call OnBootComplete
|
||
|
|
- If scene already ready and component has SceneReady flag, immediately call OnSceneReady
|
||
|
|
2. Implement `public void Unregister(ManagedBehaviour component)`:
|
||
|
|
- Remove from all lists
|
||
|
|
- Handle auto-unregistration from SaveLoadManager and GameManager
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Use binary search for insertion point (lists sorted by priority)
|
||
|
|
- Handle edge case: registration during broadcast (queue and process later)
|
||
|
|
- Validate component is not null and has valid priorities
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 8: Implement LifecycleManager Broadcast System
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Implement broadcast methods for each phase:
|
||
|
|
- `BroadcastManagedAwake()`
|
||
|
|
- `BroadcastBootComplete()`
|
||
|
|
- `BroadcastSceneReady()`
|
||
|
|
- `BroadcastPause()`
|
||
|
|
- `BroadcastResume()`
|
||
|
|
- `BroadcastSceneUnloading()`
|
||
|
|
- `BroadcastManagedDestroy()`
|
||
|
|
2. Each method iterates through corresponding list and calls hook
|
||
|
|
3. Add try-catch around each call with error logging
|
||
|
|
4. Process pending registrations after broadcast completes
|
||
|
|
5. Set state flags (_isBootComplete, _isSceneReady, _isPaused)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Iterate forward for normal phases (low→high priority)
|
||
|
|
- Iterate backward for cleanup phases (SceneUnloading, ManagedDestroy)
|
||
|
|
- Use `for` loop with index (not foreach) to handle list modifications
|
||
|
|
- Log phase start/end with timing info (use Stopwatch)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 9: Implement LifecycleManager Update Handlers
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Implement `void Update()`:
|
||
|
|
- Check if _updateList is empty (skip if so)
|
||
|
|
- Iterate _updateList and call OnManagedUpdate() on each
|
||
|
|
- Add try-catch with error logging
|
||
|
|
2. Implement `void FixedUpdate()`:
|
||
|
|
- Check if _fixedUpdateList is empty (skip if so)
|
||
|
|
- Iterate _fixedUpdateList and call OnManagedFixedUpdate() on each
|
||
|
|
- Add try-catch with error logging
|
||
|
|
3. Add optimization: disable Update/FixedUpdate when lists are empty
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Use `enabled = false` when no components registered for updates
|
||
|
|
- Re-enable when first component registers
|
||
|
|
- Consider pooling/caching for performance
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 10: Integrate LifecycleManager with Bootstrap
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. In `Awake()`:
|
||
|
|
- Set singleton instance
|
||
|
|
- Subscribe to BootCompletionService.OnBootComplete
|
||
|
|
- Set up initial state
|
||
|
|
2. Implement handler for `BootCompletionService.OnBootComplete`:
|
||
|
|
- Set _isBootComplete = true
|
||
|
|
- Call BroadcastManagedAwake() first (if not already called)
|
||
|
|
- Then call BroadcastBootComplete()
|
||
|
|
3. Add `Start()` method:
|
||
|
|
- Call BroadcastManagedAwake() if boot not complete yet (fallback)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- LifecycleManager should exist in BootstrapScene (persistent)
|
||
|
|
- Must handle both editor and runtime initialization
|
||
|
|
- Consider RuntimeInitializeOnLoadMethod for creation if needed
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 11: Integrate LifecycleManager with SceneManagerService
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. In post-boot initialization:
|
||
|
|
- Subscribe to SceneManagerService.Instance.SceneLoadCompleted
|
||
|
|
- Subscribe to SceneManagerService.Instance.SceneUnloadStarted
|
||
|
|
2. Implement handler for `SceneLoadCompleted`:
|
||
|
|
- Set _isSceneReady = true
|
||
|
|
- Call BroadcastSceneReady()
|
||
|
|
- Handle scene-specific vs persistent components (check IsPersistent flag)
|
||
|
|
3. Implement handler for `SceneUnloadStarted`:
|
||
|
|
- Set _isSceneReady = false
|
||
|
|
- Call BroadcastSceneUnloading()
|
||
|
|
- Only call on scene-specific components (IsPersistent = false)
|
||
|
|
4. In `OnDestroy()`:
|
||
|
|
- Unsubscribe from all events
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Track which scene each component belongs to (use component.gameObject.scene)
|
||
|
|
- Only broadcast SceneReady/Unloading to components in affected scene
|
||
|
|
- Persistent components (BootstrapScene) should not receive scene lifecycle events
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 12: Integrate LifecycleManager with GameManager (Pause System)
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. In post-boot initialization:
|
||
|
|
- Subscribe to GameManager.Instance.OnGamePaused
|
||
|
|
- Subscribe to GameManager.Instance.OnGameResumed
|
||
|
|
2. Implement handler for `OnGamePaused`:
|
||
|
|
- Set _isPaused = true
|
||
|
|
- Call BroadcastPause()
|
||
|
|
3. Implement handler for `OnGameResumed`:
|
||
|
|
- Set _isPaused = false
|
||
|
|
- Call BroadcastResume()
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Components can opt-in to pause events via ActiveLifecyclePhases flags
|
||
|
|
- BroadcastPause/Resume iterates _pauseList only
|
||
|
|
- Late-registered components get immediate pause state if game is paused
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 13: Add Debug and Profiling Tools
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs` (continued)
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Add `[SerializeField] private bool enableDebugLogging = false`
|
||
|
|
2. Add `[SerializeField] private bool enableProfilingMarkers = true`
|
||
|
|
3. Create LogDebugMessage() helper that checks flag
|
||
|
|
4. Add Unity Profiler markers around each broadcast phase
|
||
|
|
5. Implement GetRegisteredComponents() method for inspector/debugging
|
||
|
|
6. Add OnGUI() debug overlay showing:
|
||
|
|
- Registered component counts per phase
|
||
|
|
- Current lifecycle state flags
|
||
|
|
- Last broadcast timings
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Use `UnityEngine.Profiling.ProfilerMarker` for zero-cost profiling in builds
|
||
|
|
- Debug overlay only active in editor or development builds
|
||
|
|
- Consider creating custom inspector for LifecycleManager
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 14: Create LifecycleManager Prefab
|
||
|
|
**File**: `Assets/Prefabs/Core/LifecycleManager.prefab`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create empty GameObject named "LifecycleManager"
|
||
|
|
2. Add LifecycleManager component
|
||
|
|
3. Configure default settings (debug logging off, profiling on)
|
||
|
|
4. Save as prefab
|
||
|
|
5. Add to BootstrapScene if not already present
|
||
|
|
6. Verify it persists across scenes (should be in BootstrapScene which is additive)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Only one instance should exist (singleton)
|
||
|
|
- Should be in BootstrapScene, not in gameplay scenes
|
||
|
|
- Consider adding validation script to prevent duplicates
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 15: Update Bootstrap Integration
|
||
|
|
**File**: `Assets/Scripts/Bootstrap/BootCompletionService.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. In `HandleBootCompleted()` method, add:
|
||
|
|
- Before executing initialization actions, notify LifecycleManager
|
||
|
|
- Call `LifecycleManager.Instance?.OnBootCompletionStarting()` (new method)
|
||
|
|
2. After initialization actions complete:
|
||
|
|
- Call existing `OnBootComplete?.Invoke()`
|
||
|
|
- LifecycleManager handles this via event subscription
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Bootstrap/CustomBoot.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Verify LifecycleManager exists before CustomBoot completes
|
||
|
|
2. Add fallback: if LifecycleManager doesn't exist, log warning
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- BootCompletionService remains authoritative for boot completion
|
||
|
|
- LifecycleManager observes and broadcasts to ManagedBehaviours
|
||
|
|
- Maintain backward compatibility with existing RegisterInitAction pattern
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 16: Extend SaveLoadManager Integration
|
||
|
|
**File**: `Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Add public method `AutoRegisterParticipant(ISaveParticipant participant, ManagedBehaviour owner)`:
|
||
|
|
- Same as RegisterParticipant but stores reference to owner ManagedBehaviour
|
||
|
|
- Allows automatic unregistration when owner is destroyed
|
||
|
|
2. Add public method `AutoUnregisterParticipant(ManagedBehaviour owner)`:
|
||
|
|
- Looks up participant by owner reference and unregisters
|
||
|
|
3. Store Dictionary<ManagedBehaviour, string> to track auto-registrations
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. In Awake() registration:
|
||
|
|
- Check if `this is ISaveParticipant` and `AutoRegisterSaveParticipant == true`
|
||
|
|
- If yes, call SaveLoadManager.Instance.AutoRegisterParticipant(this as ISaveParticipant, this)
|
||
|
|
2. In OnDestroy() cleanup:
|
||
|
|
- Call SaveLoadManager.Instance.AutoUnregisterParticipant(this)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Only auto-register after boot completes (SaveLoadManager must be initialized)
|
||
|
|
- Handle null checks (SaveLoadManager may not exist in editor)
|
||
|
|
- Log when auto-registration occurs (debug mode)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 17: Extend GameManager Pausable Integration
|
||
|
|
**File**: `Assets/Scripts/Core/GameManager.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Add public method `AutoRegisterPausable(IPausable component, ManagedBehaviour owner)`:
|
||
|
|
- Same as RegisterPausableComponent but stores owner reference
|
||
|
|
2. Add public method `AutoUnregisterPausable(ManagedBehaviour owner)`:
|
||
|
|
- Looks up pausable by owner and unregisters
|
||
|
|
3. Store Dictionary<ManagedBehaviour, IPausable> to track auto-registrations
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. In post-boot registration (called by LifecycleManager):
|
||
|
|
- Check if `this is IPausable` and `AutoRegisterPausable == true`
|
||
|
|
- If yes, call GameManager.Instance.AutoRegisterPausable(this as IPausable, this)
|
||
|
|
2. In OnDestroy() cleanup:
|
||
|
|
- Call GameManager.Instance.AutoUnregisterPausable(this)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Wait until boot completes before registering with GameManager
|
||
|
|
- Handle case where component implements both ISaveParticipant and IPausable
|
||
|
|
- Verify GameManager exists before calling
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 18: Create Migration Helper Attribute
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/RequiresManagedBehaviourAttribute.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create custom attribute `[RequiresManagedBehaviour]`
|
||
|
|
2. Can be applied to classes that should be converted to ManagedBehaviour
|
||
|
|
3. Create custom inspector that shows warning if class derives from MonoBehaviour instead
|
||
|
|
|
||
|
|
**File**: `Assets/Editor/ManagedBehaviourValidation.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create editor script that scans project for components with attribute
|
||
|
|
2. Shows list of components needing migration
|
||
|
|
3. Provides "Convert to ManagedBehaviour" button for each
|
||
|
|
4. Automatic string replacement in source files
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Editor-only functionality (Assets/Editor folder)
|
||
|
|
- Use AssetDatabase to find and modify scripts
|
||
|
|
- Show before/after preview before conversion
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 19: Create Example ManagedBehaviour Implementations
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/Examples/ExampleManagedSingleton.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create example showing singleton pattern with ManagedBehaviour
|
||
|
|
2. Demonstrate priority usage
|
||
|
|
3. Show lifecycle hook overrides
|
||
|
|
4. Include code comments explaining each part
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/Examples/ExampleManagedComponent.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create example showing scene-specific component
|
||
|
|
2. Demonstrate managed event subscription
|
||
|
|
3. Show auto-save participant integration
|
||
|
|
4. Show auto-pausable integration
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/Examples/ExampleManagedManager.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create example showing persistent manager
|
||
|
|
2. Demonstrate all lifecycle phases
|
||
|
|
3. Show priority ordering
|
||
|
|
4. Include performance considerations
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Well-commented code for reference
|
||
|
|
- Cover common use cases (singleton, scene component, manager)
|
||
|
|
- Include unit tests if applicable
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 20: Migrate Core Systems (Phase 1)
|
||
|
|
**Priority Order**: GameManager → SceneManagerService → SaveLoadManager → InputManager
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Core/GameManager.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Change class declaration: `public class GameManager : ManagedBehaviour`
|
||
|
|
2. Override properties:
|
||
|
|
- `protected override int ManagedAwakePriority => 10;` (very early)
|
||
|
|
- `protected override int BootCompletePriority => 10;`
|
||
|
|
3. Remove `BootCompletionService.RegisterInitAction(InitializePostBoot)` from Awake
|
||
|
|
4. Rename `InitializePostBoot()` to `protected override void OnBootComplete()`
|
||
|
|
5. Move Awake logic to `protected override void OnManagedAwake()`
|
||
|
|
6. Add `protected override LifecycleFlags ActiveLifecyclePhases => LifecycleFlags.ManagedAwake | LifecycleFlags.BootComplete;`
|
||
|
|
7. Keep existing pause/resume system (don't double-integrate)
|
||
|
|
8. Remove manual singleton setup (handled by base class)
|
||
|
|
9. Test thoroughly
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- GameManager initializes early (priority 10)
|
||
|
|
- Keep existing functionality intact
|
||
|
|
- Verify settings loading still works
|
||
|
|
- Ensure pause system integration works
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 21: Migrate Core Systems (Phase 2)
|
||
|
|
**Target**: SceneManagerService, SaveLoadManager, InputManager, ItemManager
|
||
|
|
|
||
|
|
**For Each File**:
|
||
|
|
1. Change base class to ManagedBehaviour
|
||
|
|
2. Set appropriate priorities (15-30 range)
|
||
|
|
3. Move InitializePostBoot → OnBootComplete
|
||
|
|
4. Remove manual BootCompletionService registration
|
||
|
|
5. Add ActiveLifecyclePhases flags
|
||
|
|
6. Test scene transitions, save/load, input handling
|
||
|
|
|
||
|
|
**Priorities**:
|
||
|
|
- SceneManagerService: 15 (after GameManager)
|
||
|
|
- SaveLoadManager: 20 (after SceneManagerService)
|
||
|
|
- InputManager: 25 (after SaveLoadManager)
|
||
|
|
- ItemManager: 30 (general manager)
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Verify event subscriptions still work
|
||
|
|
- Check scene loading/unloading
|
||
|
|
- Validate save/load system
|
||
|
|
- Test input handling in different modes
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 22: Migrate UI Systems
|
||
|
|
**Target**: UIPageController, LoadingScreenController, PauseMenu, CardSystemUI components
|
||
|
|
|
||
|
|
**For Each File**:
|
||
|
|
1. Change base class to ManagedBehaviour
|
||
|
|
2. Set priority 50-100 (standard range)
|
||
|
|
3. Convert InitializePostBoot → OnBootComplete
|
||
|
|
4. Use RegisterManagedEvent for event subscriptions
|
||
|
|
5. Add OnSceneReady override if needed for scene-specific UI
|
||
|
|
6. Test UI navigation, loading screens, pause menu
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- UI generally has lower priority than managers
|
||
|
|
- Scene-specific UI should override OnSceneReady
|
||
|
|
- Use AutoRegisterSaveParticipant for UI with state
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 23: Migrate Gameplay Systems
|
||
|
|
**Target**: PuzzleManager, DivingGameManager, CinematicsManager, CardSystemManager
|
||
|
|
|
||
|
|
**For Each File**:
|
||
|
|
1. Change base class to ManagedBehaviour
|
||
|
|
2. Set priority 100-200 (gameplay systems)
|
||
|
|
3. Convert InitializePostBoot → OnBootComplete
|
||
|
|
4. Use OnSceneReady for scene-specific setup
|
||
|
|
5. Use OnSceneUnloading for cleanup
|
||
|
|
6. Consider AutoRegisterSaveParticipant
|
||
|
|
7. Test gameplay features
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Scene-specific managers should handle OnSceneReady/Unloading
|
||
|
|
- Persistent managers (like CardSystemManager) set IsPersistent = true
|
||
|
|
- Verify minigame transitions work correctly
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 24: Migrate Interaction Systems
|
||
|
|
**Target**: Interactable, InteractionActionBase, DialogueComponent
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Interactions/InteractionActionBase.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Change base class from MonoBehaviour to ManagedBehaviour
|
||
|
|
2. Change `protected virtual void Awake()` to `protected override void OnManagedAwake()`
|
||
|
|
3. Keep OnEnable/OnDisable as-is (Unity lifecycle needed for enable/disable)
|
||
|
|
4. Consider using RegisterManagedEvent for parentInteractable events
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- InteractionActionBase is itself a base class (virtual methods remain)
|
||
|
|
- Subclasses inherit ManagedBehaviour capabilities
|
||
|
|
- Test interaction flow thoroughly
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 25: Migrate Player and Movement Systems
|
||
|
|
**Target**: PlayerTouchController, FollowerController
|
||
|
|
|
||
|
|
**For Each File**:
|
||
|
|
1. Change base class to ManagedBehaviour
|
||
|
|
2. Keep Update() as Unity Update (movement needs every frame)
|
||
|
|
3. Use OnBootComplete for post-boot initialization
|
||
|
|
4. Use RegisterManagedEvent for InputManager event subscriptions
|
||
|
|
5. Test movement, pathfinding, interactions
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Performance-critical components should use Unity Update, not OnManagedUpdate
|
||
|
|
- Only use ManagedBehaviour for initialization/cleanup benefits
|
||
|
|
- Verify A* pathfinding still works
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 26: Update InteractionActionBase Pattern
|
||
|
|
**File**: `Assets/Scripts/Interactions/InteractionActionBase.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Since this is a base class, ensure subclasses can override lifecycle hooks
|
||
|
|
2. Add example subclass showing proper override chain
|
||
|
|
3. Document pattern for action components
|
||
|
|
|
||
|
|
**Pattern**:
|
||
|
|
```csharp
|
||
|
|
public class MyAction : InteractionActionBase
|
||
|
|
{
|
||
|
|
protected override void OnManagedAwake()
|
||
|
|
{
|
||
|
|
base.OnManagedAwake(); // Calls parent registration
|
||
|
|
// Custom initialization
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Base.OnManagedAwake() must be called in subclasses
|
||
|
|
- Provide clear documentation for this pattern
|
||
|
|
- Consider sealed methods if override not intended
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 27: Create Validation and Testing Suite
|
||
|
|
**File**: `Assets/Editor/Tests/LifecycleSystemTests.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create Unity Test Runner tests for:
|
||
|
|
- Registration/unregistration
|
||
|
|
- Priority ordering
|
||
|
|
- Lifecycle hook execution order
|
||
|
|
- Event subscription cleanup
|
||
|
|
- Save/load integration
|
||
|
|
- Pause system integration
|
||
|
|
- Scene transition handling
|
||
|
|
2. Create test ManagedBehaviour subclasses
|
||
|
|
3. Mock managers for isolated testing
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleValidator.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create runtime validator that checks:
|
||
|
|
- No duplicate registrations
|
||
|
|
- All ManagedBehaviours properly registered
|
||
|
|
- Priority conflicts (warnings)
|
||
|
|
- Missing overrides (if flags set but no override)
|
||
|
|
2. Add menu item "Tools/Lifecycle/Validate Scene"
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Tests should cover all lifecycle phases
|
||
|
|
- Include edge cases (late registration, scene transitions)
|
||
|
|
- Performance benchmarks for Update broadcasts
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 28: Create Documentation
|
||
|
|
**File**: `docs/ManagedBehaviour_Usage_Guide.md`
|
||
|
|
|
||
|
|
**Content**:
|
||
|
|
1. Quick start guide
|
||
|
|
2. Common patterns and examples
|
||
|
|
3. Lifecycle phase reference
|
||
|
|
4. Priority guidelines
|
||
|
|
5. Performance considerations
|
||
|
|
6. Migration guide from MonoBehaviour
|
||
|
|
7. Troubleshooting section
|
||
|
|
|
||
|
|
**File**: `docs/ManagedBehaviour_API_Reference.md`
|
||
|
|
|
||
|
|
**Content**:
|
||
|
|
1. Complete API documentation
|
||
|
|
2. All virtual methods with parameters
|
||
|
|
3. All properties and their defaults
|
||
|
|
4. Integration points (SaveLoadManager, GameManager)
|
||
|
|
5. Best practices
|
||
|
|
|
||
|
|
**File**: `docs/ManagedBehaviour_Architecture.md`
|
||
|
|
|
||
|
|
**Content**:
|
||
|
|
1. System architecture diagram
|
||
|
|
2. Component interaction flows
|
||
|
|
3. Performance characteristics
|
||
|
|
4. Design decisions and rationale
|
||
|
|
5. Future extension points
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 29: Performance Optimization Pass
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Profile Update/FixedUpdate broadcasts
|
||
|
|
2. Consider using Unity Jobs for parallel execution (if applicable)
|
||
|
|
3. Add object pooling for event subscriptions
|
||
|
|
4. Cache frequently accessed lists
|
||
|
|
5. Add compile-time flags for debug features
|
||
|
|
6. Optimize sort algorithms for registration
|
||
|
|
7. Consider lazy initialization for empty lists
|
||
|
|
|
||
|
|
**Targets**:
|
||
|
|
- Registration: < 0.1ms per component
|
||
|
|
- Update broadcast: < 0.5ms for 100 components
|
||
|
|
- Memory overhead: < 100 bytes per ManagedBehaviour
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Use Unity Profiler to identify bottlenecks
|
||
|
|
- Compare against baseline (vanilla MonoBehaviour)
|
||
|
|
- Optimize hot paths (Update broadcasts)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 30: Create Editor Tools
|
||
|
|
**File**: `Assets/Editor/LifecycleManagerInspector.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Custom inspector for LifecycleManager
|
||
|
|
2. Show registered components grouped by phase
|
||
|
|
3. Display component priorities
|
||
|
|
4. Show current state flags
|
||
|
|
5. Add "Force Broadcast" buttons for testing
|
||
|
|
6. Real-time component count display
|
||
|
|
|
||
|
|
**File**: `Assets/Editor/ManagedBehaviourInspector.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Custom inspector for ManagedBehaviour
|
||
|
|
2. Show active lifecycle phases (visual flags)
|
||
|
|
3. Display current registration status
|
||
|
|
4. Show priority values
|
||
|
|
5. List registered managed events
|
||
|
|
6. Add "Test Lifecycle" button
|
||
|
|
|
||
|
|
**File**: `Assets/Editor/LifecycleDebugWindow.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Custom editor window "Window/Lifecycle/Debug"
|
||
|
|
2. Real-time lifecycle event log
|
||
|
|
3. Component hierarchy view
|
||
|
|
4. Priority visualization
|
||
|
|
5. Performance metrics
|
||
|
|
6. Event subscription viewer
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 31: Final Integration Testing
|
||
|
|
**Test Scenarios**:
|
||
|
|
|
||
|
|
1. **Boot Sequence Test**:
|
||
|
|
- Start game from BootstrapScene
|
||
|
|
- Verify all lifecycle phases execute in order
|
||
|
|
- Check priority ordering is respected
|
||
|
|
- Validate settings load correctly
|
||
|
|
|
||
|
|
2. **Scene Transition Test**:
|
||
|
|
- Switch between multiple scenes
|
||
|
|
- Verify OnSceneReady called for new scenes
|
||
|
|
- Verify OnSceneUnloading called for old scenes
|
||
|
|
- Check persistent components don't receive scene events
|
||
|
|
|
||
|
|
3. **Save/Load Test**:
|
||
|
|
- Save game state
|
||
|
|
- Switch scenes
|
||
|
|
- Load saved state
|
||
|
|
- Verify all ISaveParticipant components restored
|
||
|
|
|
||
|
|
4. **Pause System Test**:
|
||
|
|
- Pause game (multiple requests)
|
||
|
|
- Verify all pausable components paused
|
||
|
|
- Resume game
|
||
|
|
- Verify all components resumed
|
||
|
|
|
||
|
|
5. **Late Registration Test**:
|
||
|
|
- Instantiate ManagedBehaviour after boot
|
||
|
|
- Verify it receives appropriate lifecycle calls
|
||
|
|
- Check it gets current state (paused, scene ready, etc.)
|
||
|
|
|
||
|
|
6. **Destruction Test**:
|
||
|
|
- Destroy ManagedBehaviours during gameplay
|
||
|
|
- Verify cleanup happens correctly
|
||
|
|
- Check no memory leaks (event subscriptions cleaned)
|
||
|
|
|
||
|
|
7. **Performance Test**:
|
||
|
|
- Spawn 100+ ManagedBehaviours
|
||
|
|
- Measure frame time impact
|
||
|
|
- Profile Update broadcasts
|
||
|
|
- Check memory usage
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 32: Migration Strategy for Remaining Components
|
||
|
|
**Approach**: Gradual, category-by-category migration
|
||
|
|
|
||
|
|
**Phase 1: Critical Path** (Already covered in steps 20-25)
|
||
|
|
- Core managers
|
||
|
|
- UI systems
|
||
|
|
- Gameplay systems
|
||
|
|
|
||
|
|
**Phase 2: Scene-Specific Components**
|
||
|
|
- Level switches
|
||
|
|
- Minigame components
|
||
|
|
- Puzzle elements
|
||
|
|
- Scene triggers
|
||
|
|
|
||
|
|
**Phase 3: Utility Components**
|
||
|
|
- Camera systems
|
||
|
|
- Audio managers
|
||
|
|
- Effect spawners
|
||
|
|
- Pooling systems
|
||
|
|
|
||
|
|
**Phase 4: Low-Priority/External**
|
||
|
|
- Experimental scripts
|
||
|
|
- Test components
|
||
|
|
- External plugin wrappers
|
||
|
|
|
||
|
|
**For Each Component**:
|
||
|
|
1. Assess if it benefits from ManagedBehaviour (needs lifecycle control?)
|
||
|
|
2. If yes: follow migration pattern (change base class, update hooks)
|
||
|
|
3. If no: leave as MonoBehaviour (simple utility scripts)
|
||
|
|
4. Test after each file migrated
|
||
|
|
5. Commit to version control
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Not all components need migration (only those needing lifecycle control)
|
||
|
|
- Prioritize components with InitializePostBoot, scene event subscriptions, or complex initialization
|
||
|
|
- Simple components (visual effects, UI elements) can stay MonoBehaviour
|
||
|
|
- Document migration decisions in code comments
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 33: Backward Compatibility Layer
|
||
|
|
**File**: `Assets/Scripts/Core/Lifecycle/LegacyMonoBehaviourAdapter.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create adapter class for existing MonoBehaviour components
|
||
|
|
2. Allows non-migrated components to participate in lifecycle
|
||
|
|
3. Implement manual registration helper:
|
||
|
|
```csharp
|
||
|
|
public static class LifecycleHelper
|
||
|
|
{
|
||
|
|
public static void RegisterLegacyComponent(MonoBehaviour component, Action onBootComplete)
|
||
|
|
{
|
||
|
|
BootCompletionService.RegisterInitAction(onBootComplete);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
4. Document when to use adapter vs. migration
|
||
|
|
|
||
|
|
**Key Details**:
|
||
|
|
- Provides bridge during migration period
|
||
|
|
- Allows incremental adoption
|
||
|
|
- Eventually can be deprecated once migration complete
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 34: Code Cleanup and Refactoring
|
||
|
|
**Actions**:
|
||
|
|
|
||
|
|
1. **Remove Redundant Code**:
|
||
|
|
- Search for `BootCompletionService.RegisterInitAction` in migrated files (should be removed)
|
||
|
|
- Search for manual event subscription patterns (Convert to RegisterManagedEvent)
|
||
|
|
- Remove empty InitializePostBoot methods
|
||
|
|
|
||
|
|
2. **Standardize Patterns**:
|
||
|
|
- Consistent priority values across similar components
|
||
|
|
- Consistent ActiveLifecyclePhases usage
|
||
|
|
- Consistent logging patterns
|
||
|
|
|
||
|
|
3. **Update Comments**:
|
||
|
|
- Remove outdated references to old lifecycle
|
||
|
|
- Add references to ManagedBehaviour lifecycle
|
||
|
|
- Document priority decisions
|
||
|
|
|
||
|
|
4. **Code Review**:
|
||
|
|
- Review all migrated files
|
||
|
|
- Check for proper base.OnManagedAwake() calls
|
||
|
|
- Verify no breaking changes to public APIs
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 35: Update Project Documentation
|
||
|
|
**Files to Update**:
|
||
|
|
|
||
|
|
1. `docs/bootstrap_readme.md`:
|
||
|
|
- Add section on ManagedBehaviour integration
|
||
|
|
- Update lifecycle flow diagrams
|
||
|
|
- Reference new lifecycle guide
|
||
|
|
|
||
|
|
2. `README.md`:
|
||
|
|
- Add link to ManagedBehaviour documentation
|
||
|
|
- Update project structure description
|
||
|
|
|
||
|
|
3. Create `docs/ManagedBehaviour_Migration_Log.md`:
|
||
|
|
- List of migrated components
|
||
|
|
- Migration dates
|
||
|
|
- Issues encountered and solutions
|
||
|
|
- Components intentionally not migrated
|
||
|
|
|
||
|
|
4. Update inline documentation:
|
||
|
|
- Update XML comments in migrated files
|
||
|
|
- Reference ManagedBehaviour lifecycle in comments
|
||
|
|
- Add examples where helpful
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 36: Performance Profiling and Optimization
|
||
|
|
**Actions**:
|
||
|
|
|
||
|
|
1. **Baseline Measurements**:
|
||
|
|
- Measure current performance (before optimization)
|
||
|
|
- Profile Update broadcasts (100+ components)
|
||
|
|
- Memory allocation tracking
|
||
|
|
- GC pressure measurement
|
||
|
|
|
||
|
|
2. **Optimization Targets**:
|
||
|
|
- LifecycleManager.Update < 0.5ms (100 components)
|
||
|
|
- LifecycleManager.FixedUpdate < 0.3ms (100 components)
|
||
|
|
- Registration < 0.1ms per component
|
||
|
|
- Zero GC allocations during broadcasts
|
||
|
|
|
||
|
|
3. **Implementation**:
|
||
|
|
- Cache component counts
|
||
|
|
- Use for loops instead of foreach (no allocator)
|
||
|
|
- Avoid boxing in generic methods
|
||
|
|
- Pool event subscription objects
|
||
|
|
- Use struct enumerators
|
||
|
|
|
||
|
|
4. **Validation**:
|
||
|
|
- Re-profile after optimizations
|
||
|
|
- Compare against baseline
|
||
|
|
- Ensure optimizations don't break functionality
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 37: Edge Case Handling
|
||
|
|
**Scenarios to Handle**:
|
||
|
|
|
||
|
|
1. **Editor Mode**:
|
||
|
|
- Handle domain reload
|
||
|
|
- Handle enter/exit play mode
|
||
|
|
- Handle script recompilation during play
|
||
|
|
|
||
|
|
2. **Build Scenarios**:
|
||
|
|
- Development builds (debug logging enabled)
|
||
|
|
- Release builds (debug code stripped)
|
||
|
|
- Platform-specific behavior
|
||
|
|
|
||
|
|
3. **Error Recovery**:
|
||
|
|
- Handle missing LifecycleManager gracefully
|
||
|
|
- Handle null component references
|
||
|
|
- Handle exceptions during lifecycle hooks (isolate failures)
|
||
|
|
|
||
|
|
4. **Threading**:
|
||
|
|
- Ensure thread safety for registration queue
|
||
|
|
- Handle registration from background threads (queue for main thread)
|
||
|
|
|
||
|
|
5. **Scene Edge Cases**:
|
||
|
|
- Handle multiple scenes loaded additively
|
||
|
|
- Handle rapid scene switches
|
||
|
|
- Handle scene unload during lifecycle broadcast
|
||
|
|
|
||
|
|
**Implementation**: Add defensive checks, logging, and fallbacks throughout LifecycleManager and ManagedBehaviour.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 38: Create Tutorial Scene
|
||
|
|
**File**: `Assets/Scenes/ManagedBehaviourTutorial.unity`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create tutorial scene demonstrating system
|
||
|
|
2. Include examples of:
|
||
|
|
- Simple ManagedBehaviour
|
||
|
|
- Priority ordering demonstration
|
||
|
|
- Lifecycle phase visualization
|
||
|
|
- Event subscription examples
|
||
|
|
- Save/load integration
|
||
|
|
- Pause system integration
|
||
|
|
3. Add UI showing lifecycle events in real-time
|
||
|
|
4. Include interactive elements to trigger phases
|
||
|
|
|
||
|
|
**File**: `Assets/Scripts/Tutorial/LifecycleEventLogger.cs`
|
||
|
|
|
||
|
|
**Actions**:
|
||
|
|
1. Create component that logs all lifecycle events to UI
|
||
|
|
2. Shows order of execution
|
||
|
|
3. Shows timing information
|
||
|
|
4. Color-codes by priority
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 39: Community Documentation and Examples
|
||
|
|
**File**: `docs/ManagedBehaviour_FAQ.md`
|
||
|
|
|
||
|
|
**Content**:
|
||
|
|
1. Frequently asked questions
|
||
|
|
2. Common mistakes and solutions
|
||
|
|
3. When to use ManagedBehaviour vs MonoBehaviour
|
||
|
|
4. Performance considerations
|
||
|
|
5. Debugging tips
|
||
|
|
|
||
|
|
**File**: `docs/ManagedBehaviour_Recipes.md`
|
||
|
|
|
||
|
|
**Content**:
|
||
|
|
1. Common patterns and recipes
|
||
|
|
2. Singleton pattern with ManagedBehaviour
|
||
|
|
3. Scene-specific manager pattern
|
||
|
|
4. Persistent service pattern
|
||
|
|
5. Component with managed events pattern
|
||
|
|
6. Save/load participant pattern
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### STEP 40: Final Review and Release Preparation
|
||
|
|
**Checklist**:
|
||
|
|
|
||
|
|
- [ ] All core systems migrated
|
||
|
|
- [ ] All tests passing
|
||
|
|
- [ ] Performance targets met
|
||
|
|
- [ ] Documentation complete
|
||
|
|
- [ ] Examples created and tested
|
||
|
|
- [ ] Editor tools working
|
||
|
|
- [ ] No console errors or warnings
|
||
|
|
- [ ] Code reviewed
|
||
|
|
- [ ] Backward compatibility maintained
|
||
|
|
- [ ] Migration guide complete
|
||
|
|
|
||
|
|
**Final Actions**:
|
||
|
|
1. Create release notes
|
||
|
|
2. Tag version in git
|
||
|
|
3. Update project version number
|
||
|
|
4. Create migration checklist for team
|
||
|
|
5. Schedule team training/walkthrough
|
||
|
|
6. Monitor for issues after deployment
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Appendix A: Priority Guidelines
|
||
|
|
|
||
|
|
### Recommended Priority Ranges
|
||
|
|
| Component Type | Priority Range | Reasoning |
|
||
|
|
|----------------|----------------|-----------|
|
||
|
|
| Core Infrastructure | 0-20 | LifecycleManager, CustomBoot integration |
|
||
|
|
| Core Managers | 10-30 | GameManager, SceneManager, SaveManager |
|
||
|
|
| Service Providers | 30-50 | Settings providers, factories |
|
||
|
|
| Gameplay Managers | 50-100 | PuzzleManager, CardSystem, Minigames |
|
||
|
|
| UI Controllers | 100-150 | Page controllers, loading screens |
|
||
|
|
| Scene Components | 150-200 | Level-specific logic |
|
||
|
|
| Gameplay Objects | 200-500 | Interactables, pickups, NPCs |
|
||
|
|
| Visual Effects | 500-1000 | Particles, animations, decorative |
|
||
|
|
|
||
|
|
### Priority Best Practices
|
||
|
|
- Use increments of 5 or 10 for easy insertion
|
||
|
|
- Document priority decisions in code comments
|
||
|
|
- Avoid priority 0 (reserved for system use)
|
||
|
|
- Group related components in same priority range
|
||
|
|
- Consider dependencies when assigning priorities
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Appendix B: Common Migration Patterns
|
||
|
|
|
||
|
|
### Pattern 1: Basic Singleton Manager
|
||
|
|
**Before**:
|
||
|
|
```csharp
|
||
|
|
public class MyManager : MonoBehaviour
|
||
|
|
{
|
||
|
|
private static MyManager _instance;
|
||
|
|
public static MyManager Instance => _instance;
|
||
|
|
|
||
|
|
void Awake()
|
||
|
|
{
|
||
|
|
_instance = this;
|
||
|
|
BootCompletionService.RegisterInitAction(InitializePostBoot);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void InitializePostBoot()
|
||
|
|
{
|
||
|
|
// Setup
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**After**:
|
||
|
|
```csharp
|
||
|
|
public class MyManager : ManagedBehaviour
|
||
|
|
{
|
||
|
|
private static MyManager _instance;
|
||
|
|
public static MyManager Instance => _instance;
|
||
|
|
|
||
|
|
protected override int BootCompletePriority => 50;
|
||
|
|
protected override LifecycleFlags ActiveLifecyclePhases =>
|
||
|
|
LifecycleFlags.ManagedAwake | LifecycleFlags.BootComplete;
|
||
|
|
|
||
|
|
protected override void OnManagedAwake()
|
||
|
|
{
|
||
|
|
_instance = this;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void OnBootComplete()
|
||
|
|
{
|
||
|
|
// Setup
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 2: Component with Event Subscriptions
|
||
|
|
**Before**:
|
||
|
|
```csharp
|
||
|
|
public class MyComponent : MonoBehaviour
|
||
|
|
{
|
||
|
|
void Start()
|
||
|
|
{
|
||
|
|
SomeManager.Instance.OnEvent += HandleEvent;
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnDestroy()
|
||
|
|
{
|
||
|
|
if (SomeManager.Instance != null)
|
||
|
|
SomeManager.Instance.OnEvent -= HandleEvent;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void HandleEvent() { }
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**After**:
|
||
|
|
```csharp
|
||
|
|
public class MyComponent : ManagedBehaviour
|
||
|
|
{
|
||
|
|
protected override LifecycleFlags ActiveLifecyclePhases =>
|
||
|
|
LifecycleFlags.BootComplete;
|
||
|
|
|
||
|
|
protected override void OnBootComplete()
|
||
|
|
{
|
||
|
|
RegisterManagedEvent(SomeManager.Instance,
|
||
|
|
m => m.OnEvent += HandleEvent);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void HandleEvent() { }
|
||
|
|
// No OnDestroy needed - auto cleanup
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 3: Scene-Specific Component
|
||
|
|
**Before**:
|
||
|
|
```csharp
|
||
|
|
public class LevelComponent : MonoBehaviour
|
||
|
|
{
|
||
|
|
void Start()
|
||
|
|
{
|
||
|
|
SceneManagerService.Instance.SceneLoadCompleted += OnSceneLoaded;
|
||
|
|
Initialize();
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnDestroy()
|
||
|
|
{
|
||
|
|
if (SceneManagerService.Instance != null)
|
||
|
|
SceneManagerService.Instance.SceneLoadCompleted -= OnSceneLoaded;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnSceneLoaded(string sceneName) { }
|
||
|
|
private void Initialize() { }
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**After**:
|
||
|
|
```csharp
|
||
|
|
public class LevelComponent : ManagedBehaviour
|
||
|
|
{
|
||
|
|
protected override LifecycleFlags ActiveLifecyclePhases =>
|
||
|
|
LifecycleFlags.SceneReady | LifecycleFlags.SceneUnloading;
|
||
|
|
|
||
|
|
protected override void OnSceneReady()
|
||
|
|
{
|
||
|
|
Initialize();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void OnSceneUnloading()
|
||
|
|
{
|
||
|
|
Cleanup();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Initialize() { }
|
||
|
|
private void Cleanup() { }
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Appendix C: Troubleshooting Guide
|
||
|
|
|
||
|
|
### Issue: Lifecycle hook not being called
|
||
|
|
**Symptoms**: OnBootComplete or other hook not executing
|
||
|
|
**Solutions**:
|
||
|
|
1. Check ActiveLifecyclePhases includes the appropriate flag
|
||
|
|
2. Verify LifecycleManager exists in scene
|
||
|
|
3. Ensure base.OnManagedAwake() called if overriding
|
||
|
|
4. Check LifecycleManager debug logs
|
||
|
|
|
||
|
|
### Issue: Wrong execution order
|
||
|
|
**Symptoms**: Components initialize in unexpected order
|
||
|
|
**Solutions**:
|
||
|
|
1. Verify priority values (lower = earlier)
|
||
|
|
2. Check for priority conflicts (same priority = undefined order)
|
||
|
|
3. Add debug logging to verify execution order
|
||
|
|
4. Use LifecycleDebugWindow to visualize order
|
||
|
|
|
||
|
|
### Issue: Events not cleaning up
|
||
|
|
**Symptoms**: Memory leaks or errors after component destruction
|
||
|
|
**Solutions**:
|
||
|
|
1. Use RegisterManagedEvent instead of manual subscription
|
||
|
|
2. Verify OnDestroy calls base.OnDestroy()
|
||
|
|
3. Check event target is not null when registering
|
||
|
|
4. Review LifecycleManager event cleanup logs
|
||
|
|
|
||
|
|
### Issue: Performance degradation
|
||
|
|
**Symptoms**: Frame time increases with many ManagedBehaviours
|
||
|
|
**Solutions**:
|
||
|
|
1. Only override lifecycle hooks you need
|
||
|
|
2. Don't use OnManagedUpdate if Unity Update suffices
|
||
|
|
3. Profile with Unity Profiler to find bottleneck
|
||
|
|
4. Check for excessive logging in release builds
|
||
|
|
5. Optimize ActiveLifecyclePhases (don't include unused phases)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Appendix D: Integration Checklist
|
||
|
|
|
||
|
|
Use this checklist when migrating each component:
|
||
|
|
|
||
|
|
**Pre-Migration**:
|
||
|
|
- [ ] Component has InitializePostBoot or complex initialization
|
||
|
|
- [ ] Component subscribes to manager events
|
||
|
|
- [ ] Component needs deterministic initialization order
|
||
|
|
- [ ] Component is ISaveParticipant or IPausable
|
||
|
|
|
||
|
|
**Migration**:
|
||
|
|
- [ ] Changed base class to ManagedBehaviour
|
||
|
|
- [ ] Set appropriate priority values
|
||
|
|
- [ ] Added ActiveLifecyclePhases flags
|
||
|
|
- [ ] Moved Awake logic to OnManagedAwake
|
||
|
|
- [ ] Moved InitializePostBoot to OnBootComplete
|
||
|
|
- [ ] Converted event subscriptions to RegisterManagedEvent
|
||
|
|
- [ ] Removed manual BootCompletionService registration
|
||
|
|
- [ ] Set AutoRegisterSaveParticipant if ISaveParticipant
|
||
|
|
- [ ] Set AutoRegisterPausable if IPausable
|
||
|
|
- [ ] Updated XML documentation
|
||
|
|
|
||
|
|
**Post-Migration**:
|
||
|
|
- [ ] No compiler errors
|
||
|
|
- [ ] Component still functions correctly
|
||
|
|
- [ ] Lifecycle hooks called at appropriate times
|
||
|
|
- [ ] Priority ordering correct relative to dependencies
|
||
|
|
- [ ] No memory leaks (events cleaned up)
|
||
|
|
- [ ] Performance acceptable
|
||
|
|
- [ ] Code reviewed
|
||
|
|
- [ ] Tests updated/added
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Appendix E: Future Enhancements
|
||
|
|
|
||
|
|
Potential future additions to the system:
|
||
|
|
|
||
|
|
1. **Async Lifecycle Hooks**: Support for async/await in lifecycle methods
|
||
|
|
2. **Conditional Phases**: Enable/disable phases at runtime
|
||
|
|
3. **Lifecycle Groups**: Group related components for batch operations
|
||
|
|
4. **Visual Editor**: Node-based lifecycle flow visualization
|
||
|
|
5. **Hot Reload Support**: Better handling of domain reload in editor
|
||
|
|
6. **Multi-threading**: Parallel execution of independent components
|
||
|
|
7. **Lifecycle Templates**: Pre-configured setups for common patterns
|
||
|
|
8. **Analytics Integration**: Track lifecycle performance in production
|
||
|
|
9. **Memory Pooling**: Pool ManagedBehaviour instances for performance
|
||
|
|
10. **Dependency Injection**: Auto-resolve dependencies in OnManagedAwake
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Document Metadata
|
||
|
|
|
||
|
|
**Version**: 1.0
|
||
|
|
**Last Updated**: October 30, 2025
|
||
|
|
**Author**: AI Assistant
|
||
|
|
**Status**: Ready for Implementation
|
||
|
|
|
||
|
|
**Implementation Estimate**: 40-60 hours across 2-3 weeks
|
||
|
|
**Risk Level**: Medium (significant refactoring, but incremental approach reduces risk)
|
||
|
|
**Prerequisites**: Unity 2021.3+, C# 8.0+, existing bootstrap system
|
||
|
|
|
||
|
|
**Next Steps**:
|
||
|
|
1. Review this document thoroughly
|
||
|
|
2. Get team approval
|
||
|
|
3. Begin with STEP 1
|
||
|
|
4. Progress sequentially through steps
|
||
|
|
5. Test thoroughly at each phase
|
||
|
|
6. Document any deviations or issues
|
||
|
|
|