유니티 개발을 생업으로 삼는 사람이라면 들어봤을 Odin Inspector.
게임 개발을 깔끔하고 쾌적하게 해준다는 장점이 있다.
하지만 55달러, 할인하면 약 27달러의 가격이다.
기능 전부 다 쓸것도 아니고, 공부도 할겸 어트리뷰트를 직접 만들어보기로 했다.
---
오랜만에 리팩토링이랑 최적화하고 기능좀 추가하려고 켰는데 아주 가관이다.
프로퍼티의 수가 너무많아 Header 만으로는 정리가 되지 않는다.
Inspector 창에서 Foldout을 할 수 있으면 좋을것 같다.
우선 Attribute를 만들자.
이렇게 PropertyAttribute 를 상속받고 이름의 끝에 Attribute를 붙이면 완성이다.
이런식으로 자동완성 창에서 볼 수 있게 된다.
이제 Attribute의 기능을 만들자
기능을 만드는 방식은 크게 두 가지이다.
1. PropertyDrawer 를 상속받아서 각 Property 를 OnGUI 단위로 그리기
2. Editor를 상속받아서 특정 스크립트의 InspectorGUI 그리기
1. PropertyDrawer 로 그리기 (비추천)
FoldoutGroup과 Foldable 어트리뷰트를 통해 다같이 Fold로 묶는게 목적이다.
PropertyAttribute는 특정 어트리뷰트가 붙어있을때에만 실행되므로 영향을 끼칠 변수에 전부 붙여야한다.
CustomPropertyDrawer -> 이 어트리뷰트 보이면 아래 override 함수들이 실행됨
foldoutStates 는 각 헤더의 fold가 열렸는지 상태 확인하려고, headerDict 는 override하는 두 함수간의 실행주기가 달라서 property-header 를 Entry로 저장해둠.
특히, 변수하나 그릴때마다 새로운 클래스가 만들어지기 때문에 상태를 저장하기 위해서는 static으로 둬야함.
에디터를 다루면 자주봤을 GetPropertyHeight 함수임.
여기서 리턴하는 값으로 해당 프로퍼티가 사용할 수 있는 높이가 정해짐
-- 요약
헤더 fold가 열려있는 경우 :
FoldoutGroup -> singleLineHeight + PropertyHeight
Foldable -> PropertyHeight
헤더 fold가 닫혀있는 경우 :
FoldoutGroup -> singleLineHeight (Foldout 그려야됨)
Foldable -> 0
똑같은 논리로 OnGUI 함수를 만들고 필요한 곳에 필요한걸 그리면됨
대충 오류도 고치고 하면 완성이 되지만, 이 방법은 큰 문제가 있음
GetPropertyHeight에서 0을 반환하고 아무것도 안그려도 자동으로 프로퍼티 간에 패딩을 넣어준다는 거임;
이 값은 프로퍼티당 2px 로 EditorGUIUtility 의 standardVerticalSpacing 값과 유사함
당연하게도 이렇게 중요한건 읽기전용이므로 더이상 할 수 있는게 없음.
GetProperty로 -2를 반환하건 OnGUI에서 2px 위쪽에 뭘 그리건 해결되지 않음
2. Editor 로 그리기
이건 그냥 스크립트의 InspectorGUI를 처음부터 하나씩 그리는거임
여기서는 Monobehaviour 의 Inspector를 그려야함.
우선 Attribute를 이런식으로 바꿈
CustomEditor를 선언하고 뒤에 true를 붙여줘야 Monobehaviour 상속받은 애들까지 처리해줌
foldoutStates 는 위에거랑 하는일이 똑같고, propertyDataList는 각 프로퍼티의 정보와 FoldoutGroup 정보를 페어로 담아둠
에디터와 스크립트의 상태를 동기화시키기 위해서,
맨처음에 Update로 스크립트의 값들을 받아오고, 다 처리를 한 후에 Apply~ 로 스크립트에 반영함.
잘 모르겠으면 int main(void) 처럼 그냥 적으면됨.
Properties 를 보고 propertyDataList에 채워넣는 함수임.
단순히 prop.NextVisible 로 순회하면서 채우면 될 줄 알았지만, 아쉽게도 Vector3 의 NextVisible은 Vector3.x, Vector3.y ... 이렇게 멤버를 다 순회함
밑쪽의 부분이 그거 예외처리 하드코딩 해둔거고, 나중에 고치긴 해야될듯
Property를 그리는 부분임.
data.Attribute는 FoldoutGroupAttribute 말하는거라, 그거 없으면 그냥 그리고, 있으면 그룹 단위로 그려줌.
이렇게 하고 실행해보면
잘 되는걸 확인할 수 있음.
뭔가 Script 에 Readonly 가 사라진것같긴한데, 별로 상관없을듯
이제 저 밋밋한 Foldout 을 꾸미기만 하면됨
굿
오딘 말고 이것보다 성능은 낮아도 좋은 에셋들 있던데. 난 그거씀
@ㅅ@ 전 v인스펙터 쓸게용
감사합니다. 비슷한 기능 전부 구현해서 금방 올리겠습니다.