팀스파르타 내일배움캠프

Unity UI Panel 개발 - 문제해결 과정

creator2041 2025. 6. 12. 15:57

1. RectTransform null 참조 오류

문제

[SettingsPanel] *** 애니메이션 실패 *** RectTransform이 null입니다!
  • 비활성화된 GameObject에서 Start() 메서드가 호출되지 않음
  • RectTransform 초기화 전에 애니메이션 시도

시도

  • Start()에서 RectTransform 초기화
  • OpenSettings()에서 null 체크 추가
  • 안전장치 코드 작성

해결

  • Start() → Awake() 변경 (Awake는 비활성화 상태에서도 호출됨)
  • Lazy Initialization 추가 (OpenSettings에서 null 체크 후 즉시 초기화)
// ❌ 비활성화된 UI에서는 Start() 호출 안됨
void Start() { /* 초기화 코드 */ }

// ✅ Awake()는 항상 호출됨
void Awake() { /* 컴포넌트 초기화 */ }

2. 컴파일 오류 - 제거된 속성 참조

문제

error CS1061: 'SettingsPanel' does not contain a definition for 'IsAnimating'
error CS1061: 'SettingsPanel' does not contain a definition for 'slideAnimationDuration'
  • SettingsPanel에서 애니메이션 코드 제거
  • MainMenuPanel에서 아직 제거된 속성들을 참조

시도

  • SettingsPanel 코드 수정
  • 애니메이션 관련 변수 제거
  • 단순화 시도

해결

  • MainMenuPanel에서 IsAnimating 체크 완전 제거
  • slideAnimationDuration 참조 삭제
  • 불필요한 애니메이션 대기 코루틴 삭제
// ❌ 제거된 속성 참조
if (!settingsPanel.IsAnimating) { }

// ✅ 단순한 상태 체크
if (!settingsPanel.IsOpen) { }

3. 복잡한 애니메이션 시스템의 불안정성

문제

  • 슬라이드 애니메이션 구현이 너무 복잡
  • RectTransform 위치 계산 오류
  • 비활성화된 UI에서 애니메이션 처리 문제

시도

  • AnimationCurve 사용한 부드러운 애니메이션
  • 코루틴으로 슬라이드 인/아웃 구현
  • 복잡한 위치 계산 로직

해결

  • 애니메이션 완전 제거
  • **SetActive(true/false)**로 단순화
  • 즉시 표시/숨김 방식 채택
// ❌ 복잡한 애니메이션
StartCoroutine(SlideIn());

// ✅ 단순한 활성화
gameObject.SetActive(true);

4. UI 복원 문제 - 콜백 시스템 누락

문제

  • SettingsPanel에서 직접 CloseSettings() 호출
  • MainMenuPanel에 패널이 닫혔다는 알림 없음
  • 메인 UI 복원 로직 실행되지 않음

시도

  • CloseSettings()에서 직접 메인 UI 복원 시도
  • 다양한 UI 복원 방법 테스트
  • 이벤트 시스템 고려

해결

  • 콜백 시스템 구현
  • SettingsPanel → MainMenuPanel 통신
  • FindObjectOfType<MainMenuPanel>() 사용
// ❌ 단방향 통신
gameObject.SetActive(false); // 그냥 닫기

// ✅ 양방향 통신
MainMenuPanel mainMenu = FindObjectOfType<MainMenuPanel>();
mainMenu.OnSettingsPanelClosed(); // 닫혔다고 알림

5. Unity 생명주기 혼동

문제

  • Start()가 비활성화된 GameObject에서 호출되지 않음
  • UI 초기화 타이밍 문제
  • 생명주기 메서드 사용법 혼동

시도

  • Start()에서 모든 초기화 시도
  • OnEnable() 사용 고려
  • 다양한 생명주기 메서드 테스트

해결

  • 적절한 생명주기 메서드 선택
// 1. Awake() - 항상 호출 (비활성화 상태에서도)
void Awake() { /* 컴포넌트 참조 초기화 */ }

// 2. Start() - 활성화된 상태에서만 호출 
void Start() { /* 설정값 초기화 */ }

// 3. OnEnable() - 활성화될 때마다 호출
void OnEnable() { /* UI 갱신 */ }

핵심 교훈

1. 단순함이 최고

복잡한 애니메이션 → 여러 오류 발생
단순한 SetActive → 안정적 동작

2. Unity 생명주기 이해 필수

  • UI 컴포넌트 초기화: Awake() 사용
  • 설정값 로드: Start() 사용
  • UI 상태 갱신: OnEnable() 사용

3. 디버깅 로그의 중요성

Debug.Log($"[ClassName] *** 중요한 동작 *** 상세정보");
Debug.Log($"변수명: {변수값}");

4. 컴포넌트 간 통신 설계

  • 단방향 통신보다는 콜백 시스템 구현
  • FindObjectOfType 활용한 동적 참조

최종 결과

안정적이고 예측 가능한 UI 시스템 완성

  1. 설정 버튼 → 메인 UI 숨김 → 설정패널 활성화
  2. 설정 변경 → 실시간 적용 → 자동 저장
  3. 패널 닫기 → 메인패널에 알림 → UI 복원

"가장 단순하고 안정적인 해결책이 최고의 해결책이다"