Streamingle_URP/Assets/Scripts/Editor/Utilities/NilotoonMaterialMatcapSetter.cs
user 4a49ecd772 Refactor: 배경/프랍 브라우저 IMGUI→UI Toolkit 전환 + USS 리디자인
- BackgroundSceneLoaderWindow: OnGUI → CreateGUI (Toolbar + ToolbarSearchField)
- PropBrowserWindow: OnGUI → CreateGUI (Toolbar + ToolbarSearchField)
- StreamingleCommon.uss: 브라우저 공통 스타일 추가 (그리드/리스트/뷰토글/액션바/상태바)
- excludeFromWeb 상태 새로고침 시 보존 수정
- 삭제된 배경 리소스 정리

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 01:55:48 +09:00

237 lines
11 KiB
C#

#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Collections.Generic;
namespace Bitd
{
public struct stMatcapInfo
{
public bool _UseMatCap;
public Texture _MatCapTex;
public Color _MatCapColor;
public Texture _MatCapBlendMask;
public int _MatCapBlendMode;
public stMatcapInfo(bool _useMatCap)
{
_UseMatCap = _useMatCap;
_MatCapTex = null;
_MatCapColor = Color.white;
_MatCapBlendMask = null;
_MatCapBlendMode = 0;
}
public stMatcapInfo(bool _useMatCap, Texture _matCapTex, Color _matCapColor,
Texture _matCapBlendMask, int _matCapBlendMode)
{
_UseMatCap = _useMatCap;
_MatCapTex = _matCapTex;
_MatCapColor = _matCapColor;
_MatCapBlendMask = _matCapBlendMask;
_MatCapBlendMode = _matCapBlendMode;
}
}
public class NiloMaterialMatcapSetter : EditorWindow
{
private const string CommonUssPath = "Assets/Scripts/Streamingle/StreamingleControl/Editor/UXML/StreamingleCommon.uss";
private const string targetShaderName = "lilToon";
private List<Material> materials = new List<Material>();
private string pEnableName_Front = "_BaseMapStackingLayer";
private string pEnableName_Back = "Enable";
private VisualElement materialListContainer;
private VisualElement dropArea;
[MenuItem("Tools/Utilities/닐로툰 매트캡 자동 인식기")]
public static void ShowWindow()
{
GetWindow<NiloMaterialMatcapSetter>("닐로툰 매트캡 자동 인식기");
}
public void CreateGUI()
{
var root = rootVisualElement;
root.AddToClassList("tool-root");
var commonUss = AssetDatabase.LoadAssetAtPath<StyleSheet>(CommonUssPath);
if (commonUss != null) root.styleSheets.Add(commonUss);
root.Add(new Label("닐로툰 매트캡 자동 인식기") { name = "title" });
root.Q<Label>("title").AddToClassList("tool-title");
root.Add(new HelpBox("선택한 닐로툰에서 릴툰 매트캡 값을 찾아 닐로툰에 자동 반영합니다.", HelpBoxMessageType.Info));
// 드래그 앤 드롭 영역
root.Add(new Label("수정할 머티리얼들:") { style = { marginTop = 8, unityFontStyleAndWeight = FontStyle.Bold } });
dropArea = new VisualElement();
dropArea.style.height = 50;
dropArea.style.backgroundColor = new Color(0, 0, 0, 0.2f);
dropArea.style.borderTopWidth = dropArea.style.borderRightWidth =
dropArea.style.borderBottomWidth = dropArea.style.borderLeftWidth = 2;
dropArea.style.borderTopColor = dropArea.style.borderRightColor =
dropArea.style.borderBottomColor = dropArea.style.borderLeftColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
dropArea.style.borderTopLeftRadius = dropArea.style.borderTopRightRadius =
dropArea.style.borderBottomLeftRadius = dropArea.style.borderBottomRightRadius = 4;
dropArea.style.justifyContent = Justify.Center;
dropArea.style.alignItems = Align.Center;
dropArea.Add(new Label("여기에 머티리얼을 드래그하세요") { style = { color = new Color(0.6f, 0.6f, 0.6f) } });
dropArea.RegisterCallback<DragUpdatedEvent>(evt =>
{
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
dropArea.style.borderTopColor = dropArea.style.borderRightColor =
dropArea.style.borderBottomColor = dropArea.style.borderLeftColor = new Color(0.4f, 0.6f, 1f);
evt.StopPropagation();
});
dropArea.RegisterCallback<DragLeaveEvent>(evt =>
{
dropArea.style.borderTopColor = dropArea.style.borderRightColor =
dropArea.style.borderBottomColor = dropArea.style.borderLeftColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
});
dropArea.RegisterCallback<DragPerformEvent>(evt =>
{
DragAndDrop.AcceptDrag();
foreach (Object draggedObject in DragAndDrop.objectReferences)
{
if (draggedObject is Material mat)
materials.Add(mat);
}
dropArea.style.borderTopColor = dropArea.style.borderRightColor =
dropArea.style.borderBottomColor = dropArea.style.borderLeftColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
RebuildMaterialList();
evt.StopPropagation();
});
root.Add(dropArea);
// 추가된 머티리얼 목록
root.Add(new Label("추가된 머티리얼:") { style = { marginTop = 8, unityFontStyleAndWeight = FontStyle.Bold } });
var materialScroll = new ScrollView { style = { maxHeight = 100 } };
materialListContainer = new VisualElement();
materialScroll.Add(materialListContainer);
root.Add(materialScroll);
// 실행 버튼
var processBtn = new Button(() =>
{
ProcessMaterials();
materials.Clear();
RebuildMaterialList();
}) { text = "자동 복사 실행" };
processBtn.style.height = 30;
processBtn.style.marginTop = 8;
processBtn.AddToClassList("btn-primary");
root.Add(processBtn);
}
private void RebuildMaterialList()
{
if (materialListContainer == null) return;
materialListContainer.Clear();
if (materials.Count == 0)
{
materialListContainer.Add(new Label("머티리얼 없음") { style = { color = new Color(0.6f, 0.6f, 0.6f), unityFontStyleAndWeight = FontStyle.Italic } });
return;
}
foreach (var mat in materials)
{
var objField = new ObjectField { value = mat, objectType = typeof(Material) };
objField.SetEnabled(false);
materialListContainer.Add(objField);
}
}
void ProcessMaterials()
{
Shader lilToonShader = Shader.Find(targetShaderName);
if (lilToonShader == null)
{
Debug.LogError("lilToon Shader를 찾을 수 없습니다. 먼저 프로젝트에 추가해주세요.");
return;
}
foreach (Material originalMaterial in materials)
{
if (originalMaterial == null) continue;
Material clonedMaterial = Object.Instantiate(originalMaterial);
clonedMaterial.shader = lilToonShader;
List<stMatcapInfo> matcapInfoList = new List<stMatcapInfo>();
stMatcapInfo newInfo1 = GetMatcapInfoByName(clonedMaterial, "_UseMatCap", true);
stMatcapInfo newInfo2 = GetMatcapInfoByName(clonedMaterial, "_UseMatCap2nd", false);
if (newInfo1._UseMatCap) matcapInfoList.Add(newInfo1);
if (newInfo2._UseMatCap) matcapInfoList.Add(newInfo2);
foreach (stMatcapInfo matcapInfo in matcapInfoList)
{
int targetLayerNumber = 0;
for (int i = 1; i <= 10; i++)
{
if (originalMaterial.GetFloat(pEnableName_Front + i.ToString() + pEnableName_Back) < 0.5f)
{
targetLayerNumber = i;
originalMaterial.SetFloat(pEnableName_Front + i.ToString() + pEnableName_Back, 1f);
break;
}
}
string layer = targetLayerNumber.ToString();
originalMaterial.SetVector($"_BaseMapStackingLayer{layer}TexUVCenterPivotScalePos", new Vector4(1, 1, 0, 0));
originalMaterial.SetVector($"_BaseMapStackingLayer{layer}TexUVScaleOffset", new Vector4(1, 1, 0, 0));
originalMaterial.SetVector($"_BaseMapStackingLayer{layer}TexUVAnimSpeed", new Vector4(0, 0, 0, 0));
originalMaterial.SetVector($"_BaseMapStackingLayer{layer}MaskTexChannel", new Vector4(0, 1, 0, 0));
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}TexUVRotatedAngle", 0);
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}TexUVRotateSpeed", 0);
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}MaskUVIndex", 0);
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}MaskInvertColor", 0);
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}TexIgnoreAlpha", 0);
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}ColorBlendMode",
matcapInfo._MatCapBlendMode == 0 ? 0 :
matcapInfo._MatCapBlendMode == 1 ? 2 :
matcapInfo._MatCapBlendMode == 2 ? 3 :
matcapInfo._MatCapBlendMode == 3 ? 4 : 5);
originalMaterial.SetTexture($"_BaseMapStackingLayer{layer}Tex", matcapInfo._MatCapTex);
originalMaterial.SetColor($"_BaseMapStackingLayer{layer}TintColor",
new Color(matcapInfo._MatCapColor.r, matcapInfo._MatCapColor.g, matcapInfo._MatCapColor.b, 1f));
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}MasterStrength", matcapInfo._MatCapColor.a);
originalMaterial.SetFloat($"_BaseMapStackingLayer{layer}TexUVIndex", 4);
originalMaterial.SetTexture($"_BaseMapStackingLayer{layer}MaskTex", matcapInfo._MatCapBlendMask);
}
DestroyImmediate(clonedMaterial);
}
AssetDatabase.SaveAssets();
}
private stMatcapInfo GetMatcapInfoByName(Material mat, string propertyName, bool isFirst)
{
string plusName = string.Empty;
if (!isFirst) plusName = "2nd";
if (mat.HasProperty(propertyName) && mat.GetInt(propertyName) == 1)
{
return new stMatcapInfo(true,
mat.GetTexture("_MatCap" + plusName + "Tex"),
mat.GetColor("_MatCap" + plusName + "Color"),
mat.GetTexture("_MatCap" + plusName + "BlendMask"),
mat.GetInt("_MatCap" + plusName + "BlendMode"));
}
return new stMatcapInfo(false);
}
}
}
#endif