86 lines
4.0 KiB
C#
86 lines
4.0 KiB
C#
|
|
// WL772_MatFix.cs — PD 지시 #772 : 맵 프리팹의 마젠타(셰이더 깨짐 / null 머티리얼) 진단 + URP 업그레이드
|
||
|
|
// 진단 : unity command run_script --file AgentScripts/WL772_MatFix.cs --entry WL772_MatFix.Diag --args '["Assets/Res_Addr/Map/WL_Nature03.prefab"]'
|
||
|
|
// 수리 : ... --entry WL772_MatFix.Fix --args '["Assets/Res_Addr/Map/WL_Nature03.prefab"]'
|
||
|
|
// Fix 는 머티리얼 에셋의 셰이더만 Built-in → URP 로 승격한다(MaterialUpgrader). 프리팹은 건드리지 않는다.
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Text;
|
||
|
|
using UnityEngine;
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEditor.Rendering;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
public static class WL772_MatFix
|
||
|
|
{
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
static readonly string[] BuiltIn = { "Standard", "Standard (Specular setup)", "Legacy Shaders/", "Mobile/", "Particles/", "Nature/", "Unlit/Texture", "Unlit/Color", "Unlit/Transparent" };
|
||
|
|
|
||
|
|
static List<Material> Collect(string prefabPath, StringBuilder sb)
|
||
|
|
{
|
||
|
|
var bad = new List<Material>();
|
||
|
|
var root = PrefabUtility.LoadPrefabContents(prefabPath);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var seen = new HashSet<string>();
|
||
|
|
foreach (var r in root.GetComponentsInChildren<Renderer>(true))
|
||
|
|
foreach (var m in r.sharedMaterials)
|
||
|
|
{
|
||
|
|
if (m == null) { if (seen.Add("NULLSLOT:" + r.name)) sb.AppendLine(" null 머티리얼 슬롯 — " + r.name); continue; }
|
||
|
|
var sn = m.shader != null ? m.shader.name : "(shader null)";
|
||
|
|
bool broken = m.shader == null || sn == "Hidden/InternalErrorShader" || BuiltIn.Any(b => sn.StartsWith(b));
|
||
|
|
if (!broken) continue;
|
||
|
|
var path = AssetDatabase.GetAssetPath(m);
|
||
|
|
if (!seen.Add(path + "|" + sn)) continue;
|
||
|
|
sb.AppendLine(string.Format(" [{0}] {1} ← {2}", sn, m.name, path));
|
||
|
|
if (!string.IsNullOrEmpty(path) && path.StartsWith("Assets/")) bad.Add(m);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
finally { PrefabUtility.UnloadPrefabContents(root); }
|
||
|
|
return bad;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static object Diag(string prefabPath)
|
||
|
|
{
|
||
|
|
var sb = new StringBuilder("# " + prefabPath + "\n");
|
||
|
|
var bad = Collect(prefabPath, sb);
|
||
|
|
sb.AppendLine("수리 대상 머티리얼 = " + bad.Count);
|
||
|
|
return sb.ToString();
|
||
|
|
}
|
||
|
|
|
||
|
|
public static object Fix(string prefabPath)
|
||
|
|
{
|
||
|
|
var sb = new StringBuilder("# " + prefabPath + "\n");
|
||
|
|
var bad = Collect(prefabPath, sb);
|
||
|
|
int ok = 0, fail = 0;
|
||
|
|
foreach (var m in bad)
|
||
|
|
{
|
||
|
|
var before = m.shader != null ? m.shader.name : "(null)";
|
||
|
|
try
|
||
|
|
{
|
||
|
|
MaterialUpgrader.Upgrade(m, new UnityEditor.Rendering.Universal.StandardUpgrader(before), MaterialUpgrader.UpgradeFlags.None);
|
||
|
|
}
|
||
|
|
catch { }
|
||
|
|
if (m.shader == null || m.shader.name == before || m.shader.name == "Hidden/InternalErrorShader")
|
||
|
|
{
|
||
|
|
// 폴백: URP Lit 로 직접 지정하고 주요 값을 옮긴다
|
||
|
|
var col = m.HasProperty("_Color") ? m.GetColor("_Color") : Color.white;
|
||
|
|
var tex = m.HasProperty("_MainTex") ? m.GetTexture("_MainTex") : null;
|
||
|
|
var lit = Shader.Find("Universal Render Pipeline/Lit");
|
||
|
|
if (lit == null) { fail++; sb.AppendLine(" FAIL(URP Lit 없음) " + m.name); continue; }
|
||
|
|
m.shader = lit;
|
||
|
|
if (m.HasProperty("_BaseColor")) m.SetColor("_BaseColor", col);
|
||
|
|
if (tex != null && m.HasProperty("_BaseMap")) m.SetTexture("_BaseMap", tex);
|
||
|
|
}
|
||
|
|
EditorUtility.SetDirty(m);
|
||
|
|
ok++;
|
||
|
|
sb.AppendLine(string.Format(" {0} : {1} -> {2}", m.name, before, m.shader != null ? m.shader.name : "(null)"));
|
||
|
|
}
|
||
|
|
AssetDatabase.SaveAssets();
|
||
|
|
sb.AppendLine(string.Format("업그레이드 {0} · 실패 {1}", ok, fail));
|
||
|
|
return sb.ToString();
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|