본문 바로가기

유니티/커스텀 에디터

[ 커스텀 에디터 ] 인스펙터 윈도우

[ 인스펙터 커스텀]

[ Editor의 참조구조 ]

=>에디터 폴더를 만들고 스크립트를 생성한다 . 해당 스크립트는 Editor를 상속받는다 .

 

=>내가 커스텀 하고자 하는 target을 넣어 [CustomEditor(typeof(Cube))] 어트리뷰트를 붙여준다

이제 해당 스크립트는 CudeEditor가 변형을 할 수 있다 .

 

 

[ OnInspectorGUI ]

public override void OnInspectorGUI()를 선언하면 , 기본으로 base.OnInspectorGUI()가 생성된다 .

이는 에디터에서 기본으로 그려주는 요소를 말하며 해당 부분을 주석친다면 인스펙터에는 아무것도 보이지 않는다 .

DrawDefaultInspector()를 하여도 같은 역할을 수행한다 (여러개 해도 똑같이 동작)

 

 

void OnEnable은 큐브의 활성화 혹은  오브젝트의 선택 두가지의 경우에 발동한다 .

target은(Cube를 뜻함) Object 형식이라 형변환이 필요하며 , OnEnable을 통해 cube를 등록 값의 변경이 가능하다 .

 

[ GUI 레이아웃 옵션 ]

이와 같이 IntField의 값을 받아 다시 대입을 해준다면 원래 value가 intfield의 값으로 변함을 볼 수 있다 .

또한 해당 인트필드는 받는 인자에 따라 다양한 변화가 가능하다 . ex) 라벨을 넣어 라벨의 표시

 

=>GUILayout. 으로 형태의 변화 역시 가능하다 .

 

=>width에 다른 설정을 하지 않는다면 인스펙터가 늘어남에 따라 같이 늘어나지만 ,

ExpandWidth(false)로 늘어나지 않게 처리가 가능하다 (Height도 가능)

 

[ Box ]

=>Box를 통해 이미지를 넣어줄수도 있다 .

=>Box는 다음과 같이 넓이의 확장 (기본적으로는 확장 x ) / 최대 최소의 설정 / 고정값의 설정이 가능하다

 

[ 버튼 ]

=>버튼은 넓이의 확장 (기본적으로는 가로가 확장 ) / 최대 최소의 설정 / 고정값의 설정이 가능하다

 

=>버튼은 bool 형식을 반환하기에 if 문과 함께 원하는 액션을 실행한다 

  • 버튼 : 누르면 반응
  • 연속버튼 : 누르는 동안 반응 (마우스 움직여 GUI 가 업데이트 됨에 따라 반응)
  • 드롭다운 버튼 : 옆에 삼각형이 있는 버튼

[ 토글 ]

=>위와 같이 bool 형식을 에디터 내부에 선언하면 체크한 값이 저장이 되지 않는다 (다른 오브젝트를 클릭하고 돌아올때)

OnEnable로 큐브를 설정하고 , 해당  큐브에 toggle값을 선언하여 변경해주어야 저장이 이루어진다

 

=>해당 방식으로 토글 그룹의 설정이 가능하다 .

 

[ 라벨 ]

=>그냥 글자이다 . 

=>Horizontal Field에 들어가게 된다면 , 가로로 정렬되게 다 . PrefixLabel은 접두사 라벨을 의미한다 .

 

[ 텍스트 필드 ]

=>passwordField는 별모양 , DelayedField는 다 채워진후 엔터까지 눌러야 반영이 이루어진다 .

 

=>TextArea는 Enter를 지원하며 , 고정이 없다면 글자수에 맞추어 늘어 날 수 있다 .

 

[ 윈도우 ]

=>새로운 윈도우를 켜준다 . 메뉴아이템을 통해 등록 , Show를 통해 보여준다 .

=>OnGUI를 통해 버튼등의 요소 생성이 가능하다 .

 

[ 슬라이더 ]

=>Slider의 생성이 가능하다 . 이때 , EditorGUILayout은 라벨을 달 수 있다 .

=>또한 int Slider도 있는데 , 이는 정수만 반환한다 .

 

[ 스크롤바 ]

=>스크롤 바는 자신의 크기 / 최소 / 최대로 이루어져 있다 .

[ 스크롤뷰 ]

=>스크롤뷰는 자신의 영역을 넘어가면 스크롤 영역으로 넘긴다 .

scroll은 Vector로 가지고 있다 .

[ 기타입력 ]

 

 public override void OnInspectorGUI()
 {
 //헬프 박스
  EditorGUILayout.HelpBox("HelpBox", MessageType.Info);
  //Knob
  EditorGUILayout.Knob(new Vector2(30f, 30f), 50f, 20f, 80f, "Knob", Color.black, Color.grey, true);

//7자리 가능
  floatField = EditorGUILayout.FloatField("Float", floatField);
  //Enter까지 해야 등록
  delayedFloatField = EditorGUILayout.DelayedFloatField("DelayedFloat", delayedFloatField);
  intField = EditorGUILayout.IntField("Int", intField);
  delayedIntField = EditorGUILayout.DelayedIntField("DelayedInt", delayedIntField);
  //15자리 가능
  doubleField = EditorGUILayout.DoubleField("Double", doubleField);
  delayedDoubleField = EditorGUILayout.DelayedDoubleField("DelayedDouble", delayedDoubleField);
  longField = EditorGUILayout.LongField("Long", longField);

  vector2Field = EditorGUILayout.Vector2Field("Vector2", vector2Field);
  vector2IntField = EditorGUILayout.Vector2IntField("Vector2Int", vector2IntField);
  vector3Field = EditorGUILayout.Vector3Field("Vector3", vector3Field);
  vector3IntField = EditorGUILayout.Vector3IntField("Vector3Int", vector3IntField);
  vector4Field = EditorGUILayout.Vector4Field("Vector4", vector4Field);

  colorField = EditorGUILayout.ColorField("Color", colorField);
  //new를 통한 초기화 필요
  gradientField = EditorGUILayout.GradientField("Gradient", gradientField);
  //new를 통한 초기화 필요
  curveField = EditorGUILayout.CurveField("Curve", curveField);
  //Colider에서 봤을것
  boundsField = EditorGUILayout.BoundsField("Bounds", boundsField);
  boundsIntField = EditorGUILayout.BoundsIntField("BoundsInt", boundsIntField);
  rectField = EditorGUILayout.RectField("Rect", rectField);
  rectIntField = EditorGUILayout.RectIntField("RectInt", rectIntField);
  //enum
  enumFlagsField = (EnumFlags)EditorGUILayout.EnumFlagsField("EnumFlags", enumFlagsField);

//오브젝트 넣을 수 있다 모든 형식 가져옴
  objectField = EditorGUILayout.ObjectField(objectField, typeof(Object), true);
  tagField = EditorGUILayout.TagField("Tag", tagField);
  layerField = EditorGUILayout.LayerField("Layer", layerField);
  maskField = EditorGUILayout.MaskField("Mask", maskField, masks);

[ Serialize 프로퍼티 ]

=>objectField의 경우 모든 형식을 받을 수 있지만 특정 형식을 받고 싶다면

objectField = (Transform) EditorGUILayout.ObjectField(objectField,typeof(Transform),true)

 

=>object 로 가져오는게 아닌 다른 방식도 가능하다 . 해당 타겟의 serializedObject중 tr의 이름을 가진 오브젝트를 찾는다 .

직렬화된 프로퍼티,라벨을 달고 직렬화를 통한 저장은

마지막에 ApplyModifiedProperties를 통해 수정값의 대입이 가능하다.

(tr = Editor .. 이런식이 아닌 바로 대입이 가능하다는 점)

 

[ GUI 스타일 ]

=>EidtorWindow의 Init은 초기화 / OnGUI는 표시되는 부분을 나타낸다 .

=>BeginArea를 통해 얼마나 공백을 둘건지 / 크기를 정해 그안에 요소를  넣을 수 있다 . (인스펙터는 안되고 Area만 가능)

=>또한 별도의 GUIStyle을 넣을수 있다 .우클릭 -> Create -> GUI 스킨을 통해 넣을 수 있는 요소들을 볼 수 있다 .

=>GUI 스타일을 string으로 간단히 표현 가능하다 .

=>FlexibleSpace (유동간격)/  Space  (고정)/ Separator(나누는 역할)로 간격을 띄울 수 있다

 

[ 페이드 그룹 (자식관계) ]

=>Animbool은 애니메이션 가능한 bool 형식이다 (0에서 1을 Lerp 한다)

=>Add Listenr를 달아 바뀔때마다 대기 

=>BeginFade에서 true일동안 해당 블록이 실행되며 EndFadeGroup로 빠져나간다

=>indent Level을 - 하여 한칸 이동한것 (기본값은 0 )

 

[ 폴더형 그룹 ]

=>BeginFoldoutHeaderGroup로 접힌 상태의 폴더를 만들 수 있다 .

=>Selection은 선택하고 있는 것들을 의미한다 . activeObject / Transform / gameObjects (여러개)등을 가져올수있다.

=>큐브가 선택되었다면 해당 값의 변경으로 위치값이 변경된다

=>다수 편집을 하고 싶다면 해당 프로퍼티를 사용한다

해당 방식의 처리로 여러 큐브를 처리 가능하다 . 두가지를 선택하면 인자가 두개 나올 것이다

원래 true로 처리되던것을 false로 바꾼다면 펼쳐진 상태가 기본이 될 것이다 .

 

[ 그리드  ]

=>SelectionGrid로 그리드 형식을 만들 수 있다 (인덱스 / 넣고자하는 것의 배열 / 가로로 최대 2개까지 , 최대 넓이 / 높이)

=>해당 방식으로 체크가 가능하다.만약 특정 구간에서 변화를 체크하고 싶다면 BeginCheck / EndCheck 영역 안에 넣는다

( EndChangeCheck는 bool형식을 반환한다)

 

[ 빌드 타켓 그룹 ]

=>해당 그룹을 통해 빌드 타겟에 따른 처리도 가능하다 

 

[ 툴바 (포커스 해제) ]

=>변경 대상의 int 는 초기화가 되어 있어야 오류가 생기지 않는다

=>TextField에 switch로 각각을 제어한다 .

=>FocusControl을 null로 하는 이유는  필드입력시의 포커스의 해제를 위해서이다 .

 

 

[ 팝업 ]

=>팝업에 따라 해당 인덱스트 text를 띄워준다

=>IntField는 인덱스가 0번일경우 10이 1번일경우 100이 들어간다

=>enum 형식의 popUp역시 가능하다 .

 

[ 재생 / 중지 ]

=>EditorApplication은 에디터 상에서 가능한 행동들이다 . (좌측 상단 Edit에 있는 메뉴들)

 

[ GUI 색상 ]

=>색상을 지정하면 그뒤부터는 그 색상으로 출력된다 .

 

[ 셀 버튼 예제 ]

=>변경 예정인 Cube는 다음과 같이 세팅

=>처음 Enable에서 셀 버튼들을 A로 초기화함

 

[ 텍스트 에셋 예제 ]

=>Object는 어떤것이든 받을수 있어 TextAsset형식으로 변환

=>Area를 만든후 해당 공간에 text를 표시한다

 

[ 애니메이션 커브 예제 ]

=>먼저 큐브는 커브에 따라 움직일것이다 (커브는 초기화가 필요함)

=>Evaluate는 0에서 1까지 움직이기에 다른 수를 곱해 진폭을 크게 할 수 있다

 

[ 스킨 ]

먼저 GUI Skin을 만들어준다 .

=>해당 커스텀 스타일을 4개로 만들고 이미지를 추가해준다 .

=>큐브에는 GUISkin의 레퍼런스를

=>에디터는 해당 큐브를 받아 버튼에 표시한다

=>"MyButton"이라는 스타일을 추가한 것이다

=>이러한 문제가 발생 해결법은 : 

인스펙터를 이러한 방식으로 띄워 만들면서 본다

=>Border / Padding /Margin의 조절로 값을 조절한다

 

 

 

출처

 

Hammer Impact님의 블로그

고라니TV- 커스텀 에디터의 정석

고라니 TV- 응용하여 오목 만들기