오늘의 학습 키워드
EditorWindow, CustomEditor
공부한 내용
CustomEditor
커스텀 에디터는 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으로 바꾸고 해결하였다.
https://jcdevelop98.tistory.com/292
IEnumerator FadeIn()
{
float alpha = 1.0f;
while (alpha > 0)
{
alpha -= Time.deltaTime * fadeSpeed;
fadeImage.color = new Color(0, 0, 0, alpha);
yield return null;
}
OnLoadSceneByIndex(SceneManager.GetActiveScene().buildIndex);
}
IEnumerator FadeOut(int sceneIndex)
{
if (isFadingOut)
yield break;
isFadingOut = true;
float alpha = 0.0f;
while (alpha < 1)
{
alpha += Time.deltaTime * fadeSpeed;
fadeImage.color = new Color(0, 0, 0, alpha);
yield return null;
}
SceneManager.LoadScene(sceneIndex);
StartCoroutine(FadeIn());
}
IEnumerator FadeIn()
{
float alpha = 1.0f;
while (alpha > 0)
{
alpha -= Time.unscaledDeltaTime * fadeSpeed;
fadeImage.color = new Color(0, 0, 0, alpha);
yield return null;
}
OnLoadSceneByIndex(SceneManager.GetActiveScene().buildIndex);
}
IEnumerator FadeOut(int sceneIndex)
{
if (isFadingOut)
yield break;
isFadingOut = true;
float alpha = 0.0f;
while (alpha < 1)
{
alpha += Time.unscaledDeltaTime * fadeSpeed;
fadeImage.color = new Color(0, 0, 0, alpha);
yield return null;
}
SceneManager.LoadScene(sceneIndex);
StartCoroutine(FadeIn());
}
오늘의 회고
오늘까지 기본 게임 로직을 거의 완성했다. 우여곡절이 많았지만 팀원 분들이 열심히 해주셔서 대충 거의 다 온 것 같다. 남은 건 추가 구현들과 버그 잡기만 남았다.
내일은 아이템 구현과 최고점수 갱신 연결을 하려고 한다. 목요일까지 열심히 하자. 내일도 파이팅!
'스파르타 Unity 1기' 카테고리의 다른 글
내일배움캠프 28일차 TIL - Static Batching, Dynamic Batching, Gpu Instancing (0) | 2023.09.14 |
---|---|
내일배움캠프 27일차 TIL - CustomEditor (0) | 2023.09.13 |
내일배움캠프 25일차 TIL - 사운드 매니저 (0) | 2023.09.11 |
내일배움캠프 5주차 WIL - Input System (0) | 2023.09.11 |
내일배움캠프 24일차 TIL - Visual Studio 자동완성, Awake vs OnEnable (0) | 2023.09.08 |