ReorderableList는 Inspector창에서 리스트를 시각적으로 편리하게 관리할 수 있도록 도와주는 클래스다.
ReorderableList는 UnityEditorInternal 네임스페이스에 정의되어 있다.
또한 인스펙터 혹은 윈도우에서 사용이 가능하기 때문에 UnityEditor 네임스페이스도 정의해 주어야한다.
따라서 사용하려면
using UnityEditor;
using UnityEditorInternal;
[CustomEditor(typeof(Tistory))]
public class TistoryEditor : Editor
{
private void OnEnable()
{
}
public override void OnInspectorGUI()
{
}
}
를 작성해주어야 한다.
이제 OnEnable 메서드에서 ReorderableList를 생성해주고 콜백을 설정해 주면 된다.
우선 ReorderableList를 생성하는 방법에는 2가지가 있다.
1. SerializedObject와 SerializedProperty를 사용하는 방법
var reorderableList = new ReorderableList(
serializedObject,
serializedObject.FindProperty("데이터 명"),
순서 변경 여부(bool),
리스트 타이틀 여부(bool),
추가(+) 버튼 여부(bool),
삭제(-) 버튼 여부(bool));
용어 설명
SerializedObject란?
Unity 에디터에서 사용되는 클래스로, 에디터에서 직렬화(Serialize)된 필드와 프로퍼티를 편집할 수 있도록 해준다.
즉, Unity 에디터에서 특정 오브젝트를 직렬화된 상태로 다루기 위해서 UnityEngine.Object를 SerializedObject로 변환해서 사용한다.
이렇게 변환된 SerializedObject는 다시 Asset, .meta 파일로 직렬화 할 수 있다.
직관적으로 설명하자면
[CustomEditor(typeof(클래스 명))]
과 같이 있을 때, '클래스 명'을 나타낸다.
사용할 때에는 Editor에 정의되어 있는 serializedObject 프로퍼티로 사용할 수 있다.

SerializedProperty란?
SerializedObject 내의 특정 속성을 나타내는 클래스다.
리스트, 배열, 클래스, 구조체 등의 다양한 데이터를 포함할 수 있다.
시리얼라이즈된 필드 혹은 프로퍼티를 찾으려면
serializedObject.FindProperty("데이터 명")
으로 찾을 수 있다.
2. 리스트를 사용하는 방법
List<Element> elements = new List<Element>();
var reorderableList = new ReorderableList(
elements,
typeof(Element),
순서 변경 여부(bool),
리스트 타이틀 여부(bool),
추가(+) 버튼 여부(bool),
삭제(-) 버튼 여부(bool));
콜백을 설정해주는 방법에도 2가지 방법이 있다.
1. ReorderableList의 초기화 블럭에서 콜백을 초기화 시켜주는 방법
List<Element> elements = new List<Element>();
var reorderableList = new ReorderableList(elements, typeof(Element), true, true, true, true)
{
// 이 부분이 객체 초기화 블럭
// 객체 생성 후에 객체의 필드나 프로퍼티의 초기값을 설정해주는 블록
drawHeaderCallback = (rect) =>
{
EditorGUI.LabelField(rect, "타이틀 텍스트");
}
}
2. ReorderableList를 변수로 받아서 콜백을 초기화 시켜주는 방법
List<Element> elements = new List<Element>();
var reorderableList = new ReorderableList(elements, typeof(Element), true, true, true, true);
reorderableList.drawHeaderCallback = (rect) =>
{
EditorGUI.LabelField(rect, "타이틀 텍스트");
}
콜백을 초기화 시켜주는 방법을 알았으니, 콜백의 종류에 대해 알아보자.
콜백의 종류
콜백 이름 | 설명 |
---|---|
onChangedCallback | 리스트의 내용이 변경될 때 호출되는 콜백 |
onAddCallback | 요소를 추가할 때 호출되는 콜백 |
onAddDropdownCallback | 추가 버튼을 클릭하고 드롭다운 메뉴가 표시될 때 호출되는 콜백 |
onRemoveCallback | 요소를 제거할 때 호출되는 콜백 |
onSelectCallback | 요소를 선택했을 때 호출되는 콜백 |
onReorderCallback | 요소의 순서가 변경될 때 호출되는 콜백 |
onReorderCallbackWithDetails | 요소의 순서가 변경될 때 호출되는 콜백 (자세한 정보 포함) |
onMouseDragCallback | 마우스 드래그 중일 때 호출되는 콜백 |
onMouseUpCallback | 마우스 버튼을 놓았을 때 호출되는 콜백 |
drawElementCallback | 각 요소를 그리는 콜백 |
drawElementBackgroundCallback | 각 요소의 배경을 그리는 콜백 |
drawNoneElementCallback | 요소가 없을 때 표시되는 콜백 |
drawHeaderCallback | 리스트의 헤더(타이틀)를 그리는 콜백 |
drawFooterCallback | 리스트의 하단 푸터(부가 설명)를 그리는 콜백 |
elementHeightCallback | 각 요소의 높이를 결정하는 콜백 각 요소마다 다른 높이를 설정할 때 사용 |
onCanAddCallback | 요소를 추가할 수 있는지 여부를 결정하는 콜백 |
onCanRemoveCallback | 요소를 제거할 수 있는지 여부를 결정하는 콜백 |
새로운 요소를 추가하기
ReorderableList에서는 GenericMenu 클래스를 사용하여 요소를 추가해 줄 수 있다.
private Tistory _target;
private ReorderableList reorderableList;
private void OnEnable()
{
_target = target as Tistory;
List<Element> elements = new List<Element>();
reorderableList = new ReorderableList(elements, typeof(Element), true, true, true, true);
reorderableList.onAddDropdownCallback = (buttonRect, l) =>
{
InitMenu();
};
}
private void InitMenu()
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent("상태이상"), false, CreateElementCallback, typeof(AbnormalStatus));
menu.ShowAsContext();
}
private void CreateElementCallback(object obj)
{
// 새로운 ScriptableObject 인스턴스 생성 후, Element 타입으로 캐스팅
var element = ScriptableObject.CreateInstance((Type)obj) as Element;
if (element != null)
{
// 새롭게 만든 인스턴스가 Hierarchy 창에 보이지 않도록 설정
element.hideFlags = HideFlags.HideInHierarchy;
// Tistory의 elements 리스트에 추가
_target.elements.Add(element);
// 해당 Tistory ScriptableObject 에셋의 경로를 가져오기
var path = AssetDatabase.GetAssetPath(_target);
// element를 Tistory ScriptableObject 에셋에 추가하기
AssetDatabase.AddObjectToAsset(element, path);
// Tistory ScriptableObject가 변경되었음을 Unity 에디터에 알리며, 변경 사항을 저장한다.
EditorUtility.SetDirty(_target);
}
}
이제 리스트를 보여주기 위해,
reorderableList?.DoLayoutList();
를 OnInspectorGUI 메서드 내에 작성해주면 된다.
※ OnInspectorGUI 메서드는 인스펙터 창이 활성화되어 있을 때, 매 프레임마다 호출되어 GUI를 업데이트 한다.
또한 Inspector에서 값을 변경하는 등의 GUI 이벤트가 발생하면 지정된 오브젝트가 수정되었음을 알려주기 위해
if (GUI.changed)
{
EditorUtility.SetDirty(this);
}
를 작성해준다.
이러한 과정을 통해 지정된 오브젝트의 변경 사항이 저장된다.
'공부 > 유니티' 카테고리의 다른 글
[Unity] 툴팁 만들기 - part1. 배치된 툴팁 (0) | 2025.05.21 |
---|---|
[Unity] 백터의 내적과 외적 활용 - 적 탐색편 (0) | 2025.05.08 |
[Unity] 유니티 어트리뷰트 만들기 (0) | 2024.02.24 |
[Unity] 유니티 어트리뷰트 모음 (0) | 2024.02.24 |
[Unity] 스레드와 비동기 (0) | 2024.02.07 |