시작하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class EditorBasic : EditorWindow
{
#if UNITY_EDITOR
[MenuItem("Tools/SubTitle")]
public static void ShowWindow()
{
GetWindow<EditorBasic>("SubTitle");
}
#endif
}
class를 하나 만든 후, 위 형식으로 작성합니다. 위 형식은 Tools 메뉴바에 SubTitle(자신이 원하는 제목)을
눌려 창을 열 수 있도록 합니다.
Label
private void OnGUI()
{
GUILayout.Label("LabelTest", EditorStyles.boldLabel);
}
창에 원하는 GUI를 그리기 위해서는 무조건 OnGUI함수 안에 넣어야 만들 수 있습니다.
위 GUILayout.Label() 함수는 자신이 원하는 글에 라벨을 달 수 있도록 하여 제목이나, 설명글을 달 때 유용하며, EditorStyles을 통해 강조 등 자신이 원하는 스타일로 라벨을 꾸밀 수 있습니다.
Button
private void OnGUI()
{
if(GUILayout.Button("Button"))
{
Debug.Log("Button");
}
}
GUILayout.Button("자신이 원하는 제목") 함수는 말 그대로 버튼을 생성하도록 하며, if문을 통해 클릭하면
원하는 조건이 실행되도록 사용합니다. 버튼은 주로 에디터 창에서 모든 입력을 마치고 버튼을 누르면
맵을 생성 한다 식으로 사용을 합니다.
TextField(string 변수 저장)
string name = string.Empty;
private void OnGUI()
{
name = EditorGUILayout.TextField("InputName:", name);
if(GUILayout.Button("Button"))
{
Debug.Log(name);
}
}
EditorGUILayout.TextField("제목", 저장 할 변수)는 string 변수를 저장해야 하는 경우 사용할 수 있는 함수입니다.
위 코드는 간단히 이름을 입력받아 name에 저장을 한 후 버튼을 누르면 name을 출력하는 코드입니다.
이렇게 저장이 가능한 이유는 OnGUI함수때문입니다.
https://docs.unity3d.com/kr/530/ScriptReference/MonoBehaviour.OnGUI.html
MonoBehaviour-OnGUI() - Unity 스크립팅 API
OnGUI is called for rendering and handling GUI events.
docs.unity3d.com
Unity Documentation에 따르면 프레임 당 여러 번 호출할 수 있기 때문에 textField를 통해 입력을 할 때마다
계속 새로 저장을 하고 있습니다.(이로 인해 최적화에 신경을 써야 합니다.)
IntField, FloatField, Toggle(int, float, bool 변수 저장)
int i;
float f;
bool b;
private void OnGUI()
{
i = EditorGUILayout.IntField("IntTest:", i);
f = EditorGUILayout.FloatField("FloatTest:", f);
b = EditorGUILayout.Toggle("BoolTest:", b);
if (GUILayout.Button("Button"))
{
Debug.Log($"IntInput:{i}");
Debug.Log($"floatInput:{f}");
Debug.Log($"boolInput:{b}");
}
}
string 변수를 저장할 수 있는 TextField() 함수랑 마찬가지로, int 함수를 저장할 수 있는 IntField(), float 변수를
저장 할 수 있는 FloatField(). bool 변수를 저장 할 수 있는 Toggle() 함수가 있습니다.
ObjectField(GameObject 저장)
GameObject obj;
private void OnGUI()
{
obj = EditorGUILayout.ObjectField("Obj:", obj, typeof(GameObject), true) as GameObject;
if (GUILayout.Button("Button"))
{
Debug.Log(obj.name);
}
}
ObjectField()는 오브젝트를 저장할 수 있으며,
ObjectField(string label, Object obj, Type objType, bool allowSceneObjects, params GUILayoutOption[] options)로
구성되어 있다.(실제로는 오버로딩 되어 있어 여러 형식으로 작성할 수 있음)
여기서 label은 제목. obj는 저장할 변수, objtype은 obj의 type, allowSceneObjects는
scene에 있는 오브젝트도 넣을 수 있도록 허락할 것 인가?으로 구성되어 있다.
여기서 ObjectField()의 반환형은 Object이기 때문에 GameObject 변수에 저장을 하기 위해서는
as GameObject 문구를 통해 형변환을 진행해줘야 한다.
GameObject Array
public GameObject[] objs;
SerializedObject so;
private void OnEnable()
{
ScriptableObject target = this;
so = new SerializedObject(target);
}
private void OnGUI()
{
GUILayout.Label("Array:");
so.Update();
SerializedProperty titleProperty = so.FindProperty("objs");
EditorGUILayout.PropertyField(titleProperty, true);
so.ApplyModifiedProperties();
if (GUILayout.Button("Button"))
{
foreach(GameObject obj in objs)
{
Debug.Log(obj.name);
}
}
}
Editor 상에서 Array로 저장하기 위해서는 특수한 방식을 사용해야 한다. GameObject Array를
저장하기 위해 먼저, SerializedObject를 통해 직렬화된 데이터를 저장해야 하며,
target 변수를 자기 자신을 담아, so에 저장하였습니다.
OnGUI에서는 먼저 so.Update()를 통해 직렬화된 객체를 계속 업데이트하고,so.FindProperty() 함수를
통해 objs 변수를 찾았는데, 여기서 주의할 점은 private로 할 시 FindProperty()로찾을 수 없기 때문에
반드시 public으로 공개를 해야지 찾을 수 있습니다.
이렇게 찾은 Property를 SerializedProperty 형식 변수에 담아 PropertyField()를 이용하면 됩니다.
또, 변경사항이 있으면 저장을 하기 위해 so.ApplyModifiedProperties()를 사용하면
GameObject Array 만들기 완성입니다.
EnumPopup(enum 변수 저장)
enum Name
{
None,
Player,
Enemy,
Weapon
}
Name currentName = Name.None;
private void OnGUI()
{
currentName = (Name)EditorGUILayout.EnumPopup("CurrentName:", currentName);
}
EnumPopup("제목", 저장할 enum 변수)는 enum 변수를 저장할 수 있으며, enum 형식을
알려주기 위해 (Name)식으로 형변환을 진행해야 합니다.
현재 저는 졸업작품을 진행하고 있고, 졸업작품에서 몇 개의 툴을 개발하였습니다. 그리고 위 정리한 내용을
아주 유용하게 사용하고 있습니다.ㅎㅎ 다음에는 저가 졸업작품에서 만들고 있는 MapGeneration이나,
ExcelToClass을 한번 소개해보도록 하겠습니다.