Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- asset database_androidlib
- appcenter대체
- python_distutils_module_missing
- jenkins_role관리_플러그인
- dxt
- molocon24후기
- unrealbuildshellscript
- unreal_contentmanagement
- ChatGPT
- molocon24
- python3.12.4
- owasp_depdendency_check_shell
- unrealbuildcommand
- xcode-select_jeknins
- unity package_androidlib
- molocon24내용정리
- xcode_targeting
- unreal_android_빌드옵션
- cookcontent
- unreal_binaryselection
- sourcetree_authencicationfailed
- unreal_flavorselection
- apkipa업로드저장소
- jenkins_계정삭제
- jenkins_owasp
- etc2
- owasp_dependency_check
- Unity2022
- sourcetree_accessdenied
- jenkins_sudo
Archives
- Today
- Total
mystic-agit 개발 블로그
[Unity] EditorWindow 노출 상태에서 .cs 코드 수정 시 UI가 닫히는 이슈 본문
(1) 배경
- Unity에서 여러 프로젝트에 사용할 수 있는 플러그인이나 SDK 등을 사용하다 보면
적용하는 개발자가 편히 사용할 수 있는 설정 GUI를 만드는 경우가 있음 - GUI 구성 시 Unity의 EditorWindow를 사용하는 경우 아래와 같은 형태로 설정 기능을 제공할 수 있음
(2) 문제 발생
- 이슈 시나리오
- 적용중인 개발자가 EditorWindow를 켜놓고 Unity C# 소스코드를 수정
- 소스코드 수정 후 Unity 프로젝트 화면으로 포커스되면 변경된 소스코드를 컴파일 진행
- 이때 열려있던 EditorWindow UI가 강제 종료되는 현상 발생
(3) 원인 분석
- 에러 발생
- 에러 내용 확인
- 코드를 타고 들어가보면 EditorWindow를 다시 그리기 위해 OnGUI() 호출 및 진행 중
OnGUI() 내부에서 UI를 그리기위해 사용되는 객체의 값이 없어서 참조할 수 없어 발생- 예를 들어, 지역변수 private static string labelName 이란 변수가 있었고
EditorWindows 클래스 생성 시 labelName = “abc” 라는 값을 할당 - 처음 EditorWindow 노출 시 라벨에 “abc” 값이 정상 노출되었으나
- 소스코드 갱신으로 컴파일 진행 시 labelName 변수 값이 null 이라 exception 발생
- UI 종료
- 예를 들어, 지역변수 private static string labelName 이란 변수가 있었고
- 코드를 타고 들어가보면 EditorWindow를 다시 그리기 위해 OnGUI() 호출 및 진행 중
public class MyEditorWindow : EditorWindow
{
private static string labelName;
public void init()
{
labelName = "abc";
}
[MenuItem("MyGUI/MyEditorWindow")]
public static void create()
{
var editor = (MyEditorWindow)EditorWindow.GetWindow(typeof(MyEditorWindow), true, "MyEditorWindow");
editor.init();
editor.Show();
}
void OnGUI()
{
EditorGUILayout.LabelField(labelName, ...);
// ...
}
}
(4) 소스코드 컴파일 시 생명주기
- C# 코드를 수정하면 Unity는 컴파일을 진행하고 EditorWindow 상태를 갱신, 이 과정에서 생명주기 이벤트가 순차적으로 진행
(4-a) 컴파일 전
- OnBeforeAssemblyReload()
- [InitializeOnLoad] 속성이 붙은 클래스에서 실행 가능
- Assembly가 다시 로드되기 전에 호출됨
- 사용 예 : 현재 상태 저장, 파일 닫기 등
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class AssemblyReloadHandler
{
static AssemblyReloadHandler()
{
AssemblyReloadEvents.beforeAssemblyReload += BeforeReload;
}
private static void BeforeReload()
{
Debug.Log("Assembly Reload 시작!");
}
}
(4-b) 컴파일
- .cs 파일이 변경되었는지 감지 후 컴파일
- EditorWindow가 해제되거나 기존 상태가 사라질 수 있음
(4-c) 컴파일 완료 후
- OnAfterAssemblyReload()
- Assembly가 다시 로드된 직후 실행됨
- 사용 예 : 데이터 복원, 다시 설정하기 등
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class AssemblyReloadHandler
{
static AssemblyReloadHandler()
{
AssemblyReloadEvents.afterAssemblyReload += AfterReload;
}
private static void AfterReload()
{
Debug.Log("Assembly Reload 완료!");
}
}
- EditorWindow 다시 활성
- EditorWindow 다시 생성
- OnDisable() > OnDestroy() > OnEnable() > OnGUI() 순서로 실행
메서드 | 설명 |
OnDisable() | 기존 EditorWindows가 비활성화될 때 호출 |
OnDestroy() | 기존 EditorWindow가 완전히 삭제될 때 호출 |
OnEnable() | 새 EditorWindow가 생성될 때 호출 |
Awake() | OnEnable() 직후 한번 호출 |
OnGUI() | UI를 다시 그리기 위해 호출 |
(4) 해소 방향
- 앞서 사용한 labelName 변수에 사용되는 값을 어떤 형태로 사용하는가에 따라 해소 방향이 달라질 수 있지만
일반적으로 OnGUI() 과정에서 사용되는 변수나 객체가 null인지 확인하고 그 값을 재할당해주는 방법이 필요- OnGUI() 과정에서 변수가 객체를 null 체크하여 하나하나 값을 불러오는 방법도 있지만
- OnEnable() 메서드에서 OnGUI() 에서 사용되는 변수 및 객체를 일괄적으로 null 체크하여 미리 할당하면
생명주기를 이해하고 있는 개발자간에 유지보수에 도움이 될 수 있음
private void OnEnable()
{
if(labelName == null)
{
// set labelName
labelName = "abc";
}
}
(5) 대응 결과
- EditorWindow를 띄워놓은 상태에서 C# 소스코드가 변경되어 다시 컴파일 되어도 여전히 노출되어있음
- 참고사항
- 현재 EditorWindow에서 체크박스, 텍스트필드 등 어떤 UI에 해당하는 정보를 적용중인 개발자가 변경하였다면
해당 UI의 변경값을 다른 클래스 static 변수가 저장하거나 로컬 데이터로 확보 후 OnEnalbeI()에서 get하여 사용한다면 UI를 다시 그리게 되어도 설정 상태를 손실하지 않을 수 있음
- 현재 EditorWindow에서 체크박스, 텍스트필드 등 어떤 UI에 해당하는 정보를 적용중인 개발자가 변경하였다면
'Unity' 카테고리의 다른 글
Comments