using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace TKS.OutGame
{
///
/// 타이틀 화면 검증 캡처(PD 2026-11-13 · 에디터 TKS.EditorTools.TitleCapture.Capture 가 SessionState 로 출력 폴더를 넘기면 생성 · 메모리 세이브).
/// 등장 연출(연출 시계를 정해 찍음) · 끝 모습 1080×1920 · 화면비 1080×2400 · 1536×2048 · 대기 움직임 연속(실시간) · 누름 → 로비 확인 · 끝나면 스스로 종료.
/// UICaptureDriver(다른 세션 작업 중)와 따로 둔다.
///
public class TitleCaptureDriver : MonoBehaviour
{
public const string DirKey = "TKS_TITLE_CAPTURE_DIR";
public string OutputDir;
readonly List log = new List();
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void AutoSpawn()
{
string dir = UnityEditor.SessionState.GetString(DirKey, "");
if (string.IsNullOrEmpty(dir)) return;
UnityEditor.SessionState.EraseString(DirKey);
new GameObject("TitleCaptureDriver").AddComponent().OutputDir = dir;
}
#endif
IEnumerator Start()
{
Directory.CreateDirectory(OutputDir);
yield return null;
yield return null;
var cam = Camera.main;
if (cam == null)
{
Log("FAIL: 카메라 없음");
Finish(1);
yield break;
}
bool started = false;
TitleScreen.ForceShow = true;
var ts = TitleScreen.Show(cam, () => started = true);
Log("heroes=" + ts.Heroes.Count + " introEnd=" + ts.IntroEnd.ToString("0.00") + " provider=" + (BootFlow.TitleProvider != null));
// 등장 연출 — 연출 시계를 정해 한 장씩(캡처 시간에 흔들리지 않게)
float[] at = { 0.15f, 0.35f, 0.55f, 0.75f, 0.95f, 1.15f, 1.35f, 1.42f, 1.50f, 1.60f, 1.75f }; // 로고 내려앉는 중간(1.30~1.72) 3장 = QA r1 U2
int i = 1;
foreach (var t in at)
{
ts.SetTime(t);
yield return null;
yield return CaptureUtil.Capture(cam, 1080, 1920, Path.Combine(OutputDir, "intro_" + (i++).ToString("00") + "_" + t.ToString("0.00") + ".png"));
}
ts.SetTime(ts.IntroEnd + 1.2f);
yield return null;
yield return UiLayerProbe.Measure("title", Log, OutputDir);
yield return CaptureUtil.Capture(cam, 1080, 1920, Path.Combine(OutputDir, "title_1080x1920.png"));
yield return CaptureUtil.Capture(cam, 1080, 2400, Path.Combine(OutputDir, "title_1080x2400.png"));
yield return CaptureUtil.Capture(cam, 1536, 2048, Path.Combine(OutputDir, "title_1536x2048.png"));
// 대기 움직임(실시간 · 약 0.12 초 간격) — 실제 간격을 로그에 남김
float t0 = Time.unscaledTime;
for (int k = 0; k < 24; k++)
{
yield return CaptureUtil.Capture(cam, 540, 960, Path.Combine(OutputDir, "idle_" + k.ToString("00") + ".png"));
Log("idle " + k + " t=" + (Time.unscaledTime - t0).ToString("0.000"));
float w = Time.unscaledTime + 0.12f;
while (Time.unscaledTime < w) yield return null;
}
// 확인 영상용 실시간 연속(처음부터 다시 띄워 등장 → 대기 약 4 초 · 원본 크기 · 찍힌 실제 시각을 로그에 = 영상 프레임 길이)
ts.Close();
yield return null;
ts = TitleScreen.Show(cam, () => started = true);
string vdir = Path.Combine(OutputDir, "video");
Directory.CreateDirectory(vdir);
float v0 = Time.unscaledTime;
var vlog = new List();
for (int k = 0; Time.unscaledTime - v0 < ts.IntroEnd + 4f && k < 400; k++)
{
float vt = Time.unscaledTime - v0;
yield return CaptureUtil.Capture(cam, 1080, 1920, Path.Combine(vdir, "v" + k.ToString("000") + ".png"));
vlog.Add(k + "," + vt.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture));
}
File.WriteAllLines(Path.Combine(vdir, "times.csv"), vlog.ToArray());
Log("video frames=" + vlog.Count + " seconds=" + (Time.unscaledTime - v0).ToString("0.00"));
ts.SkipIntro();
float ready = Time.unscaledTime + 2f;
while (!ts.PressReady && Time.unscaledTime < ready) yield return null;
// 누름 → 페이드 → 로비
ts.Press();
float until = Time.unscaledTime + 4f;
while (!started && Time.unscaledTime < until) yield return null;
Log("pressed → started=" + started + " titleGone=" + (TitleScreen.Current == null));
yield return new WaitForSecondsRealtime(0.6f);
yield return CaptureUtil.Capture(cam, 1080, 1920, Path.Combine(OutputDir, "after_press.png"));
TitleScreen.ForceShow = false;
Finish(started ? 0 : 1);
}
void Log(string s)
{
log.Add(s);
Debug.Log("[TitleCapture] " + s);
try
{
File.WriteAllLines(Path.Combine(OutputDir, "capture_log.txt"), log.ToArray());
}
catch
{
}
}
void Finish(int code)
{
Log("finish code=" + code);
#if UNITY_EDITOR
UnityEditor.EditorApplication.Exit(code);
#else
Application.Quit(code);
#endif
}
}
}