210 lines
9.9 KiB
C#
210 lines
9.9 KiB
C#
// WL-813g (#813) — 설정 에셋 2종 생성 + NewGameUI.prefab 에 텍스트 연출 노드 3개 · 슬롯 오버라이드 컴포넌트 추가.
|
|
// 실행: unity command run_script --file AgentScripts/WL813g_Apply.cs --entry WL813g_Apply.CreateSettings
|
|
// unity command run_script --file AgentScripts/WL813g_Apply.cs --entry WL813g_Apply.Resave
|
|
// unity command run_script --file AgentScripts/WL813g_Apply.cs --entry WL813g_Apply.Apply
|
|
// unity command run_script --file AgentScripts/WL813g_Apply.cs --entry WL813g_Apply.Revert
|
|
// 🔴 run_script 파일은 파일마다 독립 어셈블리 — 다른 AgentScript 상수 참조 불가(813c 교훈).
|
|
|
|
using System.Text;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
public static class WL813g_Apply
|
|
{
|
|
public const string NewGameUIPath = "Assets/Res_Addr/MainUI/NewGameUI.prefab";
|
|
public const string SettingsDir = "Assets/WL/UI/Settings/Resources/WL";
|
|
public const string TextSettingsPath = SettingsDir + "/WLCombatTextSettings.asset";
|
|
public const string SlotPresetPath = SettingsDir + "/WLSkillSlotPreset.asset";
|
|
public const string HudPath = "IngameUIs/WL_HUD";
|
|
public const string PadPath = "IngameUIs/BattleUI";
|
|
public const string KillChainName = "WL_KillChainText";
|
|
public const string LootToastName = "WL_LootToast";
|
|
public const string StatPopupName = "WL_StatPopup";
|
|
const string TmpFontGuid = "a387e325271126742ad15569dba1ac57"; // 813c 가 실측한 SkillCard/t_cooltime 폰트
|
|
const int UILayer = 5;
|
|
|
|
static Transform FindByPath(Transform root, string path)
|
|
{
|
|
var cur = root;
|
|
foreach (var part in path.Split('/'))
|
|
{
|
|
Transform next = null;
|
|
for (int i = 0; i < cur.childCount; i++)
|
|
if (cur.GetChild(i).name == part) { next = cur.GetChild(i); break; }
|
|
if (next == null) return null;
|
|
cur = next;
|
|
}
|
|
return cur;
|
|
}
|
|
|
|
static void EnsureFolder(string dir)
|
|
{
|
|
var parts = dir.Split('/');
|
|
var cur = parts[0];
|
|
for (int i = 1; i < parts.Length; i++)
|
|
{
|
|
var next = cur + "/" + parts[i];
|
|
if (!AssetDatabase.IsValidFolder(next)) AssetDatabase.CreateFolder(cur, parts[i]);
|
|
cur = next;
|
|
}
|
|
}
|
|
|
|
/// <summary>설정 에셋 2종 생성(이미 있으면 값 유지 · 덮어쓰지 않는다).</summary>
|
|
public static object CreateSettings()
|
|
{
|
|
var sb = new StringBuilder();
|
|
EnsureFolder(SettingsDir);
|
|
|
|
var text = AssetDatabase.LoadAssetAtPath<WL.UI.WLCombatTextSettings>(TextSettingsPath);
|
|
if (text == null)
|
|
{
|
|
text = ScriptableObject.CreateInstance<WL.UI.WLCombatTextSettings>();
|
|
AssetDatabase.CreateAsset(text, TextSettingsPath);
|
|
sb.AppendLine("생성: " + TextSettingsPath);
|
|
}
|
|
else sb.AppendLine("이미 있음(값 유지): " + TextSettingsPath);
|
|
|
|
var slot = AssetDatabase.LoadAssetAtPath<WL.UI.WLSkillSlotPreset>(SlotPresetPath);
|
|
if (slot == null)
|
|
{
|
|
slot = ScriptableObject.CreateInstance<WL.UI.WLSkillSlotPreset>();
|
|
AssetDatabase.CreateAsset(slot, SlotPresetPath);
|
|
sb.AppendLine("생성: " + SlotPresetPath);
|
|
}
|
|
else sb.AppendLine("이미 있음(값 유지): " + SlotPresetPath);
|
|
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
WL.UI.WLCombatTextSettings.ClearCache();
|
|
WL.UI.WLSkillSlotPreset.ClearCache();
|
|
|
|
sb.AppendLine("── 데미지 리듬(기준서 §B 요소 2)");
|
|
sb.AppendLine(" normal=" + text.damageNormalSeconds + "s crit=" + text.damageCritSeconds +
|
|
"s critScale=" + text.damageCritScale + " maxConcurrent=" + text.damageMaxConcurrent);
|
|
sb.AppendLine("── 연쇄 문구 / 토스트 / 스탯 팝업");
|
|
sb.AppendLine(" killChain=" + text.killChainSeconds + "s punch=" + text.killChainPunchScale +
|
|
" topPx=" + text.killChainTopOffsetPx +
|
|
" · loot=" + text.lootToastSeconds + "s lines=" + text.lootToastLines +
|
|
" · stat=" + text.statPopupSeconds + "s rows=" + text.statPopupRows);
|
|
sb.AppendLine("── 슬롯 오버라이드(813n)");
|
|
sb.Append(WL.UI.WLSkillSlotOverride.ResolveDump(slot));
|
|
return sb.ToString();
|
|
}
|
|
|
|
/// <summary>무변경 재저장 — 프리팹 편집 전에 재직렬화 diff 가 생기는지 먼저 잰다(802b·813c 교훈).</summary>
|
|
public static object Resave()
|
|
{
|
|
var root = PrefabUtility.LoadPrefabContents(NewGameUIPath);
|
|
try { PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath); }
|
|
finally { PrefabUtility.UnloadPrefabContents(root); }
|
|
AssetDatabase.Refresh();
|
|
return NewGameUIPath + " : 무변경 재저장 (git diff 로 재직렬화 여부 확인)";
|
|
}
|
|
|
|
static Transform EnsureNode(Transform parent, string name, StringBuilder sb)
|
|
{
|
|
var t = parent.Find(name);
|
|
if (t == null)
|
|
{
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|
go.layer = UILayer;
|
|
t = go.transform;
|
|
((RectTransform)t).SetParent((RectTransform)parent, false);
|
|
sb.AppendLine(parent.name + "/" + name + " : 노드 추가");
|
|
}
|
|
else sb.AppendLine(parent.name + "/" + name + " : 이미 있음");
|
|
return t;
|
|
}
|
|
|
|
public static object Apply()
|
|
{
|
|
var sb = new StringBuilder();
|
|
var text = AssetDatabase.LoadAssetAtPath<WL.UI.WLCombatTextSettings>(TextSettingsPath);
|
|
if (text == null) return "🔴 " + TextSettingsPath + " 없음 — CreateSettings 먼저";
|
|
|
|
TMPro.TMP_FontAsset font = null;
|
|
var fontPath = AssetDatabase.GUIDToAssetPath(TmpFontGuid);
|
|
if (!string.IsNullOrEmpty(fontPath)) font = AssetDatabase.LoadAssetAtPath<TMPro.TMP_FontAsset>(fontPath);
|
|
sb.AppendLine("폰트: " + (font != null ? fontPath : "「미확인」 — TMP 기본 폰트로 떨어진다"));
|
|
|
|
var root = PrefabUtility.LoadPrefabContents(NewGameUIPath);
|
|
try
|
|
{
|
|
// ── ① 텍스트 연출 3종 = IngameUIs/WL_HUD 아래(802b SafeAreaFitter 레이어 · 813c 규칙)
|
|
var hud = FindByPath(root.transform, HudPath);
|
|
if (hud == null) sb.AppendLine("🔴 " + HudPath + " 없음");
|
|
else
|
|
{
|
|
var kc = EnsureNode(hud, KillChainName, sb);
|
|
var kct = kc.GetComponent<WL.UI.KillChainText>();
|
|
if (kct == null) { kct = kc.gameObject.AddComponent<WL.UI.KillChainText>(); sb.AppendLine(" KillChainText 추가"); }
|
|
if (font != null) kct.SetFont(font);
|
|
sb.AppendLine(" build made=" + kct.BuildIfNeeded() + " · " + kct.ApplyLayout());
|
|
kct.Hide();
|
|
|
|
var lt = EnsureNode(hud, LootToastName, sb);
|
|
var ltc = lt.GetComponent<WL.UI.LootToast>();
|
|
if (ltc == null) { ltc = lt.gameObject.AddComponent<WL.UI.LootToast>(); sb.AppendLine(" LootToast 추가"); }
|
|
if (font != null) ltc.SetFont(font);
|
|
sb.AppendLine(" build made=" + ltc.BuildIfNeeded() + " · " + ltc.ApplyLayout());
|
|
ltc.HideAll();
|
|
|
|
var sp = EnsureNode(hud, StatPopupName, sb);
|
|
var spc = sp.GetComponent<WL.UI.StatPopup>();
|
|
if (spc == null) { spc = sp.gameObject.AddComponent<WL.UI.StatPopup>(); sb.AppendLine(" StatPopup 추가"); }
|
|
if (font != null) spc.SetFont(font);
|
|
sb.AppendLine(" build made=" + spc.BuildIfNeeded() + " · " + spc.ApplyLayout());
|
|
spc.Hide();
|
|
}
|
|
|
|
// ── ② 슬롯 장착 로컬 오버라이드 = IngameUIs/BattleUI 인스턴스 전용 추가 컴포넌트(813c 방식)
|
|
var pad = FindByPath(root.transform, PadPath);
|
|
if (pad == null) sb.AppendLine("🔴 " + PadPath + " 없음");
|
|
else
|
|
{
|
|
var ov = pad.GetComponent<WL.UI.WLSkillSlotOverride>();
|
|
if (ov == null) { ov = pad.gameObject.AddComponent<WL.UI.WLSkillSlotOverride>(); sb.AppendLine(PadPath + " : WLSkillSlotOverride 추가"); }
|
|
else sb.AppendLine(PadPath + " : WLSkillSlotOverride 이미 있음");
|
|
var so = new SerializedObject(ov);
|
|
so.FindProperty("target").objectReferenceValue = pad.GetComponent<BattleUI>();
|
|
so.ApplyModifiedPropertiesWithoutUndo();
|
|
sb.AppendLine(" target=BattleUI 주입 · BattleUI.prefab 원본 무수정(인스턴스 전용 추가 컴포넌트)");
|
|
}
|
|
|
|
PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath);
|
|
}
|
|
finally { PrefabUtility.UnloadPrefabContents(root); }
|
|
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static object Revert()
|
|
{
|
|
var sb = new StringBuilder();
|
|
var root = PrefabUtility.LoadPrefabContents(NewGameUIPath);
|
|
try
|
|
{
|
|
var hud = FindByPath(root.transform, HudPath);
|
|
if (hud != null)
|
|
foreach (var n in new[] { KillChainName, LootToastName, StatPopupName })
|
|
{
|
|
var t = hud.Find(n);
|
|
if (t != null) { Object.DestroyImmediate(t.gameObject); sb.AppendLine(HudPath + "/" + n + " : 제거"); }
|
|
}
|
|
var pad = FindByPath(root.transform, PadPath);
|
|
if (pad != null)
|
|
{
|
|
var ov = pad.GetComponent<WL.UI.WLSkillSlotOverride>();
|
|
if (ov != null) { Object.DestroyImmediate(ov, true); sb.AppendLine(PadPath + " : WLSkillSlotOverride 제거"); }
|
|
}
|
|
PrefabUtility.SaveAsPrefabAsset(root, NewGameUIPath);
|
|
}
|
|
finally { PrefabUtility.UnloadPrefabContents(root); }
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
return sb.ToString();
|
|
}
|
|
}
|