VSClone/Assets/Editor/EditorRender.cs

128 lines
6.0 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.UI;
using VS.Sim;
using VS.View;
namespace VS.EditorTools
{
// 화면 렌더 검사: Unity.exe -batchmode(그래픽 켬) -projectPath <VSClone> -executeMethod VS.EditorTools.EditorRender.Run
// → C:/ViralStreamer/_re/render/*.png · 임시 세이브 사용(PD 세이브 미접촉) · 결과 "RENDER ALL PASS" 또는 "RENDER FAIL n"
public static partial class EditorRender
{
public const string OutDir = "C:/ViralStreamer/_re/render";
static int fails;
static readonly List<string> notes = new List<string>();
static DateTime clockBase = new DateTime(2026, 1, 1, 12, 0, 0);
static double clockExtra;
public static void Run()
{
int exit = 0;
try
{
Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
fails = 0; notes.Clear();
Directory.CreateDirectory(OutDir);
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
var app = NewApp();
Shot(app, "main_new");
Progress(app.G);
app.RebuildStage(); app.RefreshAll();
Shot(app, "main_mid");
app.OpenHouse(); Shot(app, "pop_house"); app.ClosePopup();
app.OpenSkill(); Shot(app, "pop_skill"); app.ClosePopup();
app.OpenCloset(); Shot(app, "pop_closet"); app.ClosePopup();
if (app.G.Story != null && app.G.Story.chapters.Count > 0) { app.OpenStory(app.G.Story.chapters[0]); Shot(app, "pop_story"); app.ClosePopup(); }
app.G.CoinDonate = 1234.5m; app.RefreshAll();
app.OpenClaimDonate(); Shot(app, "pop_donate"); app.ClosePopup();
app.OpenSettings(); Shot(app, "pop_settings"); app.ClosePopup();
app.G.Follower = app.T.RankFollower[3];
app.OpenRankUp(); Shot(app, "pop_rankup"); app.ClosePopup();
SystemShots(app);
// 방 6종 최대 단계 그림
for (int h = 0; h < Tables.HouseCount; h++)
{
app.G.S.house = h; app.G.S.rooms.Clear();
foreach (var it in app.T.Rooms[h].Items) app.G.S.rooms.Add(new SaveItem { Type = it.Index, Level = it.Levels.Count - 1 });
app.RebuildStage(); app.RefreshAll();
Shot(app, "room" + (h + 1) + "_max");
}
Debug.Log(fails == 0 ? "[VS] RENDER ALL PASS" : $"[VS] RENDER FAIL {fails}");
foreach (var n in notes) Debug.Log("[VS] RENDER NOTE " + n);
if (fails > 0) exit = 1;
}
catch (Exception e) { Debug.LogError("[VS] RENDER EXCEPTION " + e); exit = 2; }
EditorApplication.Exit(exit);
}
static RenderTexture rt;
static GameApp NewApp()
{
clockExtra = 0;
GameApp.ClockOverride = () => clockBase.AddSeconds(clockExtra);
GameApp.SavePathOverride = Path.Combine(Path.GetTempPath(), "vs_render_save.json");
if (File.Exists(GameApp.SavePathOverride)) File.Delete(GameApp.SavePathOverride);
rt = new RenderTexture(1080, 1920, 24, RenderTextureFormat.ARGB32);
GameApp.RenderTarget = rt;
var go = new GameObject("Game");
var app = go.AddComponent<GameApp>();
app.Headless = true;
app.Init();
return app;
}
public static void Advance(double sec) => clockExtra += sec;
/// 중반 진행 상태 (방 1 아이템 일부 · 스킬 · 랭크 3 · 의상 5)
static void Progress(Game g)
{
g.S.rooms.Clear();
int[] lv = { 30, 26, 52, 12, 74, 20, 8, 40, 60, 3, 50 };
for (int i = 0; i < lv.Length; i++) g.S.rooms.Add(new SaveItem { Type = i, Level = lv[i] });
g.S.skills.Clear();
for (int i = 0; i < 5; i++) g.S.skills.Add(new SaveItem { Type = i, Level = 10 + i * 7 });
g.Follower = BigInteger.Parse("250000"); g.S.rankIndex = 3;
g.Coin = BigInteger.Parse("12345678"); g.S.ticket = 7;
g.S.closetLevel = 5; g.S.closetCurrent = 3;
g.CoinDonate = 456.7m;
}
static void Shot(GameApp app, string name)
{
Canvas.ForceUpdateCanvases();
app.Cam.targetTexture = rt;
app.Cam.Render();
Canvas.ForceUpdateCanvases();
app.Cam.Render();
var prev = RenderTexture.active;
RenderTexture.active = rt;
var tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
tex.Apply();
RenderTexture.active = prev;
File.WriteAllBytes(Path.Combine(OutDir, name + ".png"), tex.EncodeToPNG());
UnityEngine.Object.DestroyImmediate(tex);
// 검사: 빈 그림 · 글자 넘침
int missing = 0, overflow = 0;
foreach (var im in app.Root.GetComponentsInChildren<Image>(false))
if (im.sprite == null && im.color.a > 0.01f && im.enabled) { missing++; if (missing <= 3) notes.Add(name + " 빈 Image: " + im.name); }
foreach (var t in app.Root.GetComponentsInChildren<Text>(false))
{
if (string.IsNullOrEmpty(t.text) || !t.enabled) continue;
var gen = t.cachedTextGenerator;
if (gen.characterCountVisible > 0 && gen.characterCountVisible < t.text.Replace("\n", "").Length - 1) overflow++;
}
if (missing > 0) { fails++; notes.Add($"{name}: 그림 없는 Image {missing}"); }
if (overflow > 0) notes.Add($"{name}: 잘린 글자 {overflow}");
Debug.Log($"[VS] RENDER {name} missing={missing} cut={overflow}");
}
}
}