YAMO-Unity6_MainProject/Assets/Scripts/Bitd/Scripts/LiltoonStencilPassSetter.cs
2025-06-08 00:55:10 +09:00

143 lines
5.5 KiB
C#

#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
namespace Bitd
{
public class LiltoonStencilPassSetter : EditorWindow
{
private List<GameObject> gameObjects = new List<GameObject>(); // 드래그 앤 드롭으로 받은 GameObject 목록
private string shaderNameToCheck = "lilToon"; // 확인할 쉐이더 이름
private string parameterNameToCheck = "_StencilPass"; // 확인할 파라미터 이름
private int parameterValue = 2; // = Replace
[MenuItem("Bitd/(릴툰)스탠실 Replace 설정기", false, 105)]
public static void ShowWindow()
{
GetWindow<LiltoonStencilPassSetter>("Replace 설정");
}
void OnGUI()
{
GUILayout.Label("아래에 게임오브젝트들을 넣어주세요", EditorStyles.boldLabel);
GUILayout.Label("속하는 머티리얼의 \"Stencil Pass\" 값이 Replace로 일괄 수정됩니다.", EditorStyles.helpBox);
// 드래그 앤 드롭 구역 생성
GUILayout.Space(10);
GUILayout.Label("수정할 게임오브젝트들:", EditorStyles.helpBox);
Rect dropArea = GUILayoutUtility.GetRect(0, 50, GUILayout.ExpandWidth(true));
HandleDragAndDrop(dropArea);
// 드래그된 게임 오브젝트 리스트 표시
GUILayout.Label("추가된 게임오브젝트:", EditorStyles.boldLabel);
foreach (var go in gameObjects)
{
EditorGUILayout.ObjectField(go, typeof(GameObject), true);
}
GUILayout.Space(5);
// 적용 버튼
if (GUILayout.Button("Replace로 세팅하기"))
{
ModifyMaterials();
gameObjects.Clear();
}
}
// 드래그 앤 드롭 처리
void HandleDragAndDrop(Rect dropArea)
{
Event evt = Event.current;
switch (evt.type)
{
case EventType.DragUpdated:
case EventType.DragPerform:
if (!dropArea.Contains(evt.mousePosition))
return;
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (evt.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
foreach (Object draggedObject in DragAndDrop.objectReferences)
{
if (draggedObject is GameObject)
{
gameObjects.Add((GameObject)draggedObject); // 게임 오브젝트 추가
}
}
evt.Use();
}
break;
}
}
// Material을 찾아서 파라미터를 수정하는 함수
void ModifyMaterials()
{
foreach (GameObject go in gameObjects)
{
if (go == null) continue;
// 게임 오브젝트와 자식 오브젝트들 가져오기
List<Renderer> renderers = FindAllRenderers(go);
foreach (Renderer renderer in renderers)
{
// 각 렌더러에서 사용하는 모든 머티리얼 확인
foreach (Material material in renderer.sharedMaterials)
{
if (material != null && material.shader != null)
{
// 특정 쉐이더인지 확인
if (material.shader.name.Contains(shaderNameToCheck))
{
// 파라미터가 존재하는지 확인하고 수정
if (material.HasProperty(parameterNameToCheck))
{
material.SetInt(parameterNameToCheck, parameterValue);
Debug.Log($"{go.name}에 있는 {material.name} 머티리얼이 수정되었어요!");
}
else
{
Debug.Log($"{go.name}의 {material.name} 머티리얼에는 해당 값이 없었어요!");
}
}
}
}
}
}
// 변경 사항 저장
AssetDatabase.SaveAssets();
}
// 비활성화된 오브젝트까지 포함한 모든 렌더러를 찾는 함수
List<Renderer> FindAllRenderers(GameObject obj)
{
List<Renderer> allRenderers = new List<Renderer>();
// 비활성화된 오브젝트도 포함하여 모든 오브젝트 수집
Object[] allObjects = EditorUtility.CollectDeepHierarchy(new Object[] { obj });
// 각 오브젝트에서 Renderer 컴포넌트 추출
foreach (Object o in allObjects)
{
if (o is GameObject)
{
GameObject go = (GameObject)o;
Renderer[] renderers = go.GetComponentsInChildren<Renderer>(true); // true를 사용해 비활성화된 자식까지 포함
allRenderers.AddRange(renderers);
}
}
return allRenderers;
}
}
}
#endif