참고: Unity 에디터를 확장하려면 UI 툴킷을 사용할 것을 강력히 권장하며, 이는 IMGUI보다 더 최신의 유연하고 확장 가능한 솔루션을 제공하기 때문입니다.
애플리케이션 개발 속도를 높이려면 일반적으로 사용하는 컴포넌트에 대한 커스텀 에디터를 생성합니다. 이 페이지에서는 게임 오브젝트가 항상 한 지점을 바라보도록 간단한 스크립트를 생성하는 방법을 설명합니다.
using UnityEngine;
public class LookAtPoint : MonoBehaviour
{
public Vector3 lookAtPoint = Vector3.zero;
void Update()
{
transform.LookAt(lookAtPoint);
}
}
플레이 모드를 시작하면 스크립트를 연결한 게임 오브젝트가 ‘Look At Point’ 프로퍼티로 설정한 좌표를 향하게 됩니다. 에디터 스크립트를 작성할 때 애플리케이션이 실행되지 않는 동안 특정 스크립트가 편집 모드에서 실행되도록 하는 것이 좋습니다. 이렇게 하려면 다음과 같이 ExecuteInEditMode 속성을 클래스에 추가합니다.
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
public Vector3 lookAtPoint = Vector3.zero;
void Update()
{
transform.LookAt(lookAtPoint);
}
}
이제 에디터에서 게임 오브젝트를 움직이거나 인스펙터에서 ‘Look At Point’ 값을 변경하면 게임 오브젝트가 회전을 업데이트하여 월드 공간의 타겟 지점을 바라봅니다.
위의 예시에는 편집 모드 중에 간단한 스크립트가 실행되도록 하는 방법이 나와 있지만, 이 방법만으로는 에디터 툴을 직접 만들 수 없습니다. 다음 단계는 방금 만든 스크립트에 대한 커스텀 에디터 를 만드는 것입니다.
Unity에서 스크립트를 생성하는 경우 기본적으로 MonoBehaviour에서 상속되므로 게임 오브젝트에 연결할 수 있는 컴포넌트입니다. 게임 오브젝트에 컴포넌트를 배치하면 인스펙터에 정수, 플로트, 문자열 등 모든 public 변수를 보고 편집하는 데 사용할 수 있는 기본 인터페이스가 표시됩니다.
LookAtPoint 컴포넌트의 인스펙터는 기본적으로 다음과 같은 모습입니다.
커스텀 에디터는 이 기본 레이아웃을 사용자가 선택하는 에디터 컨트롤로 대체하는 별도의 스크립트입니다.
LookAtPoint 스크립트에 대한 커스텀 에디터를 생성하려면 다음 단계를 따르십시오.
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LookAtPoint))]
[CanEditMultipleObjects]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("lookAtPoint");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(lookAtPoint);
serializedObject.ApplyModifiedProperties();
}
}
이 클래스는 에디터에서 상속받아야 합니다. CustomEditor 속성은 Unity에 에디터 역할을 하는 컴포넌트를 알려 줍니다. CanEditMultipleObjects 속성은 이 에디터를 사용하여 여러 개의 오브젝트를 선택하고 동시에 모두 변경할 수 있다고 Unity에 알립니다.
Unity는 OnInspectorGUI에서 코드를 실행하여 에디터를 인스펙터에 표시합니다. 여기에 GUI 코드를 넣을 수 있으며 OnGUI와 동일한 방식으로 작동하지만 인스펙터 내에서 실행됩니다. 에디터는 검사하는 게임 오브젝트에 액세스하는 데 사용할 수 있는 타겟 프로퍼티를 정의합니다.
LookAtPoint 컴포넌트의 인스펙터는 새 에디터에서 다음과 같은 모습입니다.
이는 기존과 매우 유사한 모습입니다. (단, 에디터 스크립트가 표시할 인스펙터 코드를 추가하지 않으므로 ‘Script’ 필드는 이제 존재하지 않습니다.)
하지만 이제 에디터 스크립트에서 인스펙터가 표시되는 방식을 제어할 수 있으므로 원하는 코드를 사용하여 인스펙터 필드의 레이아웃을 지정하고, 사용자가 값을 조정하고, 그래픽스나 기타 시각적 요소도 표시할 수도 있습니다. 사실 터레인 시스템과 애니메이션 임포트 설정과 같은 복잡한 인스펙터를 비롯하여 Unity 에디터에 표시되는 모든 인스펙터는 커스텀 에디터를 만들 때 액세스할 수 있는 동일한 API를 사용하여 제작되었습니다.
다음은 타겟 포인트가 게임 오브젝트 위에 있는지 아래에 있는지 나타내는 메시지를 표시하기 위해 에디터 스크립트를 확장하는 간단한 예입니다.
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LookAtPoint))]
[CanEditMultipleObjects]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("lookAtPoint");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(lookAtPoint);
serializedObject.ApplyModifiedProperties();
if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Above this object)");
}
if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Below this object)");
}
}
}
LookAtPoint 컴포넌트의 인스펙터는 다음과 같은 모습이며, 메시지는 타겟 지점이 게임 오브젝트의 위 또는 아래에 있는지 알려 줍니다.
모든 IMGUI 커맨드에 완전히 액세스하여 에디터 창 안에서 카메라를 사용하여 씬을 렌더링하는 등 모든 인터페이스 유형을 드로우할 수 있습니다.
OnSceneGUI는 씬 뷰에서 실행된다는 점을 제외하면 OnInspectorGUI와 동일하게 작동합니다. 직접 편집 컨트롤을 만들기 위해 Handles 클래스에 정의된 함수를 사용할 수 있습니다. 해당 클래스의 모든 함수는 3D 씬 뷰에서 작동하도록 설계되었습니다.
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LookAtPoint))]
[CanEditMultipleObjects]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("lookAtPoint");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(lookAtPoint);
if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Above this object)");
}
if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Below this object)");
}
serializedObject.ApplyModifiedProperties();
}
public void OnSceneGUI()
{
var t = (target as LookAtPoint);
EditorGUI.BeginChangeCheck();
Vector3 pos = Handles.PositionHandle(t.lookAtPoint, Quaternion.identity);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Move point");
t.lookAtPoint = pos;
t.Update();
}
}
}
2D GUI 오브젝트(예: GUI 또는 EditorGUI)를 추가하려면 Handles.BeginGUI() 및 Handles.EndGUI() 호출에 래핑해야 합니다.