// ───────────────────────────────────────────────────────────────────────────── // RunDirectorRunner.cs — RunDirector 의 시간 축(숨김 GameObject 1개 · 코루틴 0) // // PD 지시 #813 · 발주서 WL-813p §2 (2026-09-09) // // 새 Manager/Singleton 을 만들지 않는다 — BossArenaRunner · AutoCombatOnEnterRunner · SurvivalRunner 와 // 같은 방식이다. HideAndDontSave 라 씬 전환에도 살아남고(DontDestroyOnLoad 불필요) 씬·프리팹에 저장되지 않는다. // WLRunSettings.Enabled 가 false 면 RunDirector.Boot 이 이 오브젝트를 아예 만들지 않는다(C8). // // 🔴 어셈블리 주의: Assets/WL/Combat/ 에 .asmdef 를 만들지 말 것. // ───────────────────────────────────────────────────────────────────────────── using UnityEngine; namespace WL.Combat.Run { /// RunDirector 를 매 프레임 틱한다(폴링 간격은 SO pollSeconds 가 결정). internal sealed class RunDirectorRunner : MonoBehaviour { static RunDirectorRunner s_runner; /// 런너 1개 보장(플레이 모드 전용 · 에디트 모드에서는 만들지 않는다). internal static void Ensure() { if (!Application.isPlaying || s_runner != null) return; var go = new GameObject("[WL813p] RunDirectorRunner"); go.hideFlags = HideFlags.HideAndDontSave; s_runner = go.AddComponent(); } /// 런너가 살아 있는가(프로브가 읽는다). internal static bool Exists { get { return s_runner != null; } } void Update() { RunDirector.Tick(); } void OnDestroy() { if (ReferenceEquals(s_runner, this)) s_runner = null; } } }