글 작성자: Doublsb

지난번에는 Emotion 클래스를 완성했고, dictionary를 우회하여 배열 두 개로 입력할 수 있도록 해 보았다.

하지만 이대로는 배열 두 개일 뿐이고, dictionary처럼 보이지는 않는다.

 

그래서 Custom Editor를 활용하여 값이 보이는 방법을 다듬기로 했었다.

 

 

시작도 하기 전에 문제가 생겼는데,

만들었던 Emotion 클래스는 Monobehavior의 상속을 받지 않으므로, Custom Editor로 구현할 수 없었다.

 

이를 지원하기 위해 Monobehavior의 상속을 받지 않은 클래스도 보여지는 방식을 편집할 수 있도록,

유니티가 Property Drawer를 지원한다는 것을 알게 되었다.

유니티 Property Drawer 문서 보러가기

 


#1 PropertyDrawer 상속 받기

 

Custom Editor와 같이, Property Drawer를 사용하기 위해서는 비슷한 방식으로 상속을 받으면 된다.

- using UnityEditor로 네임스페이스를 사용한다.

- 어떤 클래스의 PropertyDrawer로 만들 것인지 알리기 위해 [CustomPropertyDrawer(typeof(클래스명))]을 써 넣는다.

- OnGUI를 override한다.

 


#2 시작

 

PropertyDrawer에서는 BeginProperty와 EndProperty를 처음과 끝 부분에 호출해주어야 한다고 공식 문서가 그랬다.

...그래서 일단은 이렇게 두고, 어떤 모양으로 Emotion Dictionary를 표현해야 할지 생각해 보았다.


#3 기획

기획이 나와야 그대로 코드를 짤 수 있을 것이다. 내가 원하는 건 다음과 같은 모양이다.

 

Size를 입력하지 않아도 Add를 통해 추가할 수 있도록 만들고 싶었기 때문에, 리스트 맨 아래쪽에 TextField와 Add 버튼을 구상했다.

리스트에는 Emotion의 이름과 Sprite를 매핑할 수 있는 칸이 뜨고, - 버튼을 눌러 삭제할 수 있게 구상하였다.

 


#4 구현 상황

 

생각보다 PropertyDrawer의 문서가 방대하다 보니, 여러 곳에서 정보를 얻느라 시간이 오래 걸렸다.

1일 1커밋을 하기 위해서는 적어도 12시가 넘어가면 안 됐기 때문에 (...) 오늘의 수확을 정리하려 한다.

정보를 찾느라, _emotion의 value만 출력해본 사진이다. 아무튼 값을 연동하는 방법은 알아냈으므로, 이를 응용하면 될 것이다.

 

 

- Serialize Property 값 가져오기

 

OnGUI에서 파라미터로 넘겨받은 property에서, property.FindPropertyRelative("값 이름")을 사용하면 된다.

나는 이를 통해 Emotion 클래스에서, _emotion이라는 string[] 값을 가져왔다.

 

 

 

- 가져온 값 보이기

 

EditorGUI.PropertyField(Rect, SerializedProperty)를 호출하면 된다. 이렇게 하면 값에 맞는 형식으로 출력할 수 있게 된다.

 

여기서 Rect는 말 그대로, 해당 값이 보여질 창의 크기 및 위치를 의미한다.

나는 array를 보여주기 위해 다음과 같이 작성하였다.

Rect NewRect = new Rect(position.position, new Vector2(position.width, 16));

for (int i = 0; i < _emotion.arraySize; i++)
{
	NewRect = new Rect(NewRect.position + new Vector2(0, 20), NewRect.size);
	EditorGUI.PropertyField(NewRect, _emotion.GetArrayElementAtIndex(i));
}

라벨 한 줄의 크기는 16 정도가 적당한 듯 하다.

 

 

 

- PropertyDrawer 크기 늘리기

 

표시한 사이즈의 길이를 늘리기 위해서는, GetPropertyHeight를 오버라이드하면 된다.

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
	return property.isExpanded ? 16 * 10 : 16;
}

 

아무튼, 내일 마저 이어서 해 봐야겠다.

 

해당 커밋 보러가기

반응형