왜 저번처럼 CustomWindow를 사용하지 않고 CustomEditor를 사용했나면 GameManager의 기능은 모든 씬 전체에 영향을 주는 것이 아니고 존재하지도 않기 때문에 이 스크립트가 존재할 때만 적용할 생각이기 때문이다.
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(GameManager))]
public class GameHelperEditor : Editor
{
GameManager gm;
private void OnEnable()
{
gm = (GameManager)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.LabelField("Helper", new GUIStyle(EditorStyles.label)
{
alignment = TextAnchor.MiddleCenter,
});
if (GUILayout.Button("AddScore100"))
{
gm.AddScore(100);
}
if (GUILayout.Button("IncreaseLife"))
{
gm.IncreaseLife();
}
if (GUILayout.Button("DecreaseLife"))
{
gm.DecreaseLife();
}
if (GUILayout.Button("GameClear"))
{
gm.Clear();
}
if (GUILayout.Button("GameOver"))
{
gm.Over();
}
}
}
오늘의 회고
오늘은 다른 팀원의 작업을 도와주면서 버그를 잡는 작업을 많이 했던 것 같다. 내일 제출이기 때문에 우리가 목표로 한 작업들까지는 버그가 없이 잘 동작해야 한다고 생각을 해서 이 부분에 집중을 했다. 그리고 CustomEditor를 사용하면서 버그가 검출이 됐는데 아 이래서 처음부터 테스트용 목적으로 에디터를 만들어 놓는구나 하는 생각이 들었다.
내일은 이번에 진행한 프로젝트의 제출일이다. 내일은 readme 작성과 영상을 찍고 제출하는 것을 할 생각이다. 내일도 파이팅!
커스텀 에디터는 MonoBehaviour를 가진 스크립트를 타겟으로 하여 OnInspectorGUI 메서드를 사용하여 인스펙터에 커스텀으로 버튼, 레이블 등을 추가할 수 있는 기능이다.
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.TerrainTools;
using UnityEngine;
[CustomEditor(typeof(GameHelper))]
public class GameEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("게임 시작"))
{
Debug.Log("게임 시작");
}
}
}
EditorWindow
에디터 윈도우는 따로 윈도우 창(탭)을 만들어 오브젝트에 종속되지 않고도(타겟을 정할 순 있음) 에디터를 커스텀 할 수 있는 기능이다.
이번 경우엔 CustomEditor보다 EditorWindow를 사용했다.
처음에 CustomEditor로 구현하다가 타겟을 정해야되는 부분에서 고민을 좀 했는데
씬을 이동하는 것을 구현하는 점에서 굳이 파괴될 수 있는 씬에 있는 오브젝트를 대상으로 타겟을 설정하는 것이 별로라고 생각했다.
씬 이동에서의 문제점 1
여기서 한 가지 문제가 있었는데 에디터 상에서 씬을 이동할 때는 EditorSceneManager.OpenScene()을 이용해야 한다는 점이었다. 플레이 모드에서 씬을 이동할 때는 SceneManager.LoadScene()을 사용해야하기 때문에 Applicaition.IsPlaying으로 분기 처리를 해주었다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
[Serializable]
public class SceneWindow : EditorWindow
{
private const string PATH = "Assets/Scenes/";
private SceneType _sceneType;
[MenuItem("Helper/SceneWindow")]
static void Init()
{
EditorWindow window = GetWindow(typeof(SceneWindow));
window.maximized = true;
window.Show();
}
private void OnGUI()
{
_sceneType = (SceneType)EditorGUILayout.EnumPopup(_sceneType, new GUIStyle(EditorStyles.popup)
{
alignment = TextAnchor.MiddleCenter,
});
if (GUILayout.Button("이동"))
{
if (Application.isPlaying)
{
SceneManager.LoadScene($"{PATH}{_sceneType}.unity");
}
else
{
EditorSceneManager.OpenScene($"{PATH}{_sceneType}.unity");
}
}
if (!Application.isPlaying && GUI.changed)
{
EditorUtility.SetDirty(this);
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
}
}
}
씬 이동에서의 문제점 2
갑자기 씬이 안 넘어가지는 버그가 생겼다.
디버그를 해봤더니 버튼까지는 잘 동작되는 것을 확인할 수 있었다.
그래서 뭐가 문제인지 봤더니 저번에 공부했던 Time.deltaTime과 Time.unscaledDeltaTime과 관련한 문제였다.
GameManager에서 게임이 끝나면 TimeScale을 0으로 만드는데 여기서 버그가 발생한 것이었다.
Time.deltaTime을 Time.unscaledDeltatime으로 바꾸고 해결하였다.