캐릭터 로드
This commit is contained in:
122
Assets/02_Scripts/Editor/VrmShaderBuildSetup.cs
Normal file
122
Assets/02_Scripts/Editor/VrmShaderBuildSetup.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// VRM 런타임 로딩에 필요한 셰이더를 빌드에 강제로 포함시킨다.
|
||||
///
|
||||
/// 왜 필요한가: Unity 는 어떤 머티리얼도 참조하지 않는 셰이더를 빌드에서 제거한다.
|
||||
/// 에디터에서는 프로젝트의 모든 셰이더를 찾을 수 있어 문제가 드러나지 않지만,
|
||||
/// 빌드된 플레이어에서는 Shader.Find 가 null 을 돌려주고
|
||||
/// "ArgumentNullException: Parameter name: Shader" 로 로드가 실패한다.
|
||||
///
|
||||
/// 일반적인 게임이라면 씬에 쓰인 머티리얼을 보고 Unity 가 알아서 판단하지만,
|
||||
/// 우리는 실행 중에 임의의 VRM 을 불러오므로 어떤 셰이더가 필요할지 빌드 시점에
|
||||
/// 알 수 없다. 그래서 Always Included Shaders 에 명시적으로 등록한다.
|
||||
/// </summary>
|
||||
public static class VrmShaderBuildSetup
|
||||
{
|
||||
// UrpVrm10MaterialDescriptorGenerator / BuiltInVrm10MaterialDescriptorGenerator 가
|
||||
// 참조하는 셰이더들. 현재 URP 를 쓰지만 파이프라인을 바꿔도 되도록 둘 다 넣는다.
|
||||
static readonly string[] RequiredShaders =
|
||||
{
|
||||
"VRM10/Universal Render Pipeline/MToon10", // URP 용 MToon (지금 쓰는 것)
|
||||
"VRM10/MToon10", // Built-in 용 MToon
|
||||
"Universal Render Pipeline/Lit", // MToon 이 아닌 PBR 머티리얼
|
||||
"Universal Render Pipeline/Unlit",
|
||||
"UniGLTF/UniUnlit",
|
||||
};
|
||||
|
||||
[MenuItem("Tools/Desktop Overlay/6. Include VRM Shaders In Build")]
|
||||
public static void IncludeShaders()
|
||||
{
|
||||
var graphicsSettings = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/GraphicsSettings.asset");
|
||||
if (graphicsSettings == null || graphicsSettings.Length == 0)
|
||||
{
|
||||
Debug.LogError("[VrmShaderBuildSetup] GraphicsSettings.asset 을 열지 못했습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
var so = new SerializedObject(graphicsSettings[0]);
|
||||
var list = so.FindProperty("m_AlwaysIncludedShaders");
|
||||
if (list == null)
|
||||
{
|
||||
Debug.LogError("[VrmShaderBuildSetup] m_AlwaysIncludedShaders 프로퍼티를 찾지 못했습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 이미 들어있는 것 수집
|
||||
var existing = new HashSet<Shader>();
|
||||
for (int i = 0; i < list.arraySize; i++)
|
||||
{
|
||||
var s = list.GetArrayElementAtIndex(i).objectReferenceValue as Shader;
|
||||
if (s != null) existing.Add(s);
|
||||
}
|
||||
|
||||
var added = new List<string>();
|
||||
var already = new List<string>();
|
||||
var notFound = new List<string>();
|
||||
|
||||
foreach (var name in RequiredShaders)
|
||||
{
|
||||
var shader = Shader.Find(name);
|
||||
if (shader == null)
|
||||
{
|
||||
notFound.Add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existing.Contains(shader))
|
||||
{
|
||||
already.Add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
list.InsertArrayElementAtIndex(list.arraySize);
|
||||
list.GetArrayElementAtIndex(list.arraySize - 1).objectReferenceValue = shader;
|
||||
existing.Add(shader);
|
||||
added.Add(name);
|
||||
}
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
var sb = new StringBuilder("[VrmShaderBuildSetup] Always Included Shaders 갱신\n");
|
||||
if (added.Count > 0)
|
||||
{
|
||||
sb.AppendLine($"추가됨 ({added.Count})");
|
||||
foreach (var s in added) sb.AppendLine(" + " + s);
|
||||
}
|
||||
if (already.Count > 0)
|
||||
{
|
||||
sb.AppendLine($"이미 있음 ({already.Count})");
|
||||
foreach (var s in already) sb.AppendLine(" = " + s);
|
||||
}
|
||||
if (notFound.Count > 0)
|
||||
{
|
||||
sb.AppendLine($"찾지 못함 ({notFound.Count}) — 해당 파이프라인을 안 쓰면 정상입니다");
|
||||
foreach (var s in notFound) sb.AppendLine(" ? " + s);
|
||||
}
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("이제 다시 빌드하세요.");
|
||||
|
||||
Debug.Log(sb.ToString());
|
||||
}
|
||||
|
||||
[MenuItem("Tools/Desktop Overlay/7. Log Always Included Shaders")]
|
||||
public static void LogIncluded()
|
||||
{
|
||||
var graphicsSettings = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/GraphicsSettings.asset");
|
||||
var so = new SerializedObject(graphicsSettings[0]);
|
||||
var list = so.FindProperty("m_AlwaysIncludedShaders");
|
||||
|
||||
var sb = new StringBuilder($"[VrmShaderBuildSetup] Always Included Shaders ({list.arraySize}개)\n");
|
||||
for (int i = 0; i < list.arraySize; i++)
|
||||
{
|
||||
var s = list.GetArrayElementAtIndex(i).objectReferenceValue as Shader;
|
||||
sb.AppendLine($" [{i}] {(s != null ? s.name : "<null>")}");
|
||||
}
|
||||
Debug.Log(sb.ToString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user