303 lines
8.5 KiB
Markdown
303 lines
8.5 KiB
Markdown
|
|
# Editor Lifecycle Bootstrap - Implementation Summary
|
||
|
|
|
||
|
|
**Date:** November 5, 2025
|
||
|
|
**Feature:** Editor-Only Quality of Life Improvement
|
||
|
|
**Status:** ✅ Complete & Ready to Use
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
**No setup required!** Simply press Play in any scene and the lifecycle will work correctly.
|
||
|
|
|
||
|
|
### What This Fixes
|
||
|
|
|
||
|
|
Before this feature:
|
||
|
|
```
|
||
|
|
Press Play in "AppleHillsOverworld" scene
|
||
|
|
↓
|
||
|
|
✅ OnManagedAwake() called
|
||
|
|
❌ OnSceneReady() NEVER called
|
||
|
|
```
|
||
|
|
|
||
|
|
After this feature:
|
||
|
|
```
|
||
|
|
Press Play in "AppleHillsOverworld" scene
|
||
|
|
↓
|
||
|
|
✅ OnManagedAwake() called
|
||
|
|
✅ OnSceneReady() called ← NOW WORKS!
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Files Added
|
||
|
|
|
||
|
|
### 1. EditorLifecycleBootstrap.cs
|
||
|
|
**Location:** `Assets/Editor/Lifecycle/EditorLifecycleBootstrap.cs`
|
||
|
|
**Purpose:** Automatically triggers OnSceneReady when playing directly from editor
|
||
|
|
**Type:** Editor-only (zero runtime overhead)
|
||
|
|
|
||
|
|
**Key Features:**
|
||
|
|
- Automatic detection of play mode entry
|
||
|
|
- Waits for CustomBoot to complete
|
||
|
|
- Broadcasts OnSceneReady to all components in active scene
|
||
|
|
- Skips infrastructure scenes (Bootstrap/BootstrapScene)
|
||
|
|
- Safety timeout (5 seconds)
|
||
|
|
- Error handling and comprehensive logging
|
||
|
|
|
||
|
|
### 2. Documentation
|
||
|
|
**Location:** `docs/editor_lifecycle_bootstrap.md`
|
||
|
|
**Content:** Complete technical documentation and design rationale
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## How It Works
|
||
|
|
|
||
|
|
### Sequence of Events
|
||
|
|
|
||
|
|
1. **Developer presses Play** in Unity Editor (in any scene)
|
||
|
|
2. **PlayModeStateChange.EnteredPlayMode** event fires
|
||
|
|
3. **EditorLifecycleBootstrap** starts polling
|
||
|
|
4. **Wait for CustomBoot.Initialised** to become true
|
||
|
|
5. **Get active scene** from Unity SceneManager
|
||
|
|
6. **Call LifecycleManager.BroadcastSceneReady(sceneName)**
|
||
|
|
7. **All components receive OnSceneReady()** callback
|
||
|
|
|
||
|
|
### Code Architecture
|
||
|
|
|
||
|
|
```csharp
|
||
|
|
[InitializeOnLoad] // Runs in editor
|
||
|
|
public static class EditorLifecycleBootstrap
|
||
|
|
{
|
||
|
|
static EditorLifecycleBootstrap()
|
||
|
|
{
|
||
|
|
// Hook into Unity editor play mode events
|
||
|
|
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void WaitForBootAndTriggerSceneReady()
|
||
|
|
{
|
||
|
|
// Poll until boot completes
|
||
|
|
if (!Bootstrap.CustomBoot.Initialised)
|
||
|
|
return;
|
||
|
|
|
||
|
|
// Get active scene
|
||
|
|
Scene activeScene = SceneManager.GetActiveScene();
|
||
|
|
|
||
|
|
// Trigger lifecycle
|
||
|
|
LifecycleManager.Instance.BroadcastSceneReady(activeScene.name);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Benefits
|
||
|
|
|
||
|
|
### For Development
|
||
|
|
- ✅ **Test any scene directly** - no need to always start from Bootstrap
|
||
|
|
- ✅ **Consistent behavior** - same lifecycle whether starting from Bootstrap or scene
|
||
|
|
- ✅ **Zero configuration** - works automatically
|
||
|
|
- ✅ **Better debugging** - components initialize properly in editor
|
||
|
|
|
||
|
|
### For Components
|
||
|
|
Components can now reliably use OnSceneReady for initialization:
|
||
|
|
|
||
|
|
```csharp
|
||
|
|
public class FollowerController : ManagedBehaviour
|
||
|
|
{
|
||
|
|
protected override void OnSceneReady()
|
||
|
|
{
|
||
|
|
// This now works when playing directly from editor!
|
||
|
|
FindPlayerReference();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### For Builds
|
||
|
|
- ✅ **No runtime impact** - editor-only code
|
||
|
|
- ✅ **No performance cost** - completely stripped from builds
|
||
|
|
- ✅ **No behavior change** - production flow unchanged
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Expected Console Output
|
||
|
|
|
||
|
|
When pressing Play in "AppleHillsOverworld":
|
||
|
|
|
||
|
|
```
|
||
|
|
[CustomBoot] Boot initialized
|
||
|
|
[LifecycleManager] Instance created
|
||
|
|
[LifecycleManager] Registered PlayerController (Scene: AppleHillsOverworld)
|
||
|
|
[LifecycleManager] Registered FollowerController (Scene: AppleHillsOverworld)
|
||
|
|
[LifecycleManager] === Boot Completion Triggered ===
|
||
|
|
[LifecycleManager] Broadcasting ManagedAwake to 15 components
|
||
|
|
[EditorLifecycleBootstrap] Triggering OnSceneReady for initial scene: AppleHillsOverworld
|
||
|
|
[LifecycleManager] Broadcasting SceneReady for scene: AppleHillsOverworld
|
||
|
|
[FollowerController] Finding player reference (OnSceneReady)
|
||
|
|
```
|
||
|
|
|
||
|
|
The cyan-colored log clearly indicates when the editor bootstrap triggers.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Testing Checklist
|
||
|
|
|
||
|
|
### ✅ Test Case 1: Direct Play from Gameplay Scene
|
||
|
|
1. Open any gameplay scene (e.g., AppleHillsOverworld)
|
||
|
|
2. Press Play
|
||
|
|
3. Check console for EditorLifecycleBootstrap log
|
||
|
|
4. Verify components receive both OnManagedAwake and OnSceneReady
|
||
|
|
|
||
|
|
### ✅ Test Case 2: Play from Bootstrap Scene
|
||
|
|
1. Open BootstrapScene
|
||
|
|
2. Press Play
|
||
|
|
3. Verify bootstrap log says "Skipping OnSceneReady for infrastructure scene"
|
||
|
|
4. Verify normal scene transition flow works
|
||
|
|
|
||
|
|
### ✅ Test Case 3: Scene Transitions During Play
|
||
|
|
1. Play from any scene
|
||
|
|
2. Use LevelSwitch to change scenes
|
||
|
|
3. Verify SceneManagerService handles transitions normally
|
||
|
|
4. Verify EditorLifecycleBootstrap only triggers once at startup
|
||
|
|
|
||
|
|
### ✅ Test Case 4: Build Verification
|
||
|
|
1. Make a build
|
||
|
|
2. Verify EditorLifecycleBootstrap is NOT included
|
||
|
|
3. Verify production bootstrap flow works normally
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Compatibility
|
||
|
|
|
||
|
|
### ✅ Compatible With
|
||
|
|
- Existing lifecycle system
|
||
|
|
- SceneManagerService scene transitions
|
||
|
|
- DontDestroyOnLoad objects
|
||
|
|
- Multi-scene editing (processes active scene)
|
||
|
|
- All existing ManagedBehaviour components
|
||
|
|
|
||
|
|
### ❌ Not Needed For
|
||
|
|
- Production builds (editor-only)
|
||
|
|
- Bootstrap scene (infrastructure only)
|
||
|
|
- Scenes loaded via SceneManagerService (already handled)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Safety Features
|
||
|
|
|
||
|
|
### Timeout Protection
|
||
|
|
- Maximum wait time: 5 seconds (300 frames at 60fps)
|
||
|
|
- Prevents infinite loops if boot fails
|
||
|
|
- Logs error message with diagnostic info
|
||
|
|
|
||
|
|
### Error Handling
|
||
|
|
- Try-catch around BroadcastSceneReady
|
||
|
|
- Null checks for LifecycleManager
|
||
|
|
- Scene validation before broadcasting
|
||
|
|
|
||
|
|
### Smart Scene Detection
|
||
|
|
- Skips infrastructure scenes (Bootstrap, BootstrapScene)
|
||
|
|
- Only processes gameplay scenes
|
||
|
|
- Validates scene is loaded before broadcasting
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Performance
|
||
|
|
|
||
|
|
### Editor Impact
|
||
|
|
- **Minimal** - Only runs during play mode entry
|
||
|
|
- **Short-lived** - Unsubscribes after first trigger
|
||
|
|
- **Efficient** - Simple polling mechanism
|
||
|
|
|
||
|
|
### Runtime Impact
|
||
|
|
- **Zero** - Code is editor-only
|
||
|
|
- **Not included in builds** - Completely stripped
|
||
|
|
- **No overhead** - Production flow unchanged
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Problem: OnSceneReady still not called
|
||
|
|
|
||
|
|
**Check:**
|
||
|
|
1. Is LifecycleManager being created? (Check console for "[LifecycleManager] Instance created")
|
||
|
|
2. Is CustomBoot completing? (Check for "Boot Completion Triggered")
|
||
|
|
3. Is the scene name correct? (Not a bootstrap scene)
|
||
|
|
4. Does the component inherit from ManagedBehaviour?
|
||
|
|
|
||
|
|
**Solution:**
|
||
|
|
Enable LifecycleManager debug logging to see detailed lifecycle events.
|
||
|
|
|
||
|
|
### Problem: EditorLifecycleBootstrap not running
|
||
|
|
|
||
|
|
**Check:**
|
||
|
|
1. Is the file in Assets/Editor folder? (Editor-only location)
|
||
|
|
2. Is the AppleHillsEditor assembly definition including AppleHillsScripts?
|
||
|
|
3. Are there any compilation errors?
|
||
|
|
|
||
|
|
**Solution:**
|
||
|
|
Check Unity console for errors. Verify assembly definition references.
|
||
|
|
|
||
|
|
### Problem: Timeout error after 300 frames
|
||
|
|
|
||
|
|
**Diagnostic:**
|
||
|
|
CustomBoot is failing to initialize properly.
|
||
|
|
|
||
|
|
**Solution:**
|
||
|
|
1. Check CustomBoot logs for errors
|
||
|
|
2. Verify CustomBootSettings are loaded
|
||
|
|
3. Check Addressables are properly configured
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Integration with Existing Systems
|
||
|
|
|
||
|
|
### CustomBoot
|
||
|
|
- ✅ Waits for CustomBoot.Initialised flag
|
||
|
|
- ✅ Respects boot completion timing
|
||
|
|
- ✅ No modifications to CustomBoot required
|
||
|
|
|
||
|
|
### LifecycleManager
|
||
|
|
- ✅ Uses existing BroadcastSceneReady method
|
||
|
|
- ✅ No modifications to LifecycleManager required
|
||
|
|
- ✅ Follows same pattern as SceneManagerService
|
||
|
|
|
||
|
|
### SceneManagerService
|
||
|
|
- ✅ Doesn't interfere with scene transitions
|
||
|
|
- ✅ Only triggers for initial scene on editor play
|
||
|
|
- ✅ Production scene flow unchanged
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Future Considerations
|
||
|
|
|
||
|
|
### Potential Enhancements
|
||
|
|
1. **Developer Settings Integration** - Toggle in settings menu
|
||
|
|
2. **Multi-Scene Support** - Handle multiple loaded scenes
|
||
|
|
3. **Custom Delay** - Option to delay trigger by frames
|
||
|
|
4. **Editor Window** - Visual lifecycle state inspector
|
||
|
|
|
||
|
|
### Known Limitations
|
||
|
|
1. Only processes single active scene (not multi-scene setups)
|
||
|
|
2. Assumes Bootstrap scene naming convention
|
||
|
|
3. No support for domain reload disabled mode (edge case)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
The EditorLifecycleBootstrap provides a seamless, zero-configuration quality of life improvement for developers. It ensures that playing scenes directly from the Unity Editor provides the same consistent lifecycle orchestration as the production scene flow.
|
||
|
|
|
||
|
|
**Bottom Line:** Press Play anywhere, lifecycle just works. ✅
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Related Documentation
|
||
|
|
- `docs/editor_lifecycle_bootstrap.md` - Full technical documentation
|
||
|
|
- `docs/lifecycle_technical_review.md` - Lifecycle system overview
|
||
|
|
- `docs/lifecycle_implementation_roadmap.md` - Implementation details
|
||
|
|
- `docs/levelswitch_onsceneready_fix.md` - Related timing issue fix
|
||
|
|
|