Version: Unity 6.0 (6000.0)
언어 : 한국어
C# 스크립트로 커스텀 에디터 창 생성
Create a default Inspector

커스텀 인스펙터 생성

버전: 2022.3+

MonoBehaviours 및 ScriptableObjects를 위한 기본 인스펙터가 있지만, 클래스에 대한 커스텀 인스펙터를 작성하는 것이 좋습니다. 커스텀 인스펙터를 사용하면 다음을 수행할 수 있습니다.

  • 스크립트 프로퍼티를 보다 사용자 친화적으로 나타낼 수 있습니다.
  • 프로퍼티를 정리하고 그룹화할 수 있습니다.
  • 사용자의 선택에 따라__ UI__(사용자 인터페이스) 사용자가 애플리케이션과 상호 작용하도록 해 줍니다. Unity는 현재 3개의 UI 시스템을 지원합니다. 자세한 정보
    See in Glossary
    섹션을 표시하거나 숨길 수 있습니다.
  • 개별 설정 및 프로퍼티의 의미에 관한 추가 정보를 제공할 수 있습니다.

개요 예시

이 예시에서는 MonoBehaviour 클래스에 대한 커스텀 인스펙터를 만듭니다. 이때 C# 스크립트와 UI 빌더를 모두 사용하여 UI를 생성합니다. 커스텀 인스펙터에는 커스텀 프로퍼티 드로어도 있습니다.

커스텀 인스펙터에는 제조사, 제작 연도, 컬러, 타이어 목록과 같은 Car 클래스의 프로퍼티가 표시됩니다. 인스펙터는 PropertyField 컨트롤을 사용하여 Car 클래스의 프로퍼티를 표시하고, 커스텀 프로퍼티 드로어를 사용하여 Tire 클래스의 프로퍼티를 표시합니다.

이 예시에서 만든 완성된 파일은 이 GitHub 저장소에서 찾을 수 있습니다.

선행 조건

이 가이드는 Unity 에디터, UI 툴킷, C# 스크립팅에 익숙한 개발자를 위한 가이드입니다. 시작하기 전에 먼저 다음을 숙지하십시오.

새 MonoBehaviour 생성

커스텀 인스펙터를 생성하려면 먼저 MonoBehaviour에서 상속하는 커스텀 클래스를 정의합니다. 커스텀 클래스는 여러 프로퍼티를 갖는 단순한 car를 나타냅니다.

  1. 템플릿을 사용하여 Unity에서 프로젝트를 생성합니다.

  2. 프로젝트 창에서 모든 파일을 저장할 create-a-custom-inspector라는 폴더를 만듭니다.

  3. 다음 내용을 포함하는 Car.cs라는 이름의 C# 스크립트를 생성합니다.

    using UnityEngine;
    
    public class Car : MonoBehaviour
    {
         public string m_Make = "Toyota";
         public int m_YearBuilt = 1980;
         public Color m_Color = Color.black;
    }
    
  4. 씬에 새 게임 오브젝트를 만들고 Car 스크립트 컴포넌트를 부착합니다.

    Car 오브젝트의 기본 인스펙터
    Car 오브젝트의 기본 인스펙터

커스텀 인스펙터 스크립트 생성

직렬화된 오브젝트에 대한 커스텀 인스펙터를 생성하려면 Editor 기본 클래스에서 파생된 클래스를 생성하여 CustomEditor 속성을 추가해야 합니다. 이 속성을 통해 Unity는 이 커스텀 인스펙터가 나타내는 클래스를 알 수 있습니다.

참고: 커스텀 인스펙터 스크립트는 Editor 폴더 또는 에디터 전용 어셈블리 정의에 있어야 합니다. 이는 커스텀 인스펙터를 생성하는 데 필수적인 UnityEditor 네임스페이스는 해당 영역 외부에서 액세스할 수 없기 때문입니다. 이를 무시하고서 스탠드얼론 빌드를 생성하려고 하면 빌드 프로세스가 실패합니다.

  1. create-a-custom-inspector 폴더 안에 Editor라는 이름의 폴더를 만듭니다.

  2. Editor 폴더 안에 다음 내용이 포함된 Car_Inspector.cs라는 이름의 C# 스크립트를 생성합니다.

    using UnityEditor;
    using UnityEditor.UIElements;
    using UnityEngine.UIElements;
    
    [CustomEditor(typeof(Car))]
    public class Car_Inspector : Editor
    {
    }
    
  3. Car 컴포넌트가 연결된 게임 오브젝트를 선택합니다. 기본 인스펙터가 표시됩니다.

  4. 기본 인스펙터를 대체하려면 Car_Inspector 클래스 내에 다음 코드를 추가하여 CreateInspectorGUI()를 오버라이드하고 UI가 포함된 새 시각적 요소를 반환합니다.

    public override VisualElement CreateInspectorGUI()
    {
         // Create a new VisualElement to be the root of our Inspector UI.
         VisualElement myInspector = new VisualElement();
    
         // Add a simple label.
         myInspector.Add(new Label("This is a custom Inspector"));
    
         // Return the finished Inspector UI.
         return myInspector;
    }
    
  5. Car 컴포넌트가 연결된 게임 오브젝트를 선택합니다. 이제 인스펙터가 기본 인스펙터 대신 레이블 This is a custom Inspector를 표시합니다.

    레이블이 적용된 커스텀 인스펙터
    레이블이 적용된 커스텀 인스펙터

UI 빌더로 커스텀 인스펙터 UI 생성

UI 빌더로 커스텀 인스펙터 UI를 만들고, C# 스크립트를 사용하여 UXML 파일에서 UI를 로드하고 인스턴스화할 수 있습니다.

  1. Window > UI Toolkit > UI Builder를 선택하여 UI 빌더를 엽니다.

  2. File > New를 선택해 새 시각적 트리 에셋을 만듭니다.

    레이블이 적용된 커스텀 인스펙터
    레이블이 적용된 커스텀 인스펙터
  3. UI 빌더에서 에디터 전용 컨트롤을 활성화하려면 계층 구조 뷰에서 <unsaved file>*.uxml를 선택한 다음 Editor Extension Authoring 체크박스를 선택합니다.

    레이블이 적용된 커스텀 인스펙터
    레이블이 적용된 커스텀 인스펙터
  4. 레이블 컨트롤을 Library에서 Hierarchy로 드래그합니다. 그러면 시각적 트리에 레이블 컨트롤이 추가됩니다.

    레이블이 적용된 커스텀 인스펙터
    레이블이 적용된 커스텀 인스펙터
  5. 레이블 컨트롤의 인스펙터 패널에서 레이블 텍스트를 업데이트합니다.

    레이블이 적용된 커스텀 인스펙터
    레이블이 적용된 커스텀 인스펙터
  6. File > Save를 선택하고 시각적 트리를 Assets/create-a-custom-inspector 폴더에 Car_Inspector_UXML.uxml로 저장합니다.

커스텀 인스펙터 내에서 UXML 사용

커스텀 인스펙터 내에서 생성한 UXML 파일을 사용하려면 커스텀 인스펙터에 파일을 할당하여 CreateInspectorGUI() 함수 내에서 로드하고 복제한 후 시각적 트리에 추가합니다. 이때 CloneTree 메서드를 사용하면 됩니다. 어떤 VisualElement든 파라미터로 전달하여 생성된 요소의 부모 역할을 하도록 만들 수 있습니다.

  1. Car_Inspector.cs에서 스크립의 VisualTreeAsset에 대한 public 변수를 생성하고 Car_Inspector_UXML.uxml를 할당합니다.

    public VisualTreeAsset m_InspectorXML;
    
  2. CreateInspectorGUI() 메서드를 다음과 같이 업데이트합니다.

    public override VisualElement CreateInspectorGUI()
    {
         // Create a new VisualElement to be the root of our Inspector UI.
         VisualElement myInspector = new VisualElement();
    
         // Add a simple label.
         myInspector.Add(new Label("This is a custom Inspector"));
    
         // Load the UXML file.
         m_InspectorXML= AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/create-a-custom-inspector/Car_Inspector_UXML.uxml");
    
         // Instantiate the UXML.
         myInspector = m_InspectorXML.Instantiate();
    
         // Return the finished Inspector UI.
         return myInspector;
    }
    
  3. Car 컴포넌트가 연결된 게임 오브젝트를 선택합니다. 그러면 car 컴포넌트를 위한 인스펙터가 레이블 두 개를 표시합니다. 하나는 스크립트를 통해, 다른 하나는 UI 빌더/UXML을 통해 표시됩니다.

    두 개의 레이블이 적용된 커스텀 인스펙터
    두 개의 레이블이 적용된 커스텀 인스펙터

텍스트 필드 바인드

이 커스텀 인스펙터는 Car 클래스의 모든 프로퍼티를 표시합니다. 사용자가 UI 컨트롤을 수정할 경우 Car 클래스의 인스턴스 내 값이 변경됩니다. 이렇게 하려면 시각적 트리에 UI 컨트롤을 추가한 뒤 클래스의 개별 프로퍼티에 바인드합니다.

컨트롤을 직렬화된 프로퍼티에 바인드하려면 해당 프로퍼티를 컨트롤의 binding-path 필드에 할당합니다. 커스텀 인스펙터를 생성하면 바인드가 자동으로 수행됩니다. 시각적 트리가 반환되면 CreateInspectorGUI()가 암시적 바인드를 수행합니다. 자세한 내용은 SerializedObject 데이터 바인드를 참조하십시오.

  1. UI 빌더에서 Car_Inspector_UXML.uxml를 더블 클릭하여 엽니다.

  2. TextField 컨트롤을 추가합니다.

    UI에 텍스트 필드 추가
    UI에 텍스트 필드 추가
  3. TextField의 인스펙터 패널에서 레이블 텍스트를 Make of the car로 설정합니다.

  4. 바인딩 경로를 m_Make로 설정합니다.

    UI 빌더에서 프로퍼티를 컨트롤에 바인딩
    UI 빌더에서 프로퍼티를 컨트롤에 바인딩
  5. Style Class List에 스타일 클래스 unity-base-field__aligned를 추가하여 텍스트 필드가 인스펙터 창의 다른 필드와 정렬되도록 합니다. 자세한 내용은 BaseField를 참조하십시오.

    텍스트 필드에 스타일 클래스 추가
    텍스트 필드에 스타일 클래스 추가
  6. UI 빌더에서 File > Save를 선택합니다.

  7. Car 컴포넌트가 연결된 게임 오브젝트를 선택합니다. 이제 car 컴포넌트의 인스펙터에 Make of the car 텍스트 필드가 표시됩니다. 텍스트 필드는 Car 클래스의 m_Make 프로퍼티에 바인드됩니다.

    텍스트 필드가 표시된 커스텀 인스펙터
    텍스트 필드가 표시된 커스텀 인스펙터

프로퍼티 필드 바인드

Car 클래스의 프로퍼티를 표시하려면 각 필드에 대한 컨트롤을 추가합니다. 컨트롤은 프로퍼티 유형과 일치해야 합니다. 예를 들어 정수 필드나 정수 슬라이더에는 int를 바인드해야 합니다.

프로퍼티 유형에 따라 특정 컨트롤을 추가하는 대신 일반 PropertyField 컨트롤을 사용할 수 있습니다. 이 컨트롤은 대부분의 직렬화된 프로퍼티 유형에서 작동하며 해당 프로퍼티 유형에 대한 기본 인스펙터 UI를 생성합니다.

PropertyField의 장점은 스크립트 내에서 변수 유형을 변경할 때 인스펙터 UI가 자동으로 조정된다는 점입니다. 그러나 시각적 트리가 직렬화된 오브젝트에 바인드될 때까지 컨트롤 유형은 알 수 없으므로, UI 빌더 내에서 컨트롤의 미리보기를 확인할 수는 없습니다.

  1. UI 빌더에서 Car_Inspector_UXML.uxml를 더블 클릭하여 엽니다.

  2. Car 클래스의 m_YearBuilt 프로퍼티에 PropertyField 컨트롤을 추가하고 바인드 경로와 레이블 텍스트를 설정합니다.

    UI 빌더에서 프로퍼티 필드 추가
    UI 빌더에서 프로퍼티 필드 추가
  3. Style Class List에 스타일 클래스 unity-base-field__aligned를 추가합니다.

  4. Car 클래스의 m_Color 프로퍼티에 PropertyField 컨트롤을 추가하고 바인드 경로와 레이블 텍스트를 설정합니다.

  5. Style Class List에 스타일 클래스 unity-base-field__aligned를 추가합니다.

  6. UI 빌더에서 File > Save를 선택합니다.

  7. Car 컴포넌트가 있는 게임 오브젝트를 선택합니다. 이제 car 컴포넌트의 인스펙터에 Year BuiltPaint Color 프로퍼티 필드가 표시됩니다.

    프로퍼티 필드가 있는 커스텀 인스펙터
    프로퍼티 필드가 있는 커스텀 인스펙터

커스텀 프로퍼티 드로어 생성

커스텀 프로퍼티 드로어는 커스텀 직렬화 가능 클래스를 위한 커스텀 인스펙터 UI입니다. 직렬화 가능 클래스가 다른 직렬화된 오브젝트에 속해 있을 경우 커스텀 UI는 해당 프로퍼티를 인스펙터에 표시합니다. UI 툴킷에서 PropertyField 컨트롤은 필드에 대한 커스텀 프로퍼티 드로어가 존재할 경우 이를 표시합니다.

  1. create-a-custom-inspector 폴더에 다음 내용을 포함하는 Tire.cs라는 이름의 새 스크립트를 생성합니다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
        
    [System.Serializable]
    public class Tire
    {
        public float m_AirPressure = 21.5f;
        public int m_ProfileDepth = 4;
    }
        
    
  2. Car.cs에서 리스트 TireCar 클래스에 추가합니다. 완료된 Car.cs 파일은 다음과 같습니다.

    using UnityEngine;
        
    public class Car : MonoBehaviour
    {
        public string m_Make = "Toyota";
        public int m_YearBuilt = 1980;
        public Color m_Color = Color.black;
        
        // This car has four tires.
        public Tire[] m_Tires = new Tire[4];
    }
    
  3. PropertyField 컨트롤은 모든 표준 프로퍼티 유형에서 사용할 수 있으며 커스텀 직렬화 가능 클래스와 배열도 지원합니다. 자동차 타이어의 프로퍼티를 표시하려면 Car_Inspector_UXML.uxmlPropertyField를 하나 더 추가하고 m_Tires에 바인드하십시오. 완료된 Car_Inspector_UXML.uxml 파일은 다음과 같습니다.

    <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True">
        <ui:TextField picking-mode="Ignore" label="Make of the car" value="filler text" binding-path="m_Make" class="unity-base-field__aligned" />
        <uie:PropertyField binding-path="m_YearBuilt" label="Year Built" class="unity-base-field__aligned" />
        <uie:PropertyField binding-path="m_Color" label="Paint Color" class="unity-base-field__aligned" />
        <uie:PropertyField label="Tires" binding-path="m_Tires" class="unity-base-field__aligned" />
    </ui:UXML>
        
    
  4. Car 컴포넌트가 있는 게임 오브젝트를 선택합니다. 이제 car 컴포넌트의 인스펙터에 Tires 프로퍼티 필드가 표시됩니다.

    PropertyField 컨트롤을 사용하여 배열 표시
    PropertyField 컨트롤을 사용하여 배열 표시

커스텀 프로퍼티 드로어에 대한 UI 생성

커스텀 프로퍼티 드로어를 생성하여 리스트에 있는 개별 Tire 요소의 모양을 커스터마이즈할 수 있습니다. 커스텀 프로퍼티 드로어는 Editor 기본 클래스에서 파생되는 대신 PropertyDrawer 클래스에서 파생됩니다.

C# 스크립트 또는 UXML을 사용하여 프로퍼티에 대한 UI를 생성할 수 있습니다. 이 예시는 C# 스크립트를 사용하여 커스텀 UI를 만드는 법을 보여줍니다. 커스텀 프로퍼티에 대한 UI를 생성하려면 CreatePropertyGUI 메서드를 오버라이드하십시오.

  1. Editor 폴더에 다음 내용을 포함하는 Tire_PropertyDrawer.cs라는 이름의 새 스크립트를 생성합니다.

    using UnityEditor;
    using UnityEditor.UIElements;
    using UnityEngine.UIElements;
        
    [CustomPropertyDrawer(typeof(Tire))]
    public class Tire_PropertyDrawer : PropertyDrawer
    {
        public override VisualElement CreatePropertyGUI(SerializedProperty property)
        {
            // Create drawer UI using C#.
            var popup = new UnityEngine.UIElements.PopupWindow();
            popup.text = "Tire Details";
            popup.Add(new PropertyField(property.FindPropertyRelative("m_AirPressure"), "Air Pressure (psi)"));
            popup.Add(new PropertyField(property.FindPropertyRelative("m_ProfileDepth"), "Profile Depth (mm)"));
        
            // Return the finished UI.
            return popup;
        }
    }
    
  2. Car 컴포넌트가 있는 게임 오브젝트를 선택합니다. 이제 car 컴포넌트의 인스펙터에 Tires 프로퍼티 필드가 커스텀 프로퍼티 드로어와 함께 표시됩니다.

    커스텀 프로퍼티 드로어를 사용하는 인스펙터
    커스텀 프로퍼티 드로어를 사용하는 인스펙터

기본 인스펙터 생성

기본 인스펙터 UI를 표시할 Foldout 컨트롤을 생성합니다. 기본 인스펙터 UI를 Foldout에 연결하려면 그에 대한 레퍼런스를 얻어야 합니다. UQuery를 사용하여 인스펙터의 시각적 트리에서 Foldout의 시각적 요소를 가져올 수 있으며, InspectorElement 클래스의 FillDefaultInspector 메서드를 사용하여 기본 인스펙터 UI를 Foldout 컨트롤에 연결할 수 있습니다.

  1. Car_Inspector_UXML.uxml 파일을 더블 클릭하여 UI 빌더에서 엽니다.

  2. UI에 Foldout 컨트롤을 추가한 뒤 이름을 Default_Inspector로 지정하고 레이블 텍스트를 다음과 같이 설정합니다.

    기본 인스펙터를 위한 폴드아웃
    기본 인스펙터를 위한 폴드아웃
  3. Car_Inspector.cs 파일에서 CreateInspectorGUI() 메서드를 업데이트하여 Default_Inspector 폴드아웃에 대한 레퍼런스를 가져오고 기본 인스펙터 UI를 연결합니다. 완료된 Car_Inspector.cs 파일은 다음과 같습니다.

    using UnityEditor;
    using UnityEditor.UIElements;
    using UnityEngine.UIElements;
        
    [CustomEditor(typeof(Car))]
    public class Car_Inspector : Editor
    {
        public VisualTreeAsset m_InspectorUXML;
        public override VisualElement CreateInspectorGUI()
        {
             // Create a new VisualElement to be the root of our Inspector UI.
            VisualElement myInspector = new VisualElement();
        
            // Add a simple label.
            myInspector.Add(new Label("This is a custom Inspector"));
        
            // Load the UXML file and clone its tree into the inspector.
            if (m_InspectorUXML != null)
            {
                VisualElement uxmlContent = m_InspectorUXML.CloneTree();
                myInspector.Add(uxmlContent);
            }
        
            // Return the finished Inspector UI.
            return myInspector;
        }
    }
        
    
  4. Car 컴포넌트가 있는 게임 오브젝트를 선택합니다. 이제 car 컴포넌트의 인스펙터에 기본 인스펙터 UI가 들어 있는 Default Inspector 폴드아웃이 표시됩니다.

    기본 인스펙터가 있는 인스펙터
    기본 인스펙터가 있는 인스펙터

추가 리소스

C# 스크립트로 커스텀 에디터 창 생성
Create a default Inspector