using System.Collections.Generic; using System.IO; using System.Text; using UnityEditor; using UnityEngine; // WL837 — ExplosiveLLC Warrior 데모 씬을 URP 프로젝트에서 보이게 하는 보정 2종 (에디트 모드 전용 · Play 중 실행 금지) // FixGuiCamera(apply) : Warrior/Demo Elements/Prefabs/Camera.prefab 의 보조 'GUI Camera'(Depth-only · TransparentFX 만) 를 끈다. // URP 는 Base 카메라마다 화면을 다시 그려 이 카메라가 메인 화면을 회색으로 덮는다(실측 2026-10-11). // ConvertMaterials(apply): Assets/ExplosiveLLC 아래 내장 Standard 셰이더 머티리얼 → Universal Render Pipeline/Lit (주요 속성 매핑). // 실행: unity command run_script --file AgentScripts/WL837_DemoFixes.cs --entry WL837_DemoFixes.FixGuiCamera --args '[true]' // unity command run_script --file AgentScripts/WL837_DemoFixes.cs --entry WL837_DemoFixes.ConvertMaterials --args '[true]' public static class WL837_DemoFixes { const string CameraPrefab = "Assets/ExplosiveLLC/Warrior/Demo Elements/Prefabs/Camera.prefab"; const string Root = "Assets/ExplosiveLLC"; public static string FixGuiCamera(bool apply) { if (EditorApplication.isPlaying) return "skipped: playing"; var root = PrefabUtility.LoadPrefabContents(CameraPrefab); try { Camera gui = null; foreach (var c in root.GetComponentsInChildren(true)) if (c.gameObject.name == "GUI Camera") gui = c; if (gui == null) return "GUI Camera: not found in " + CameraPrefab; string before = "GUI Camera enabled=" + gui.enabled + " clear=" + gui.clearFlags + " mask=" + gui.cullingMask + " depth=" + gui.depth; if (!apply || !gui.enabled) return before + (apply ? " (already off)" : " (dry run)"); gui.enabled = false; PrefabUtility.SaveAsPrefabAsset(root, CameraPrefab); return before + " -> enabled=false saved"; } finally { PrefabUtility.UnloadPrefabContents(root); } } public static string ConvertMaterials(bool apply) { if (EditorApplication.isPlaying) return "skipped: playing"; var lit = Shader.Find("Universal Render Pipeline/Lit"); if (lit == null) return "URP Lit shader not found"; var sb = new StringBuilder(); int n = 0, done = 0; foreach (var guid in AssetDatabase.FindAssets("t:Material", new[] { Root })) { var path = AssetDatabase.GUIDToAssetPath(guid); var m = AssetDatabase.LoadAssetAtPath(path); if (m == null || m.shader == null || m.shader.name != "Standard") continue; n++; if (!apply) { sb.Append("would convert: ").Append(Path.GetFileName(path)).Append('\n'); continue; } // Standard 값 보관 Texture main = m.HasProperty("_MainTex") ? m.GetTexture("_MainTex") : null; Vector2 sc = m.HasProperty("_MainTex") ? m.GetTextureScale("_MainTex") : Vector2.one, off = m.HasProperty("_MainTex") ? m.GetTextureOffset("_MainTex") : Vector2.zero; Color col = m.HasProperty("_Color") ? m.GetColor("_Color") : Color.white; Texture bump = m.HasProperty("_BumpMap") ? m.GetTexture("_BumpMap") : null; float bumpScale = m.HasProperty("_BumpScale") ? m.GetFloat("_BumpScale") : 1f; Texture metal = m.HasProperty("_MetallicGlossMap") ? m.GetTexture("_MetallicGlossMap") : null; float metallic = m.HasProperty("_Metallic") ? m.GetFloat("_Metallic") : 0f; float gloss = m.HasProperty("_Glossiness") ? m.GetFloat("_Glossiness") : 0.5f; Texture occ = m.HasProperty("_OcclusionMap") ? m.GetTexture("_OcclusionMap") : null; Texture emi = m.HasProperty("_EmissionMap") ? m.GetTexture("_EmissionMap") : null; Color emiCol = m.HasProperty("_EmissionColor") ? m.GetColor("_EmissionColor") : Color.black; bool emission = m.IsKeywordEnabled("_EMISSION"); float mode = m.HasProperty("_Mode") ? m.GetFloat("_Mode") : 0f; // 0 opaque 1 cutout 2 fade 3 transparent float cutoff = m.HasProperty("_Cutoff") ? m.GetFloat("_Cutoff") : 0.5f; m.shader = lit; if (main) { m.SetTexture("_BaseMap", main); m.SetTextureScale("_BaseMap", sc); m.SetTextureOffset("_BaseMap", off); } m.SetColor("_BaseColor", col); if (bump) { m.SetTexture("_BumpMap", bump); m.SetFloat("_BumpScale", bumpScale); m.EnableKeyword("_NORMALMAP"); } if (metal) { m.SetTexture("_MetallicGlossMap", metal); m.EnableKeyword("_METALLICSPECGLOSSMAP"); } m.SetFloat("_Metallic", metallic); m.SetFloat("_Smoothness", gloss); if (occ) { m.SetTexture("_OcclusionMap", occ); m.EnableKeyword("_OCCLUSIONMAP"); } if (emission) { m.SetColor("_EmissionColor", emiCol); if (emi) m.SetTexture("_EmissionMap", emi); m.EnableKeyword("_EMISSION"); m.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive; } if (mode >= 1.5f) { m.SetFloat("_Surface", 1); m.SetFloat("_Blend", 0); m.SetOverrideTag("RenderType", "Transparent"); m.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; m.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); m.SetFloat("_ZWrite", 0); m.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.SrcAlpha); m.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } else if (mode >= 0.5f) { m.SetFloat("_AlphaClip", 1); m.SetFloat("_Cutoff", cutoff); m.EnableKeyword("_ALPHATEST_ON"); m.SetOverrideTag("RenderType", "TransparentCutout"); m.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest; } EditorUtility.SetDirty(m); done++; sb.Append("converted: ").Append(Path.GetFileName(path)).Append(main ? " tex" : "").Append(bump ? " normal" : "").Append(metal ? " metalmap" : "").Append(mode >= 0.5f ? " mode" + mode : "").Append('\n'); } if (apply && done > 0) AssetDatabase.SaveAssets(); sb.Insert(0, "standard materials=" + n + " converted=" + done + "\n"); return sb.ToString(); } }