f31ffe910b
Netcode frontend pattern: UITK main menu / pause / settings (MenuUi + controllers), on-demand world lifecycle (WorldLauncher/SessionRunner), GameBootstrap menu branch; Graphics/Audio settings (SettingsService/GameVolume); single-slot save foundation (SaveData/SaveService, born-correct load at director spawn, autosave on Siege->Calm + quit); RuntimePanelSettings + theme; BuildTool menu; 10 EditMode tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
33 lines
1.1 KiB
C#
33 lines
1.1 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace ProjectM.Client
|
|
{
|
|
/// <summary>
|
|
/// Persistent (<c>DontDestroyOnLoad</c>) MonoBehaviour that hosts the world-lifecycle coroutines for
|
|
/// <see cref="WorldLauncher"/>. World create/dispose + scene loads must run at a FRAME BOUNDARY (never
|
|
/// inside an ECS system update — that crashes), and must survive the MainMenu<->Game scene swap, so a
|
|
/// single long-lived runner owns them. Created lazily on first use.
|
|
/// </summary>
|
|
public class SessionRunner : MonoBehaviour
|
|
{
|
|
static SessionRunner _instance;
|
|
|
|
static SessionRunner Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
var go = new GameObject("~SessionRunner");
|
|
DontDestroyOnLoad(go);
|
|
_instance = go.AddComponent<SessionRunner>();
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
public static void Run(IEnumerator routine) => Instance.StartCoroutine(routine);
|
|
}
|
|
}
|