using UnityEngine; using UnityEditor; public class SmartMaterialConverterProFixed : EditorWindow { [MenuItem("Tools/マテリアル一括変更/究極版・改:URP Lit に変換 (Base/Normal/ARM引継ぎ)")] public static void ConvertToURPProFixed() { Undo.RecordObjects(Selection.objects, "Pro Fixed Convert to URP"); int count = 0; Shader newShader = Shader.Find("Universal Render Pipeline/Lit"); if (newShader == null) return; foreach (Object obj in Selection.objects) { Material mat = obj as Material; if (mat == null) continue; if (mat.shader.name == "Hidden/InternalErrorShader") { mat.shader = newShader; EditorUtility.SetDirty(mat); continue; } Texture baseTex = null; Texture normalTex = null; Texture maskTex = null; Texture fallbackBaseTex = null; // 最強版の「最初に見つけた画像」を記憶する保険 Color oldColor = Color.white; bool foundColor = false; if (mat.HasProperty("_Color")) { oldColor = mat.GetColor("_Color"); foundColor = true; } else if (mat.HasProperty("_BaseColor")) { oldColor = mat.GetColor("_BaseColor"); foundColor = true; } string[] texNames = mat.GetTexturePropertyNames(); foreach (string tName in texNames) { Texture t = mat.GetTexture(tName); if (t == null) continue; string pNameLower = tName.ToLower(); string tNameLower = t.name.ToLower(); // ① Normal Map の判定 if (pNameLower.Contains("norm") || pNameLower.Contains("bump") || tNameLower.Contains("norm") || tNameLower.Contains("bump")) { if (normalTex == null) normalTex = t; continue; // 見つけたら次の画像へ } // ② ARM / Mask / Metallic などの判定 if (pNameLower.Contains("arm") || pNameLower.Contains("mask") || pNameLower.Contains("met") || pNameLower.Contains("rough") || pNameLower.Contains("occ") || tNameLower.Contains("arm") || tNameLower.Contains("mask") || tNameLower.Contains("met") || tNameLower.Contains("rough") || tNameLower.Contains("occ")) { if (maskTex == null) maskTex = t; continue; } // ③ Emission (発光) はBaseMapにしないよう除外 if (pNameLower.Contains("emi") || tNameLower.Contains("emi")) { continue; } // ④ Base Map の判定(※まだ見つかっていない場合のみ登録して上書きを防ぐ) if (pNameLower.Contains("base") || pNameLower.Contains("alb") || pNameLower.Contains("diff") || pNameLower.Contains("main") || pNameLower.Contains("color") || tNameLower.Contains("base") || tNameLower.Contains("alb") || tNameLower.Contains("diff") || tNameLower.Contains("main") || tNameLower.Contains("color")) { if (baseTex == null) baseTex = t; continue; } // ⑤ どのキーワードにも引っかからなかった最初の画像を、最強版と同じように「保険」として記憶 if (fallbackBaseTex == null) { fallbackBaseTex = t; } } // 最終決定:明確なキーワードでBaseMapが見つからなかったら、最強版の保険を採用する if (baseTex == null) { baseTex = fallbackBaseTex; } // URP Lit にシェーダーを変更 mat.shader = newShader; // 各テクスチャと色の流し込み if (mat.HasProperty("_BaseMap") && baseTex != null) mat.SetTexture("_BaseMap", baseTex); if (mat.HasProperty("_BaseColor") && foundColor) mat.SetColor("_BaseColor", oldColor); if (mat.HasProperty("_BumpMap") && normalTex != null) { mat.SetTexture("_BumpMap", normalTex); mat.EnableKeyword("_NORMALMAP"); } if (maskTex != null) { if (mat.HasProperty("_MetallicGlossMap")) { mat.SetTexture("_MetallicGlossMap", maskTex); mat.EnableKeyword("_METALLICSGLOSSMAP"); } if (mat.HasProperty("_OcclusionMap")) mat.SetTexture("_OcclusionMap", maskTex); } EditorUtility.SetDirty(mat); count++; } AssetDatabase.SaveAssets(); Debug.Log($"{count} 個のマテリアルをURP Litに変換し、Base/Normal/ARMを正しく引き継ぎました!"); } }