본문 바로가기

내일 배움 캠프/뭐하지

커스텀 에디터

[커스텀 에디터]

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