2014년 5월 28일 수요일

[Unity] 사용자 정의 컴포넌트 에디터를 구현하기.

1. 에디터 인터페이스 제공을 위한 에디터 클래스 스크립트 작성. (ex. SimpleEditor.cs)

2. 커스텀 에디터 구현을 위해 프로젝트 뷰의 Scripts 폴더 내에 Editor 폴더를 생성 후 작성한 에디터 클래스이름 뒤에 Inspector를 붙여서 클래스 스크립트 생성. (ex. SimpleEditorInspector.cs)
*커스텀 에디터를 작성할때는 프로젝트 뷰에 반드시 Editor 폴더를 생성한다. Editor폴더는 에디팅에만 사용될 뿐 최종빌드에는 포함되지 않는다. 따라서 에디터 클래스만 보관한다. 

3. UnityEditor에 대한 접근과 Editor 상속, 커스텀 에디터를 구현할 OnInspectorGUI() 함수 재정의. (매소드 오버라이딩)

[CustomEditor(typeof(SimpleEditor))]

public class SimpleEditorInspector : Editor 
{
       public override void OnInspectorGUI()  //Editor상속, 커스텀에디터 구현 함수 재 정의.  
      {
     SimpleEditor simpleEditor = target as SimpleEditor;
       }
}

4. Bool 형태의 커스텀 에디터는 인스펙터 창에 토글버튼을 구현.

simpleEditor.showButton = EditorGUILayout.Toggle("Show Button", simpleEditor.showButton);  
if (simpleEditor.showButton) 
{
GUILayout.Button ("Show Button");
}

*인스펙터 창에서 체크 설정시 버튼 노출 / 체크 해제시 노출 되지 않음.

5. int, float, string 형태의 커스텀 에디터는 인스펙터 창에 각각 정수형, 실수형, 문자열 필드 생성.

simpleEditor.age = EditorGUILayout.IntField("Age", simpleEditor.age);
simpleEditor.height = EditorGUILayout.FloatField("Heghit", simpleEditor.height);
simpleEditor.myName = EditorGUILayout.TextField("Name", simpleEditor.myName);

6. enum 형태의 커스텀 에디터는 인스펙터 창에 드롭다운 팝업메뉴 생성.

simpleEditor.bloodType = (BLOODTYPE)EditorGUILayout.EnumPopup("Blood Type", simpleEditor.bloodType);

*EditorGUILayout.EnumPopup 앞에 형 변환을 해줘야 한다.

7. Object 형태의 자료형들에 대한 커스텀에디터는 인스펙터 창에 해당 Object의 링크 필드를 생성.

simpleEditor.cameraObject = (GameObject)EditorGUILayout.ObjectField("Camera Object", simpleEditor.cameraObject, typeof(GameObject), true);

*EditorGUILayout.ObjectField 앞에 형 변환을 해줘야 한다.

simpleEditor.myTransform = (Transform)EditorGUILayout.ObjectField("My Transformt", simpleEditor.myTransform, typeof(Transform), true);

8. List 형태의 커스텀 에디터는 인스펙터 창에 지정된 수만큼의 데이터 필드를 생성한다. 
*List 형태의 커스텀 에디터 사용시 인터페이스 에디터 클래스의 네임스페이스에 Generic을 추가한다.

for (int i = 0; i < simpleEditor.myList.Count; i++) 
{
string fieldName = "My List" + i;
simpleEditor.myList[i] = EditorGUILayout.IntField(fieldName, simpleEditor.myList[i]);
}

9. 배열형태의 커스텀 에디터 역시 인스펙터 창에 지정된 수만큼의 데이터 필드를 생성한다.

for (int i = 0; i < simpleEditor.arrayFloat.Length; i++) 
{
string fieldName = "array flaot" + i;
simpleEditor.arrayFloat[i] = EditorGUILayout.FloatField(fieldName, simpleEditor.arrayFloat[i]);
}

for (int i = 0; i < simpleEditor.arrayVector.Length; i++) 
{
string fieldName = "array vector" + i;
simpleEditor.arrayVector[i] = EditorGUILayout.Vector3Field(fieldName, simpleEditor.arrayVector[i]);
}

10. 인스펙터 창에 컴포넌트 구분선 구현 함수.

void DrawSeperator(Color color)
{
EditorGUILayout.Space();

Texture2D tex = new Texture2D(1, 1);  //1 by 1 Pixel
GUI.color = color;
float y = GUILayoutUtility.GetLastRect().yMax;  //마지막 구성요소의 사각형
GUI.DrawTexture(new Rect(0.0f, y, Screen.width, 1.0f), tex);  //인스펙터창의 가로사이즈 만큼 라인을 그린다.
tex.hideFlags = HideFlags.DontSave;  //매번 정보가 변경될 때 마다 인스펙터 창이 새로 랜더링 되므로 저장을 방지하여 메모리 누수를 방지한다.
GUI.color = Color.white;  //기본 색상 화이트로 초기화 해준다. 

EditorGUILayout.Space();
}

11. 컴포넌트의 접기와 펼치기 기능 구현.

bool형태로 해당 컴포넌트의 데이터 선언과 초기화를 한다.

bool myListFold = false;

if (myListFold = EditorGUILayout.Foldout(myListFold, "My List"))  //인자의 순서에 주의.
{

}

12. 컴포넌트의 필드값의 상태를 색상으로 확인하는 기능 구현.

GUI.backgroundColor = (simpleEditor.cameraObject !=null) ? Color.blue:Color.red;  //3항 연산자로 간략화 사용.
simpleEditor.cameraObject = (GameObject)EditorGUILayout.ObjectField("Camera Object", simpleEditor.cameraObject, typeof(GameObject), true);

*GUI.backgroundColor : 유니티 프로 라이센스에서 사용, 프리 라이센스에서는 GUI.color 사용.



댓글 없음:

댓글 쓰기