먼저 컴포넌트의 Inspector창을 수정하는 것부터 알아보자.
Inspector창을 수정하는 데에는 제약이 있다.
자세한건 후술하겠다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Human : MonoBehaviour
{
public string name;
public int age;
public float height;
}
우리는 이 스크립트의 에디터 클래스를 만들어서 공부를 할것이다.
HumanEditor로 Script를 하나 더 만들고 다음과 같이 코드를 쓰자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR // 1)
using UnityEditor;
[CustomEditor(typeof(Human))] // 2)
public class HumanEditor : Editor // 3)
{
public override void OnInspectorGUI() // 4)
{
base.OnInspectorGUI();
}
}
#endif
1) 전처리 지시문이다. 에디터 관련 코드가 들어있으면 빌드할때 오류를 내기 때문에, 전처리 지시문에서 UNITY_EDITOR 조건을 통해 유니티 에디터에서만 컴파일 되게 해야한다.
2) UnityEditor에 포함되어있는 Attribute이다. Inspector창을 커스텀할 클래스를 typeof를 이용하여 전달하면 된다.
3) Editor클래스를 상속하는 HumanEditor 클래스이다. 밑의 override 함수 OnInspectorGUI함수를 사용하기 위해서 필수적이다.
4) OnInspectorGUI함수다, base는 Inspector에서 기본적으로 보여주는 화면.
스크립트의 Instance는 serializedObject 변수로 가져올 수 있다.
또한 변수를 가져오기 위해서는 FindProperty함수와 변수의 이름을 이용해서 가져와야 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(Human))]
public class HumanEditor : Editor
{
public override void OnInspectorGUI()
{
var name = serializedObject.FindProperty("name");
var age = serializedObject.FindProperty("age");
var height = serializedObject.FindProperty("height");
}
}
#endif
이렇게 가져온 변수들은 SerializedProperty클래스이며, 내부 속성들을 이용해 변수의 값을 가져올 수 있다.
예를들어 human에서의 name의 값은 string이므로 name.stringValue를 통하여 수정을 해야한다. 맞지 않는 타입의 값을 수정하면 오류를 출력한다.
우리는 변수들의 이름을 한번 한국어로 표시되게 해보자
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(Human))]
public class HumanEditor : Editor
{
public override void OnInspectorGUI()
{
var name = serializedObject.FindProperty("name");
var age = serializedObject.FindProperty("age");
var height = serializedObject.FindProperty("height");
// 문자열 필드를 표시
name.stringValue = EditorGUILayout.TextField("이름", name.stringValue);
// 정수 필드를 표시
age.intValue = EditorGUILayout.IntField("나이", age.intValue);
// 실수 필드를 표시
height.floatValue = EditorGUILayout.FloatField("키", height.floatValue);
}
}
#endif
아마도 이상태로 값을 조정할려하면 값이 변하지 않을것이다.
Inspetor에서 변한 값은 바로 적용되고, 저장되는것이 아닌, 변경점을 저장하는 함수인 serializedObject.ApplyModifiedProperties를 호출해야한다. (Dirty Flag)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(Human))]
public class HumanEditor : Editor
{
public override void OnInspectorGUI()
{
var name = serializedObject.FindProperty("name");
var age = serializedObject.FindProperty("age");
var height = serializedObject.FindProperty("height");
name.stringValue = EditorGUILayout.TextField("이름", name.stringValue);
age.intValue = EditorGUILayout.IntField("나이", age.intValue);
height.floatValue = EditorGUILayout.FloatField("키", height.floatValue);
serializedObject.ApplyModifiedProperties();
}
}
#endif