Project_WL/AgentScripts/WL802b_Apply.cs

109 lines
5.0 KiB
C#

// WL802b_Apply.cs — #802 재단 2차: 세로 Safe Area 를 타이틀·로딩/팝업 프리팹까지 공통 적용 (에디트 모드 · 프리팹 컨텐츠 · Play 불필요)
// unity command run_script --file AgentScripts/WL802b_Apply.cs --entry WL802b_Apply.Resave (무변경 재저장 — 재직렬화 diff 측정용)
// unity command run_script --file AgentScripts/WL802b_Apply.cs --entry WL802b_Apply.Apply
// unity command run_script --file AgentScripts/WL802b_Apply.cs --entry WL802b_Apply.Revert (신규 패널 제거 = 2026-09-07 원상)
// 방식: 각 프리팹 캔버스 루트 직속에 **전용 루트 패널**(Graphic 없음 · 스트레치 · offset 0)을 1개 추가하고 WL.UI.SafeAreaFitter 를 붙인다.
// 기존 자식은 재부모화하지 않는다(#806 팝업 값 포함 레이아웃 회귀 0). 패널은 후속 UI 가 들어갈 안전 영역 레이어다.
// NewGameUI.prefab 은 WL_HUD 에 이미 SafeAreaFitter 가 있어 대상에서 제외한다(파일당 1개 · 중복 0).
// 롤백: 이 스크립트의 Revert() 또는 git checkout -- <프리팹 2종>
using System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine;
public static class WL802b_Apply
{
// 이번 웨이브 UI 단독 소유 핫스팟 2종 (NewGameUI 는 기존 부착 유지 → 대상 아님)
static readonly string[] Targets =
{
"Assets/ResWork/UIPrefabs/Title/TitleInfo.prefab",
"Assets/ResWork/UIPrefabs/Title/SortOrder_5.prefab",
};
public const string PanelName = "WL_SafeArea";
const int UILayer = 5;
static RectTransform FindPanel(GameObject root)
{
var t = root.transform.Find(PanelName);
return t as RectTransform;
}
static string Describe(RectTransform rt)
{
return "aMin=" + rt.anchorMin + " aMax=" + rt.anchorMax
+ " offMin=" + rt.offsetMin + " offMax=" + rt.offsetMax
+ " size=" + rt.sizeDelta + " pos=" + rt.anchoredPosition
+ " pivot=" + rt.pivot + " scale=" + rt.localScale;
}
public static object Apply()
{
var sb = new StringBuilder();
foreach (var path in Targets)
{
var root = PrefabUtility.LoadPrefabContents(path);
try
{
if (FindPanel(root) != null) { sb.AppendLine(path + " : 이미 " + PanelName + " 있음 — 건너뜀"); continue; }
var go = new GameObject(PanelName, typeof(RectTransform));
go.layer = UILayer;
var rt = (RectTransform)go.transform;
rt.SetParent(root.transform, false); // 마지막 자식 = 최상위 시블링(빈 패널이라 렌더 영향 0)
rt.localScale = Vector3.one;
rt.localRotation = Quaternion.identity;
rt.pivot = new Vector2(0.5f, 0.5f);
rt.anchorMin = Vector2.zero; // 스트레치
rt.anchorMax = Vector2.one;
rt.offsetMin = Vector2.zero; // offset 0 (= sizeDelta 0 · anchoredPosition 0)
rt.offsetMax = Vector2.zero;
go.AddComponent<WL.UI.SafeAreaFitter>(); // applyHorizontal/applyVertical 기본 true
PrefabUtility.SaveAsPrefabAsset(root, path);
sb.AppendLine(path + " : " + PanelName + " 추가 · SafeAreaFitter 부착 · " + Describe(rt));
}
finally { PrefabUtility.UnloadPrefabContents(root); }
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return sb.ToString();
}
public static object Revert()
{
var sb = new StringBuilder();
foreach (var path in Targets)
{
var root = PrefabUtility.LoadPrefabContents(path);
try
{
var panel = FindPanel(root);
if (panel == null) { sb.AppendLine(path + " : " + PanelName + " 없음 — 건너뜀"); continue; }
Object.DestroyImmediate(panel.gameObject);
PrefabUtility.SaveAsPrefabAsset(root, path);
sb.AppendLine(path + " : " + PanelName + " 제거");
}
finally { PrefabUtility.UnloadPrefabContents(root); }
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return sb.ToString();
}
/// <summary>내용 변경 없이 LoadPrefabContents→SaveAsPrefabAsset 만 수행 — 재직렬화가 diff 를 만드는지 측정한다(완료 기준 ⓓ 사전 확인).</summary>
public static object Resave()
{
var sb = new StringBuilder();
var only = new List<string>(Targets);
foreach (var path in only)
{
var root = PrefabUtility.LoadPrefabContents(path);
try { PrefabUtility.SaveAsPrefabAsset(root, path); sb.AppendLine(path + " : 무변경 재저장"); }
finally { PrefabUtility.UnloadPrefabContents(root); }
}
AssetDatabase.Refresh();
return sb.ToString();
}
}