[Unity, C#] EditorWindow - 커스텀 에디터 윈도우

2025. 8. 2. 18:25·Unity,C#/Unity 정보
728x90

■ EditorWindow - 커스텀 윈도우

[Custom Window]

CustomEditor를 통해 기존 컴포넌트의 인스펙터를 꾸민다면, Custom Editor Window는 Unity 상단 메뉴에서 열 수 있는 독립적인 창을 만들 수 있다.

  • 툴 제작, 데이터 편집 등 전용 유틸리티를 만들 때 유용하다.

 

■ EditorWindow 생성

using UnityEditor;
using UnityEngine;

public class CustomWindowTest : EditorWindow
{
    [MenuItem("Tools/Window Test", validate = false, priority = 100)]
    private static void Init()
    {
        var window = GetWindow<CustomWindowTest>();
        window.Show();
    }

    public void OnGUI()
    {
        GUILayout.Label("My First Custom Window");
    }
}

커스텀 에디터 창을 만들기 위해서는 EditorWindow 클래스를 상속받아 스크립트를 작성해야 한다.

  • EditorWindow는 유니티의 에디터 전용 클래스로 사용자가 정의한 창을 에디터 상단 메뉴에서 열 수 있게 해 준다.
  • 이 클래스는 내부적으로 ScriptableObject를 상속받기 때문에, 씬에 존재하지 않고 독립적으로 동작 가능하다.

즉, 게임 오브젝트에 붙어있지 않아도 에디터 창을 띄우는 것이 가능하다.

 

1. [MenuItem] 어트리뷰트

[MenuItem(string itemName, bool isValidateFunction = false, int priority = -1)]

MenuItem의 전체 시그니쳐는 위와 같은데, 이 어트리뷰트가 있어야 에디터 상단 메뉴에 해당 윈도우가 표시된다.

 

파라미터 설명
itemName 메뉴에서 보여질 경로 및 이름 (예시 : “Tools/My Tool”)
      → 상단 메뉴에 Tools 란 항목이 생기고, 그 하위 항목으로 My Tool이 존재한다.
isValidateFunction  메뉴 항목을 특정 조건에서만 사용 가능하도록 설정한다. 이 값이 false면 조건 없이 실행한다.
priority  항목의 우선순위. 낮을수록 먼저 표시된다.

 

 

using System;
using UnityEditor;
using UnityEngine;

public class CustomWindowTest : EditorWindow
{
    [MenuItem("Tools/Window Test", priority = 100)]
    private static void Init()
    {
        var window = GetWindow<CustomWindowTest>();

        window.titleContent = new GUIContent("Test");
    }

		// 실행 가능 여부 판단 함수
    [MenuItem("Tools/Window Test", true)]
    private static bool IsSelectedObject()
    {
		    // 오브젝트가 선택되었을 때만 메뉴 활성화
        return Selection.activeObject != null;
    }

    public void OnGUI()
    {
        GUILayout.Label("My First Custom Window");
    }
}

[MenuItem(…, true)] 어트리뷰트를 사용하면, 해당 함수는 실제 실행이 아닌 “메뉴 조건”을 판단하는 함수가 된다.

  • 따라서 함수가 true를 반환하면 메뉴를 활성화하고 false면 비활성화된다.

 

2. Init(), OnGUI() 함수

[MenuItem("Tools/Window Test", validate = false, priority = 100)]
private static void Init()
{
	var window = GetWindow<CustomWindowTest>();
	
	window.Show();
}

public void OnGUI()
{
	GUILayout.Label("My First Custom Window");
}

Init() 함수는 메뉴 항목을 클릭할 때 한번 호출된다. 이 함수는 창을 열고 초기화하는 역할을 한다.

OnGUI() 함수는 창이 그려질 때마다 렌더링 루프처럼 매 프레임마다 호출되어 UI를 갱신한다.

  • [MenuItem] 어트리뷰트가 붙은 함수는 반드시 static 이어야 한다. 이는 메뉴가 클릭될 때 클래스의 인스턴스를 만들지 않고 직접 호출하기 때문이다.

Init()에서 호출하는 GetWindow<CustomWindowTest>()로 해당 타입의 창을 가져오거나 없으면 새로 생성한다.

  • 내부적으론 Show() 함수를 호출하긴 하지만, 명시적으로 Show함수를 호출하는 것이 안전하다.

 

▼ EditorWindow 주요 기능

[MenuItem("Tools/Window Test", validate = false, priority = 100)]
private static void Init()
{
	var window = GetWindow<CustomWindowTest>();
	
	// 상단 탭의 제목 설정
	window.titleContent = new GUIContent("Test");
	        
	// 윈도우 창의 최소, 최대 크기 설정
	window.minSize = new Vector2(200, 200);
	window.maxSize = new Vector2(1024, 1024);
	        
	// 창의 위치와 크기 설정(x, y, width, height)
	window.position = new Rect(400, 400, 350, 600);
	        
	// 현재 커스텀 윈도우를 선택 상태로 만듦
	window.Focus();
	
	// 값이 true면 마우스가 창 위에서 움직이기만 해도 OnGUI() 호출
	// -> 마우스가 창 위에서 움직일 때 Event.mousePosition을 갱신
	window.wantsMouseMove = false;
	        
	window.Show();
	        
	// 윈도우 창 닫기
	//window.Close();
}

 

■ GUILayout

GUILayout을 사용해 OnGUI() 함수에서 라벨, 버튼, 텍스트 필드, 드롭다운 등의 UI 요소를 쉽게 배치할 수 있다.

  • GUILayout은 자동 레이아웃 시스템을 기반으로 하기 때문에, UI 요소의 위치나 크기가 자동 정렬된다.

아래는 GUILayout에서 자주 사용되는 함수를 정리하였다.

private string _textField = " ";
private string _textArea = " ";

private bool _check;

private float _sliderValue = 0;

// 드롭다운 변수
private int _selectedIndex = 0;
private string[] _options = { "옵션 1", "옵션 2", "옵션 3" };

public void OnGUI()
{
    // 단순한 라벨(읽기 전용 텍스트) 출력
    GUILayout.Label("My First Custom Window");

    // 공백
    GUILayout.Space(10);

    // 라벨을 가운데 정렬
    var label = new GUIStyle(GUI.skin.label)
    {
        alignment = TextAnchor.MiddleCenter,
        fontSize = 20,
        fontStyle = FontStyle.Bold,
        normal = { textColor = Color.red }
    };

    GUILayout.Label("My First Custom Window", label);

    // 입력 필드 (string)
    _textField = GUILayout.TextField(_textField);
    _textArea = GUILayout.TextArea(_textArea); // 여러 줄 입력 필드

    // 체크박스 (bool)
    _check = GUILayout.Toggle(_check, "Check");

    // 버튼 (클릭 시 true 반환)
    GUILayout.Button("Button");

    // 슬라이더 (float, min, max)
    _sliderValue = GUILayout.HorizontalSlider(_sliderValue, 0, 100);

    // 문자열 기반 드롭다운
    _selectedIndex = EditorGUILayout.Popup(_selectedIndex, _options);
}

[Custom Editor Window]

728x90

'Unity,C# > Unity 정보' 카테고리의 다른 글

[Unity, C#] ScriptableObject - 스크립터블 오브젝트  (4) 2025.08.02
[Unity, C#] Editor - 커스텀 인스펙터  (0) 2025.08.02
[C#] LINQ(Language Integrated Query)  (1) 2025.06.27
[Unity] Coroutine(코루틴) 파헤치기  (4) 2025.05.30
'Unity,C#/Unity 정보' 카테고리의 다른 글
  • [Unity, C#] ScriptableObject - 스크립터블 오브젝트
  • [Unity, C#] Editor - 커스텀 인스펙터
  • [C#] LINQ(Language Integrated Query)
  • [Unity] Coroutine(코루틴) 파헤치기
브라더스톤
브라더스톤
유티니, C#과 관련한 여러 정보를 끄적여둔 블로그입니다. Email : dkavmdk98@gmail.com
  • 브라더스톤
    젊은 프로그래머의 슬픔
    브라더스톤
  • 전체
    오늘
    어제
    • 개발 노트 (26)
      • Unity,C# (26)
        • Unity 정보 (5)
        • 알고리즘 (10)
        • 자료구조 (2)
        • 절차적생성(PCG) (9)
      • C++ (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    binary space partitioning
    절차적던전생성
    unity
    CustomWindow
    CustomEditorWindow
    PerlinNoise
    정렬알고리즘
    절차적 던전 생성
    pcg
    이진공간분할법
    Custom Inspector
    C#
    알고리즘
    절차적지형생성
    커스텀 인스펙터
    최단경로찾기
    자료구조
    커스텀 윈도우
    이진공간분할
    BSP
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
브라더스톤
[Unity, C#] EditorWindow - 커스텀 에디터 윈도우
상단으로

티스토리툴바