에셋을 추가하여, 객체를 사용하다보면 2D 소팅 레이어가 개발자의 의도대로 설정되어 있지 않은 경우가 대부분 입니다.
하지만, 객체는 여러 텍스쳐가 결합되어 구현된 오브젝트이기에 모든 하위 컴포넌트의 SpriteRenderer에 접근하여 소팅 레이어를 수정하는 행위는 비효율적인 작업 방식입니다.
그렇기 때문에, 드래그 앤 드롭 방식으로 객체를 선택하고, 소팅 레이어를 선택하여 하위 컴포넌트의 모든 레이어를 수정할 수 있는 자동화 툴이 필요했습니다.
드래그 앤 드롭하여, 객체를 선택합니다.
드롭박스로 소팅레이어를 선택한 후에, 소팅 레이어 설정 버튼을 누르면. 해당 객체가 가지고 있는 모든 SpriteRenderer 컴포넌트에 접근하여, 소팅레이어를 선택한 레이어로 수정해줍니다.
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class SortingLayerEditor : EditorWindow
{
private List<GameObject> targetObjects = new List<GameObject>(); // 대상 객체 목록
private string[] sortingLayerNames; // 소팅 레이어 이름 목록
private int sortingLayerIndex = 0; // 현재 선택된 소팅 레이어 인덱스
[MenuItem("Tools/Sorting Layer Editor")]
public static void ShowWindow()
{
GetWindow<SortingLayerEditor>("소팅 레이어 에디터"); // 에디터 창 이름 설정
}
void OnEnable()
{
sortingLayerNames = GetSortingLayerNames(); // 소팅 레이어 이름 목록 초기화
}
void OnGUI()
{
GUILayout.Label("선택된 객체의 소팅 레이어 설정", EditorStyles.boldLabel); // UI 제목
sortingLayerIndex = EditorGUILayout.Popup("소팅 레이어", sortingLayerIndex, sortingLayerNames); // 소팅 레이어 선택 드롭다운 메뉴
Rect dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));
GUI.Box(dropArea, "여기에 게임 오브젝트를 드래그 앤 드롭하세요");
ProcessDragAndDrop(dropArea); // 드래그 앤 드롭 처리
DisplayObjectList(); // 객체 목록 표시
if (GUILayout.Button("소팅 레이어 설정"))
{
SetSortingLayer(); // 소팅 레이어 설정
}
}
#region 객체 선택(드래그 앤 드롭), 객체 출력
// 객체 드래그 앤 드롭
private void ProcessDragAndDrop(Rect dropArea)
{
Event e = Event.current;
switch (e.type)
{
case EventType.DragUpdated:
case EventType.DragPerform:
if (!dropArea.Contains(e.mousePosition))
return;
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (e.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
foreach (Object draggedObject in DragAndDrop.objectReferences)
{
if (draggedObject is GameObject gameObject)
{
AddGameObject(gameObject); // 드래그된 객체 추가
}
}
}
break;
}
}
// 객체 추가
private void AddGameObject(GameObject gameObject)
{
if (!targetObjects.Contains(gameObject))
{
targetObjects.Add(gameObject); // 객체를 목록에 추가
}
}
// 선택 객체 제거
private void RemoveGameObject(GameObject gameObject)
{
targetObjects.Remove(gameObject); // 객체를 목록에서 제거
}
// 객체 출력
private void DisplayObjectList()
{
foreach (GameObject gameObject in targetObjects)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.ObjectField(gameObject, typeof(GameObject), false); // 객체 표시
if (GUILayout.Button("제거", GUILayout.Width(80)))
{
RemoveGameObject(gameObject); // 제거 버튼 클릭 시 객체 제거
break; // 객체가 제거되었으므로 반복 종료
}
EditorGUILayout.EndHorizontal();
}
}
#endregion
#region 소팅 레이어 설정
private void SetSortingLayer()
{
foreach (GameObject targetObject in targetObjects)
{
if (targetObject != null)
{
SpriteRenderer[] spriteRenderers = targetObject.GetComponentsInChildren<SpriteRenderer>(); // 하위 객체 포함 모든 SpriteRenderer 가져오기
foreach (SpriteRenderer sr in spriteRenderers)
{
sr.sortingLayerName = sortingLayerNames[sortingLayerIndex]; // 소팅 레이어 설정
}
Debug.Log($"'{targetObject.name}'의 {spriteRenderers.Length}개의 스프라이트 렌더러에 '{sortingLayerNames[sortingLayerIndex]}' 소팅 레이어가 설정되었습니다.");
}
}
}
#endregion
#region 소팅 레이어 드롭박스 출력
private string[] GetSortingLayerNames()
{
int layerCount = SortingLayer.layers.Length;
string[] layerNames = new string[layerCount];
for (int i = 0; i < layerCount; i++)
{
layerNames[i] = SortingLayer.layers[i].name; // 소팅 레이어 이름 배열 생성
}
return layerNames;
}
#endregion
}