199 lines
11 KiB
C#
199 lines
11 KiB
C#
// WL793_Probe.cs — PD 지시 #793·#794·#795 타이틀 해상도 대응 실측 (에디트 모드 · 읽기 전용)
|
|
// unity command run_script --file AgentScripts/WL793_Probe.cs --entry WL793_Probe.Dump
|
|
// unity command run_script --file AgentScripts/WL793_Probe.cs --entry WL793_Probe.Textures
|
|
//
|
|
// 왜 스크립트인가: Title.unity 51KB YAML 을 눈으로 읽어 앵커·피벗·sizeDelta 를 계산하면 오독이 난다.
|
|
// CanvasScaler 의 실제 scaleFactor 는 런타임 계산식이라 YAML 만 봐서는 버튼의 "화면 픽셀 크기"가 안 나온다.
|
|
// → 공개 API 로 씬을 걸어 실측한다. 쓰기 없음(SetDirty/Save 호출 없음).
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public static class WL793_Probe
|
|
{
|
|
const string Out = "Screenshots_WL/title/probe_wl793.txt";
|
|
|
|
static string Rt(RectTransform r)
|
|
{
|
|
if (r == null) return "(RectTransform 없음)";
|
|
return string.Format(
|
|
"aMin({0:F2},{1:F2}) aMax({2:F2},{3:F2}) piv({4:F2},{5:F2}) anchPos({6:F1},{7:F1}) sizeDelta({8:F1},{9:F1}) rect({10:F1}x{11:F1}) scale({12:F2},{13:F2})",
|
|
r.anchorMin.x, r.anchorMin.y, r.anchorMax.x, r.anchorMax.y, r.pivot.x, r.pivot.y,
|
|
r.anchoredPosition.x, r.anchoredPosition.y, r.sizeDelta.x, r.sizeDelta.y,
|
|
r.rect.width, r.rect.height, r.localScale.x, r.localScale.y);
|
|
}
|
|
|
|
static void Walk(Transform t, int depth, StringBuilder sb)
|
|
{
|
|
var pad = new string(' ', depth * 2);
|
|
var rt = t as RectTransform;
|
|
var comps = t.GetComponents<Component>()
|
|
.Where(c => c != null && !(c is Transform))
|
|
.Select(c => c.GetType().Name).ToArray();
|
|
sb.AppendLine(string.Format("{0}{1} [{2}] active={3}", pad, t.name,
|
|
comps.Length == 0 ? "-" : string.Join(",", comps), t.gameObject.activeSelf));
|
|
if (rt != null) sb.AppendLine(pad + " " + Rt(rt));
|
|
|
|
var img = t.GetComponent<Image>();
|
|
if (img != null)
|
|
sb.AppendLine(string.Format("{0} Image sprite={1} type={2} preserveAspect={3} raycast={4} color={5}",
|
|
pad, img.sprite != null ? img.sprite.name : "(null)", img.type, img.preserveAspect,
|
|
img.raycastTarget, img.color));
|
|
|
|
var raw = t.GetComponent<RawImage>();
|
|
if (raw != null)
|
|
sb.AppendLine(string.Format("{0} RawImage tex={1} uvRect={2} raycast={3} color={4}",
|
|
pad, raw.texture != null ? raw.texture.name : "(null)", raw.uvRect, raw.raycastTarget, raw.color));
|
|
|
|
var btn = t.GetComponent<Button>();
|
|
if (btn != null)
|
|
{
|
|
int n = btn.onClick.GetPersistentEventCount();
|
|
var calls = new List<string>();
|
|
for (int i = 0; i < n; i++)
|
|
calls.Add((btn.onClick.GetPersistentTarget(i) != null ? btn.onClick.GetPersistentTarget(i).name : "?")
|
|
+ "." + btn.onClick.GetPersistentMethodName(i));
|
|
sb.AppendLine(string.Format("{0} Button interactable={1} onClick=[{2}]", pad, btn.interactable, string.Join(" ", calls)));
|
|
}
|
|
|
|
var txt = t.GetComponent<Text>();
|
|
if (txt != null)
|
|
sb.AppendLine(string.Format("{0} Text size={1} font={2} text=\"{3}\"", pad, txt.fontSize,
|
|
txt.font != null ? txt.font.name : "(null)",
|
|
(txt.text ?? "").Replace("\n", "\\n")));
|
|
|
|
var tmp = t.GetComponent("TMPro.TextMeshProUGUI");
|
|
if (tmp != null) sb.AppendLine(pad + " TMP present");
|
|
|
|
for (int i = 0; i < t.childCount; i++) Walk(t.GetChild(i), depth + 1, sb);
|
|
}
|
|
|
|
public static object Dump()
|
|
{
|
|
if (EditorApplication.isPlaying) return "ABORT: Play 중";
|
|
var sb = new StringBuilder();
|
|
var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
|
sb.AppendLine("=== 씬: " + scene.name + " (" + scene.path + ") isDirty=" + scene.isDirty + " ===");
|
|
sb.AppendLine("Screen(에디터 게임뷰) = " + Screen.width + "x" + Screen.height);
|
|
sb.AppendLine();
|
|
|
|
foreach (var cv in Object.FindObjectsByType<Canvas>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
|
{
|
|
var cs = cv.GetComponent<CanvasScaler>();
|
|
sb.AppendLine("[Canvas] " + cv.name + " renderMode=" + cv.renderMode
|
|
+ " scaleFactor=" + cv.scaleFactor.ToString("F4")
|
|
+ " sortOrder=" + cv.sortingOrder
|
|
+ " pixelRect=" + cv.pixelRect);
|
|
if (cs != null)
|
|
sb.AppendLine(" CanvasScaler mode=" + cs.uiScaleMode
|
|
+ " ref=" + cs.referenceResolution
|
|
+ " screenMatch=" + cs.screenMatchMode
|
|
+ " match=" + cs.matchWidthOrHeight.ToString("F2")
|
|
+ " refPPU=" + cs.referencePixelsPerUnit);
|
|
var crt = cv.GetComponent<RectTransform>();
|
|
if (crt != null) sb.AppendLine(" Canvas rect=" + crt.rect.width.ToString("F1") + "x" + crt.rect.height.ToString("F1"));
|
|
}
|
|
sb.AppendLine();
|
|
|
|
foreach (var cam in Object.FindObjectsByType<Camera>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
|
sb.AppendLine("[Camera] " + cam.name + " clearFlags=" + cam.clearFlags + " bg=" + cam.backgroundColor
|
|
+ " ortho=" + cam.orthographic + " depth=" + cam.depth);
|
|
sb.AppendLine();
|
|
|
|
sb.AppendLine("=== 하이라키 ===");
|
|
foreach (var go in scene.GetRootGameObjects()) Walk(go.transform, 0, sb);
|
|
|
|
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Out));
|
|
System.IO.File.WriteAllText(Out, sb.ToString());
|
|
return "OK -> " + Out + " (" + sb.Length + " chars)";
|
|
}
|
|
|
|
// 런타임 로드되는 타이틀 UI 프리팹(TitleInfo 등) 실측
|
|
// unity command run_script --file AgentScripts/WL793_Probe.cs --entry WL793_Probe.Prefab --args '["Assets/ResWork/UIPrefabs/Title/TitleInfo.prefab"]'
|
|
public static object Prefab(string path)
|
|
{
|
|
if (EditorApplication.isPlaying) return "ABORT: Play 중";
|
|
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|
if (go == null) return "ABORT: 로드 실패 " + path;
|
|
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("=== 프리팹: " + path + " ===");
|
|
foreach (var cv in go.GetComponentsInChildren<Canvas>(true))
|
|
{
|
|
var cs = cv.GetComponent<CanvasScaler>();
|
|
sb.AppendLine("[Canvas] " + cv.name + " renderMode=" + cv.renderMode + " sortOrder=" + cv.sortingOrder);
|
|
if (cs != null)
|
|
sb.AppendLine(" CanvasScaler mode=" + cs.uiScaleMode + " ref=" + cs.referenceResolution
|
|
+ " screenMatch=" + cs.screenMatchMode + " match=" + cs.matchWidthOrHeight.ToString("F2"));
|
|
}
|
|
sb.AppendLine();
|
|
Walk(go.transform, 0, sb);
|
|
|
|
var outp = "Screenshots_WL/title/probe_" + System.IO.Path.GetFileNameWithoutExtension(path) + ".txt";
|
|
System.IO.Directory.CreateDirectory("Screenshots_WL/title");
|
|
System.IO.File.WriteAllText(outp, sb.ToString());
|
|
return "OK -> " + outp + " (" + sb.Length + " chars)";
|
|
}
|
|
|
|
// 타이틀 씬이 참조하는 모든 텍스처의 임포트 설정 실측
|
|
public static object Textures()
|
|
{
|
|
if (EditorApplication.isPlaying) return "ABORT: Play 중";
|
|
var sb = new StringBuilder();
|
|
var seen = new HashSet<string>();
|
|
var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
|
|
|
var texs = new List<Texture>();
|
|
foreach (var go in scene.GetRootGameObjects())
|
|
{
|
|
foreach (var g in go.GetComponentsInChildren<Graphic>(true))
|
|
{
|
|
var im = g as Image;
|
|
if (im != null && im.sprite != null && im.sprite.texture != null) texs.Add(im.sprite.texture);
|
|
var rw = g as RawImage;
|
|
if (rw != null && rw.texture != null) texs.Add(rw.texture);
|
|
}
|
|
}
|
|
|
|
foreach (var t in texs)
|
|
{
|
|
var path = AssetDatabase.GetAssetPath(t);
|
|
if (string.IsNullOrEmpty(path) || !seen.Add(path)) continue;
|
|
var ti = AssetImporter.GetAtPath(path) as TextureImporter;
|
|
sb.AppendLine("--- " + path);
|
|
sb.AppendLine(" 로드된 텍스처 = " + t.width + "x" + t.height + " format=" + (t is Texture2D ? ((Texture2D)t).format.ToString() : "?")
|
|
+ " mip=" + t.mipmapCount + " filter=" + t.filterMode);
|
|
if (ti == null) { sb.AppendLine(" (TextureImporter 없음)"); continue; }
|
|
int ow = 0, oh = 0;
|
|
ti.GetSourceTextureWidthAndHeight(out ow, out oh);
|
|
sb.AppendLine(" 원본 소스 = " + ow + "x" + oh);
|
|
sb.AppendLine(" type=" + ti.textureType + " shape=" + ti.textureShape + " npot=" + ti.npotScale
|
|
+ " mipmap=" + ti.mipmapEnabled + " filter=" + ti.filterMode + " wrap=" + ti.wrapMode
|
|
+ " aniso=" + ti.anisoLevel + " sRGB=" + ti.sRGBTexture + " alphaIsTransparency=" + ti.alphaIsTransparency
|
|
+ " readable=" + ti.isReadable + " compressionQuality=" + ti.compressionQuality);
|
|
var def = ti.GetDefaultPlatformTextureSettings();
|
|
sb.AppendLine(" [Default] maxSize=" + def.maxTextureSize + " format=" + def.format + " compression=" + def.textureCompression
|
|
+ " crunched=" + def.crunchedCompression);
|
|
foreach (var plat in new[] { "Android", "iPhone" })
|
|
{
|
|
var ps = ti.GetPlatformTextureSettings(plat);
|
|
sb.AppendLine(" [" + plat + "] override=" + ps.overridden + " maxSize=" + ps.maxTextureSize + " format=" + ps.format
|
|
+ " compression=" + ps.textureCompression + " quality=" + ps.compressionQuality
|
|
+ " crunched=" + ps.crunchedCompression);
|
|
}
|
|
if (ti.textureType == TextureImporterType.Sprite)
|
|
sb.AppendLine(" [Sprite] mode=" + ti.spriteImportMode + " ppu=" + ti.spritePixelsPerUnit
|
|
+ " border=" + ti.spriteBorder);
|
|
var fi = new System.IO.FileInfo(path);
|
|
if (fi.Exists) sb.AppendLine(" 파일 크기 = " + (fi.Length / 1024) + " KB");
|
|
}
|
|
|
|
System.IO.Directory.CreateDirectory("Screenshots_WL/title");
|
|
System.IO.File.WriteAllText("Screenshots_WL/title/probe_wl793_tex.txt", sb.ToString());
|
|
return "OK -> Screenshots_WL/title/probe_wl793_tex.txt (" + sb.Length + " chars)";
|
|
}
|
|
}
|