144 lines
5.2 KiB
C#
144 lines
5.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
namespace TKS
|
|
{
|
|
/// <summary>
|
|
/// 자동 플레이 실측: 아군도 AI 로 조작해 몇 턴을 돌리며 스크린샷·로그를 남긴다.
|
|
/// 에디터에서 ProjectSetup.AutoPlayCapture 가 SessionState 로 출력 폴더를 넘기면 생성된다.
|
|
/// </summary>
|
|
public class AutoPlayDriver : MonoBehaviour
|
|
{
|
|
public string OutputDir;
|
|
public int MaxTurns = 3;
|
|
public int Width = 720;
|
|
public int Height = 1280;
|
|
|
|
readonly List<string> log = new List<string>();
|
|
int shotIndex = 1;
|
|
|
|
#if UNITY_EDITOR
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
|
static void AutoSpawn()
|
|
{
|
|
string dir = UnityEditor.SessionState.GetString("TKS_AUTOPLAY_DIR", "");
|
|
if (string.IsNullOrEmpty(dir)) return;
|
|
UnityEditor.SessionState.EraseString("TKS_AUTOPLAY_DIR");
|
|
var go = new GameObject("AutoPlayDriver");
|
|
var d = go.AddComponent<AutoPlayDriver>();
|
|
d.OutputDir = dir;
|
|
d.MaxTurns = UnityEditor.SessionState.GetInt("TKS_AUTOPLAY_TURNS", 3);
|
|
}
|
|
#endif
|
|
|
|
IEnumerator Start()
|
|
{
|
|
Directory.CreateDirectory(OutputDir);
|
|
float t0 = Time.realtimeSinceStartup;
|
|
while ((BattleManager.Instance == null || BattleManager.Instance.Phase != BattlePhase.PlayerTurn)
|
|
&& Time.realtimeSinceStartup - t0 < 20f)
|
|
{
|
|
yield return null;
|
|
}
|
|
var bm = BattleManager.Instance;
|
|
var cam = Camera.main;
|
|
if (bm == null || cam == null)
|
|
{
|
|
Log("FAIL: BattleManager 또는 카메라 없음");
|
|
Finish(1);
|
|
yield break;
|
|
}
|
|
|
|
Log("stage=" + bm.Stage.title + " players=" + bm.AliveCount(Faction.Player) + " enemies=" + bm.AliveCount(Faction.Enemy));
|
|
yield return Fx.Wait(0.6f);
|
|
yield return Shot(cam, "start");
|
|
|
|
var first = FirstActable(bm);
|
|
if (first != null)
|
|
{
|
|
var tgt = EnemyAI.Decide(first, bm.AliveUnits(Faction.Enemy), 1f, bm.Rng, bm.Board);
|
|
Vector2 pointer = first.Position - (tgt - first.Position) * 0.5f;
|
|
bm.Sling.ShowPreview(first, tgt, pointer);
|
|
first.View.SetSelected(true);
|
|
yield return null;
|
|
yield return Shot(cam, "aim_" + first.DisplayName);
|
|
first.View.SetSelected(false);
|
|
bm.Sling.HidePreview();
|
|
}
|
|
|
|
bool firstActionShot = false;
|
|
for (int turn = 1; turn <= MaxTurns; turn++)
|
|
{
|
|
int guard = 0;
|
|
while (bm.Phase == BattlePhase.PlayerTurn && guard++ < 24)
|
|
{
|
|
var u = FirstActable(bm);
|
|
if (u == null)
|
|
{
|
|
bm.OnEmptyTap();
|
|
break;
|
|
}
|
|
var target = EnemyAI.Decide(u, bm.AliveUnits(Faction.Enemy), 1f, bm.Rng, bm.Board);
|
|
if (!bm.RequestPlayerAction(u, target)) break;
|
|
while (bm.Phase == BattlePhase.Resolving) yield return null;
|
|
Log("turn " + turn + " | " + bm.LastMessage);
|
|
if (!firstActionShot)
|
|
{
|
|
firstActionShot = true;
|
|
yield return Shot(cam, "after_first_action");
|
|
}
|
|
if (bm.Phase == BattlePhase.StageClear || bm.Phase == BattlePhase.Defeat) break;
|
|
}
|
|
while (bm.Phase == BattlePhase.EnemyTurn || bm.Phase == BattlePhase.Resolving) yield return null;
|
|
Log("turn " + turn + " end | phase=" + bm.Phase + " players=" + bm.AliveCount(Faction.Player) + " enemies=" + bm.AliveCount(Faction.Enemy) + " | " + bm.LastMessage);
|
|
yield return Shot(cam, "turn" + turn + "_end");
|
|
if (bm.Phase == BattlePhase.StageClear || bm.Phase == BattlePhase.Defeat) break;
|
|
}
|
|
|
|
File.WriteAllLines(Path.Combine(OutputDir, "autoplay_log.txt"), log.ToArray());
|
|
Finish(0);
|
|
}
|
|
|
|
static Unit FirstActable(BattleManager bm)
|
|
{
|
|
foreach (var u in bm.AliveUnits(Faction.Player))
|
|
{
|
|
if (!u.ActedThisTurn) return u;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
IEnumerator Shot(Camera cam, string name)
|
|
{
|
|
string file = Path.Combine(OutputDir, shotIndex.ToString("00") + "_" + name + ".png");
|
|
shotIndex++;
|
|
yield return CaptureUtil.Capture(cam, Width, Height, file);
|
|
Log("shot " + file);
|
|
}
|
|
|
|
void Log(string s)
|
|
{
|
|
log.Add(s);
|
|
Debug.Log("[AutoPlay] " + s);
|
|
}
|
|
|
|
void Finish(int code)
|
|
{
|
|
try
|
|
{
|
|
File.WriteAllLines(Path.Combine(OutputDir, "autoplay_log.txt"), log.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
#if UNITY_EDITOR
|
|
UnityEditor.EditorApplication.Exit(code);
|
|
#else
|
|
Application.Quit(code);
|
|
#endif
|
|
}
|
|
}
|
|
}
|