본문 바로가기

Unity/작업방식

Unity: Workflow. 유니티 에디터 종료 확인 문구

유니티 에디터를 의도치 않게 꺼버릴 때가 있습니다. 다른 브라우저를 끄거나, 클릭 미스로 꺼버리는 경우가 있죠. 프로젝트가 작다면 금방 다시 키는게 큰 문제가 되지 않지만, 로딩 시간이 오래 걸리는 경우 의도치 않은 에디터 종료가 부담스러울 수 있습니다.

 

간단하게 에디터 콜백을 추가해 다이얼로그 박스를 한 번 더 띄우도록 구현해보겠습니다.

 

 

나타나는 다이얼로그

 

using UnityEditor;

	public class EditorQuitHandler
	{
		[InitializeOnLoadMethod]
		private static void Register()
		{
			EditorApplication.wantsToQuit += OnWantsToQuit;
		}

		private static bool OnWantsToQuit()
		{
			return EditorUtility.DisplayDialog("Unity Editor", 
				"정말 에디터를 종료하시겠습니까?", "종료", "아니오");
		}
	}

 

InitializeOnLoadMethod 어트리뷰트가 붙은 정적 함수는 도메인이 로드 될 때 호출됩니다. 일반적으로 스크립트를 컴파일 하고 에디터를 선택하면 잠시 멈추는 동안, 플레이모드 버튼을 누르면 로딩되는 시간동안 호출된다고 생각하시면 됩니다.

 

도메인이 로드 될 때는 static 필드나 클래스들이 파괴되기 때문에, 이전 도메인에서 등록해두었던 콜백이 파괴됩니다. 그래서 위 코드는 매번 도메인이 로드 될 때 콜백을 등록하는 코드로 이해하실 수 있습니다.

 

위 코드는 빌드에서 제외되는 코드이므로 Editor 폴더에 넣거나 (어셈블리 정의를 사용하지 않는 경우), Editor를 위한 어셈블리에 넣어주시면 됩니다.

 

응용해서 몇 분 작업했는지 등을 확인할 수도 있습니다. 저는 뉴턴소프트의 json 라이브러리를 사용했지만 시간을 기록하는 수단은 마음에 드시는 아무 방법이나 사용하시면 됩니다.

 

	public class EditorQuitHandler
	{
		[Serializable]
		private class TimeCache
		{
			public DateTime time;
		}
		
		[InitializeOnLoadMethod]
		private static void Register()
		{
			EditorApplication.wantsToQuit += OnWantsToQuit;
			
			if (EditorApplication.timeSinceStartup < 10)
			{
				string path = Application.dataPath.Replace("/Assets", "/Temp/StartupTime.json");
				var cache = new TimeCache()
				{
					time = DateTime.UtcNow,
				};
				
				File.WriteAllText(path, JsonConvert.SerializeObject(cache));
			}
		}

		private static bool OnWantsToQuit()
		{
			StringBuilder message = new StringBuilder(256);

			message.Append("정말 에디터를 종료하시겠습니까?");
			
			string path = Application.dataPath.Replace("/Assets", "/Temp/StartupTime.json");
			if (new FileInfo(path).Exists)
			{
				var startup = JsonConvert.DeserializeObject<TimeCache>(File.ReadAllText(path));
				TimeSpan gap = DateTime.UtcNow - startup.time;

				message.Append("\n");

				if (gap.Hours > 0)
				{
					message.Append($"{gap.Hours}시간");
				}

				if (gap.Minutes > 0)
				{
					message.Append($"{gap.Minutes}분");
				}
			}
			
			return EditorUtility.DisplayDialog("Unity Editor", 
				message.ToString(), "종료", "아니오");
		}
	}