Project_WL/Assets/WL/Combat/Reaction/SkillSpectacleRunner.cs

56 lines
2.8 KiB
C#

// ─────────────────────────────────────────────────────────────────────────────
// SkillSpectacleRunner.cs — 스킬 스펙터클 전용 틱 러너 + 풀 루트(숨은 오브젝트 1개 · Play 는 DontDestroyOnLoad · 에디트 모드는 DontSave)
//
// 발주서 WL-811i · 새 Manager/Singleton 을 만들지 않는다(WLReactionRunner · LootBurstRunner 선례 · 발주서 밖 파일 무수정 원칙으로 별도 러너).
// Pool(비활성) 아래에서 Instantiate 해 Awake/OnEnable 없이 캐시한 뒤 Live(활성) 로 옮긴다. 씬 전환 · 비활성 · 앱 종료 시 활성 이펙트를 끄고 예산을 돌려준다.
// ─────────────────────────────────────────────────────────────────────────────
using UnityEngine;
using UnityEngine.SceneManagement;
namespace WL.Combat.Reaction
{
public sealed class SkillSpectacleRunner : MonoBehaviour
{
static SkillSpectacleRunner s_runner;
static bool s_sceneHooked;
/// <summary>비활성 부모(여기서 Instantiate → Awake 안 돎).</summary>
public Transform PoolRoot;
/// <summary>활성 부모(재생 중 인스턴스).</summary>
public Transform LiveRoot;
public static bool Exists { get { return s_runner != null; } }
public static SkillSpectacleRunner Ensure()
{
if (s_runner != null) return s_runner;
bool playing = Application.isPlaying;
var go = new GameObject("__WLSkillSpectacle");
if (playing) DontDestroyOnLoad(go); else go.hideFlags = HideFlags.DontSave;
s_runner = go.AddComponent<SkillSpectacleRunner>();
var pool = new GameObject("Pool");
pool.transform.SetParent(go.transform, false);
if (!playing) pool.hideFlags = HideFlags.DontSave;
pool.SetActive(false);
s_runner.PoolRoot = pool.transform;
var live = new GameObject("Live");
live.transform.SetParent(go.transform, false);
if (!playing) live.hideFlags = HideFlags.DontSave;
s_runner.LiveRoot = live.transform;
if (!s_sceneHooked) { SceneManager.activeSceneChanged += OnSceneChanged; s_sceneHooked = true; }
return s_runner;
}
static void OnSceneChanged(Scene from, Scene to) { SkillSpectacle.ClearAll(); }
void Update() { SkillSpectacle.Tick(Time.time); }
void OnDisable() { SkillSpectacle.ClearAll(); }
void OnApplicationQuit() { SkillSpectacle.ClearAll(); }
}
}