[커스텀 에디터]
● Unity에서 Editor 폴더 안에 들어 있는 스크립트는 런타임이 아닌 에디터 환경에서만 동작하며 Unity가 실행되지 않아도 백그라운드에서 자동으로 컴파일된다.
■ 동작 방식
● Assets/Editor/ 또는 AnyFolder/Editor/ 안에 있는 스크립트는 Unity가 구동될 때 에디터 전용으로 따로 컴파일된다.
● Unity는 스크립트를 Assembly 단위로 나누어 처리하며 Editor 폴더 안의 스크립트는 Assembly-CSharp-Editor.dll에 컴파일된다.
● 이러한 스크립트는 게임 빌드에는 포함되지 않는다.
■ 커스텀 에디터 예시 1) 플레이어 스탯
● EditorGUILayout.ObjectField(...)
○ 현재 인스펙터에서 MonoScript (스크립트 파일 참조)를 보여 준다.
○ false를 주면 읽기 전용 필드로 보여 준다.
○ 즉, 스크립트가 어디 연결되었는지 사용자에게 알려 주는 역할만 한다.
EditorGUILayout.ObjectField("Scripts", MonoScript.FromMonoBehaviour(playerStats), typeof(MonoScript), false);
● EditorGUILayout.Space()
○ 인스펙터 UI에서 공백 줄을 추가한다.
○ 시각적으로 항목 간 여백을 두어 가독성을 높이는 역할을 한다.
EditorGUILayout.Space();
● EditorGUILayout.HelpBox(...)
○ 인스펙터 내에 안내 박스(알림창)를 추가한다.
○ MessageType에 따라 아이콘과 색상이 다르게 표시된다.
○ Info, Warning, Error, None
EditorGUILayout.HelpBox("주인공 캐릭터 스탯", MessageType.Info);
● EditorGUILayout.IntField(...)
○ 정수형 필드(int)를 입력받는 UI를 표시한다.
○ 유저가 직접 수치 입력 가능하다.
playerStats.hp = EditorGUILayout.IntField("생명", playerStats.hp);
● EditorGUILayout.IntSlider(...)
○ 슬라이더 형태로 정수 입력 UI를 구성한다.
○ 최소값~최대값 범위로 값을 제한할 수 있다.
playerStats.mp = EditorGUILayout.IntSlider("마나", playerStats.mp, 0, 100);
● EditorGUILayout.BeginHorizontal() / EndHorizontal()
○ 가로 방향으로 GUI 요소를 배치한다.
○ 두 개 이상의 버튼 등을 한 줄에 나란히 배치할 때 유용하다.
EditorGUILayout.BeginHorizontal();
// 버튼들...
EditorGUILayout.EndHorizontal();
● GUILayout.Button(...)
○ 버튼을 생성하고 해당 버튼이 클릭되었는지 여부를 확인한다.
○ if(GUILayout.Button(...)) 형태로 사용되며 클릭 시 내부 로직을 실행한다.
if (GUILayout.Button(playerStats.isGodMode ? "일반모드로 전환" : "무적모드로 전환"))
{
playerStats.isGodMode = !playerStats.isGodMode;
}
● 인스펙터 화면

■ 커스텀 에디터 예시 2) 게임 매니저
● [CustomEditor(typeof(GameManager))]
○ Unity Editor에게 GameManager 타입의 오브젝트를 커스텀 인스펙터로 그릴 때는 이 클래스를 사용하라고 알려 준다.
○ 즉, GameMaanger 컴포넌트를 인스펙터에서 특별한 방식으로 표시하고 싶을 때 사용된다.
[CustomEditor(typeof(GameManager))]
public class GameManagerEditor : Editor
{
}
● public override void OnInspectorGUI()
○ Unity 에디터가 인스펙터를 그릴 때 자동으로 호출되는 메서드
○ 이 메서드를 오버라이드하면 기본 인스펙터 대신 우리가 원하는 방식으로 UI를 직접 구성할 수 있다.
○ 호출 타이밍: 사용자가 Unity 에디터에서 해당 컴포넌트를 클릭할 때마다 자동으로 호출된다.
public override void OnInspectorGUI()
{
}
● target
○ Editor 클래스에서 제공하는 기본 속성으로 커스텀 인스펙터가 편집 중인 오브젝트를 가리킨다.
○ 타입은 UnityEngine.Object이기 때문에 직접 사용할 때는 캐스팅(형변환)이 필요하다.
var manager = target as GameManager;
● 인스펙터 화면

■ 커스텀 에디터 예시 3) 스크립터블 오브젝트 생성
● Unity 메뉴의 Window > Item Creator를 클릭하면 팝업창이 열리고 사용자가 직접 입력한 정보로 ScriptableObject 에셋을 생성할 수 있다.
● ShowWindow()
○ Unity 메뉴바에 Window > Item Creator 항목을 추가한다.
○ 클릭 시 ItemCreator 에디터 창이 새로 뜬다.
○ "아이템 생성"이라는 제목의 윈도우가 열린다.
[MenuItem("Window/Item Creator")]
private static void ShowWindow()
{
GetWindow<ItemCreator>("아이템 생성");
}

● OnGUI()
○ Unity 에디터용 UI를 구성하는 함수
○ 사용자가 직접 값을 입력할 수 있도록 각 필드를 GUI로 그려준다.
| 함수 | 역할 |
| TextField | 문자열 입력 필드 |
| EnumPopup | Enum 값을 드롭다운으로 선택 |
| IntField | 정수 값 입력 필드 |
| Toggle | 체크박스 (불리언 토글) |
private void OnGUI()
{
itemName = EditorGUILayout.TextField("아이템 이름", itemName);
itemType = (ItemType)EditorGUILayout.EnumPopup("아이템 종류", itemType);
quantity = EditorGUILayout.IntField("수량", quantity);
isMultiple = EditorGUILayout.Toggle("복수 보유 여부", isMultiple);

● 버튼과 ScirptableObject 생성
○ 버튼을 클릭하면 ItemData 스크립터블 오브젝트 인스턴스를 생성한다.
○ 사용자 입력값으로 필드를 채우고 Asset/ 폴더에 .asset 파일로 저장한다.
| 함수 | 역할 |
| CreateInstance<ItemData>() | ScriptableObject 인스턴스 생성 |
| AssetDatabase.CreateAsset() | 에셋으로 저장 (에디터 전용 함수) |
| AssetDatabase.SaveAssets() | 에셋 저장 트리거 (실제 적용) |
if (GUILayout.Button("아이템 생성"))
{
ItemData data = ScriptableObject.CreateInstance<ItemData>();
data.itemName = itemName;
data.itemType = itemType;
data.quantity = quantity;
data.isMultiple = isMultiple;
AssetDatabase.CreateAsset(data, $"Assets/{itemName}.asset");
AssetDatabase.SaveAssets();
}

'내일 배움 캠프 > 뭐하지' 카테고리의 다른 글
| 게임 데이터 저장과 로드 (0) | 2025.06.04 |
|---|---|
| 스테이지 구조 설계 (0) | 2025.06.04 |
| Cinemachine (0) | 2025.06.04 |
| 렌더링 파이프라인 (10) | 2025.06.01 |
| UI 구성법 (0) | 2025.05.30 |