📕학습 개요

커스텀 에디터란? -말 그대로 유니티 인스펙터 창을 커스텀하는 기능이며, UI를 더 직관적으로 구성 가능하고, 개발 중 반복 작업을 줄이고 생산성을 향상시키는 효과를 가진다. 또한, 디자이너와 팀원이 쉽게 데이터를 편집 가능하다는 장점이 있으며 툴 제작이나 에디터 확장에 유용하게 활용된다.


📖학습 내용


커스텀 에디터 제작에 사용되는 클래스

  • EditorGUILayout
  • EditorGUI
  • GUILayout
  • GUI

주요 UI 항목

항목 설명
LabelField 텍스트 라벨 표시
TextField 한 줄 문자열 입력
TextArea 여러 줄 문자열 입력
IntField 정수 입력
FloatField 실수 입력
Space 여백 삽입
HelpBox 설명이나 경고 메시지 박스
Button 버튼 생성 및 클릭 이벤트 처리
HorizontalScope / VerticalScope UI 배치 정렬 용도
Toggle 체크박스 (bool 값)
Slider 슬라이더 UI (min~max 값 사이 float)
Vector2Field / Vector3Field 벡터 값 입력
ObjectField 오브젝트(에셋, GameObject 등) 참조 설정
EnumPopup Enum 타입 선택 드롭다운
Popup 문자열 배열 기반 드롭다운
ColorField 색상 선택
CurveField 애니메이션 커브 입력
RectField Rect 영역 입력
BoundsField Bounds 영역 입력
Foldout 접이식 섹션 UI

실제 활용 예시

1. 플레이어 스탯 에디터

public class PlayerStats : MonoBehaviour
{
    public int hp = 100;
    public int mp = 100;

    public bool isGodMode = false;

    public void InitPlayerData()
    {
        hp = 100;
        mp = 100;
        isGodMode = false;
    }
}
[CustomEditor(typeof(PlayerStats))]
public class PlayerStatsEditor : Editor
{
    //인스펙터에 GUI를 커스탐하기 위한 기본 메소드
    public override void OnInspectorGUI()
    {
        var playerStats = (PlayerStats)target;

        EditorGUILayout.Space();
        EditorGUILayout.HelpBox("주인공 캐릭터 스탯", MessageType.Info);
        EditorGUILayout.Space();

        //입력 필드
        playerStats.hp = EditorGUILayout.IntSlider("생명력", playerStats.hp, 0, 100);
        playerStats.mp = EditorGUILayout.IntSlider("마나", playerStats.mp, 0, 100);

        EditorGUILayout.BeginHorizontal();

        //무적 모드 토글 버튼

        if(GUILayout.Button(playerStats.isGodMode ? "일반 모드로 전환" : "무적 모드로 전환"))
        {
            playerStats.isGodMode = !playerStats.isGodMode;
        }

        //플레이어 데이터 초기화
        if(GUILayout.Button("데이터 초기화"))
        {
            playerStats.InitPlayerData();
        }

        EditorGUILayout.EndHorizontal();
    }
}

image_1

저번 팀 프로젝트를 할 때 내가 플레이어 조작 부분을 맡았는데, 팀원들로부터 플레이어의 기본 스탯을 어떻게 조절하는지에 대한 질문을 많이 받았다. 이런 식으로 직관적인 메뉴를 만들어서 보여준다면, 협업 과정에서 굉장히 편리할 수 있겠다는 생각이 들었다.


2. 게임매니저 에디터

[CustomEditor(typeof(GameManager))]
public class GameManagerEditor :Editor
{
    public override void OnInspectorGUI()
    {
        var manager = target as GameManager;

        EditorGUILayout.ObjectField("GameManager", MonoScript.FromMonoBehaviour(manager), typeof(MonoScript), false);

        EditorGUILayout.BeginHorizontal();

        if(GUILayout.Button("적 생성"))
        {
            manager.SpawnEnemy();
        }

        if(GUILayout.Button("적 삭제"))
        {
            var enemies = GameObject.FindGameObjectsWithTag("Enemy");

            foreach(var enemy in enemies)
            {
                DestroyImmediate(enemy);
            }
        }

        EditorGUILayout.EndHorizontal();
    }
}

image_2

게임을 테스트 하는 과정에서 쉽게 테스트 하기 위해 일부러 특정 수치를 크게 높여놓고는 했는데, 이런 식으로 테스트 전용 버튼을 만들어놓으면 게임 테스트 과정에서 굉장히 편리할 것 같다.


3. 아이템 데이터 생성기

public class ItemCreator : EditorWindow
{
    private string itemName = "New Item";
    private ItemType itemType = ItemType.Weapon;
    private int quantity = 1;
    private bool isMultiple = false;

    [MenuItem("Window/Item Creator")]
    private static void ShowWindow()
    {
        GetWindow<ItemCreator>("아이템 생성기");
    }

    private void OnGUI()
    {
        itemName = EditorGUILayout.TextField("아이템 명", itemName);
        itemType = (ItemType)EditorGUILayout.EnumPopup("아이템 종류", itemType);
        quantity = EditorGUILayout.IntField("수량", quantity);
        isMultiple = EditorGUILayout.Toggle("복수 보유", isMultiple);

        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();
        }
    }
}

image_3

이런 식으로 데이터 생성기를 따로 만들어놓는다면 유니티를 잘 다룰 줄 모르는 사람들도 쉽게 데이터를 생성할 수 있을 것 같다. 유니티를 다룰 줄 아는 사람 입장에서도 윈도우 창에서 에디터에 접근하여 생성하는 식이 조금이라도 편리할 것이라 생각한다.


🏁오늘 배운 내용 정리

유니티의 커스텀 메뉴를 사용하면 게임 내 데이터에 더욱 쉽고 편리하게 접근 할 수 있다. 사실 코드를 직접 짠 개발자 입장에서는 인스펙터 창에 뜨는 정보가 뭘 의미하는지 쉽게 알 수 있겠지만, 다른 개발자들 입장에서는 그렇지 않다. 하지만 커스템 메뉴를 통해 정보를 직관적으로 전달한다면 협업 과정에서의 효율이 많이 증진될 것 같다. 세상에 존재하는 모든 것은 일단 보기 좋아서 나쁠 건 없으니까…

댓글남기기