Files
EnglewoodLAB/작업지시서_TopMenu_UIToolkit_마이그레이션.md

25 KiB

TopMenu UIToolkit 마이그레이션 작업지시서

📋 개요

UGUI 기반의 TopMenu 시스템을 UI Toolkit 기반으로 마이그레이션하는 작업입니다. 기존의 MenuItemData 구조와 TopMenuController의 public 메서드를 동일하게 유지하면서, 관심사 분리 원칙을 준수합니다.


🎯 작업 목표

  1. 독립적인 데이터 구조: UTKMenuItemData, UTKTopMenuModel을 UIToolkit 전용으로 별도 구현
  2. Controller 호환성: TopMenuController의 public API 동일하게 구현
  3. UIToolkit 전환: TopMenuView를 UIToolkit 기반으로 재구현
  4. 관심사 분리: Model, View, Controller 명확히 분리
  5. 메모리 관리: IDisposable 구현, 이벤트 정리, 메모리 누수 방지
  6. 성능 최적화: 쿼리 캐싱, GC 최소화, 불필요한 리빌드 방지
  7. 완전한 문서화: 모든 public/protected 멤버에 XML 주석 필수

📁 파일 구조

기존 파일 (참조용)

Assets/Scripts/UVC/UI/Menu/
├── TopMenuModel.cs              # MenuItemData, TopMenuModel (참조만, 재사용 X)
├── TopMenuController.cs         # UGUI Controller (참조)
└── TopMenuView.cs               # UGUI View (참조)

신규 파일 (생성)

Assets/Scripts/UVC/UIToolkit/Menu/
├── UTKMenuItemData.cs           # ⭐ UIToolkit 전용 메뉴 데이터
├── UTKTopMenuModel.cs           # ⭐ UIToolkit 전용 모델
├── UTKTopMenuController.cs      # UIToolkit Controller
├── UTKTopMenuView.cs            # UIToolkit View
└── UTKTopMenuItem.cs            # UIToolkit 메뉴 아이템 컴포넌트

Assets/Resources/UIToolkit/Menu/
├── UTKTopMenu.uxml              # 메인 메뉴 구조
├── UTKTopMenuUss.uss            # 메인 메뉴 스타일
├── UTKMenuItem.uxml             # 메뉴 아이템 구조
├── UTKMenuItemUss.uss           # 메뉴 아이템 스타일
├── UTKSubMenuItem.uxml          # 하위 메뉴 아이템 구조
└── UTKSubMenuItemUss.uss        # 하위 메뉴 아이템 스타일

🔧 구현 상세

1. 데이터 레이어 (신규 구현)

1.1 UTKMenuItemData

파일 경로: Assets/Scripts/UVC/UIToolkit/Menu/UTKMenuItemData.cs

책임:

  • UIToolkit 전용 메뉴 아이템 데이터 구조
  • 메모리 효율적인 데이터 관리
  • IDisposable 구현으로 리소스 정리

필수 구현:

#nullable enable
using System;
using System.Collections.Generic;
using UVC.UI.Commands;

namespace UVC.UIToolkit.Menu
{
    /// <summary>
    /// UIToolkit 메뉴 시스템에서 개별 메뉴 아이템을 나타내는 데이터 클래스입니다.
    /// IDisposable을 구현하여 Command 등의 리소스를 안전하게 정리합니다.
    /// </summary>
    public class UTKMenuItemData : IDisposable
    {
        // --- 속성 ---
        /// <summary>메뉴 아이템의 고유 식별자</summary>
        public string ItemId { get; private set; }

        /// <summary>UI에 표시될 이름 (다국어 키)</summary>
        public string DisplayName { get; private set; }

        /// <summary>실행될 명령</summary>
        public ICommand? Command { get; private set; }

        /// <summary>Command 실행 시 전달될 파라미터</summary>
        public object? CommandParameter { get; set; }

        /// <summary>하위 메뉴 아이템 리스트</summary>
        public List<UTKMenuItemData>? SubMenuItems { get; private set; }

        /// <summary>구분선 여부</summary>
        public bool IsSeparator { get; private set; }

        /// <summary>활성화 상태</summary>
        public bool IsEnabled { get; set; }

        /// <summary>단축키 문자열</summary>
        public string? Shortcut { get; set; }

        /// <summary>메뉴 깊이 (0: 최상위)</summary>
        public int Depth { get; internal set; }

        /// <summary>부모 메뉴 아이템</summary>
        public UTKMenuItemData? Parent { get; internal set; }

        // --- 생성자 ---
        public UTKMenuItemData(
            string itemId,
            string displayName,
            ICommand? command = null,
            object? commandParameter = null,
            List<UTKMenuItemData>? subMenuItems = null,
            bool isSeparator = false,
            bool isEnabled = true,
            string? shortcut = null);

        // --- 메서드 ---
        /// <summary>하위 메뉴 아이템 추가</summary>
        public void AddSubMenuItem(UTKMenuItemData subItem);

        /// <summary>구분선 생성 팩토리 메서드</summary>
        public static UTKMenuItemData CreateSeparator(string? itemId = null);

        /// <summary>특정 ID의 하위 메뉴 존재 여부</summary>
        public bool HasSubMenuItem(string itemId);

        // --- IDisposable ---
        private bool _disposed;

        /// <summary>
        /// 리소스를 정리합니다. Command가 IDisposable인 경우 함께 정리합니다.
        /// </summary>
        public void Dispose();

        protected virtual void Dispose(bool disposing);
    }
}

구현 지침:

  1. 메모리 관리:

    • Dispose()에서 SubMenuItems 재귀적으로 정리
    • CommandIDisposable이면 함께 Dispose()
    • _disposed 플래그로 중복 호출 방지
  2. 성능 최적화:

    • SubMenuItemsList<T> 사용 (배열 변환 지양)
    • 문자열 비교는 StringComparison.Ordinal 사용
    • 깊이/부모 설정은 생성 시 한 번만 수행
  3. 주석:

    • 모든 public/protected 멤버에 XML 주석
    • 예외 상황 명시 (<exception> 태그)
    • 사용 예제 제공 (<example> 태그)

1.2 UTKTopMenuModel

파일 경로: Assets/Scripts/UVC/UIToolkit/Menu/UTKTopMenuModel.cs

책임:

  • 메뉴 아이템 컬렉션 관리
  • 메뉴 아이템 검색/추가/제거
  • IDisposable 구현으로 전체 메뉴 데이터 정리

필수 구현:

#nullable enable
using System;
using System.Collections.Generic;

namespace UVC.UIToolkit.Menu
{
    /// <summary>
    /// UIToolkit 메뉴 시스템의 데이터 모델입니다.
    /// 메뉴 아이템 컬렉션을 관리하고 검색 기능을 제공합니다.
    /// </summary>
    public class UTKTopMenuModel : IDisposable
    {
        /// <summary>최상위 메뉴 아이템 리스트</summary>
        public List<UTKMenuItemData> MenuItems { get; private set; }

        // --- 생성자 ---
        public UTKTopMenuModel();

        // --- 메서드 ---
        /// <summary>메뉴 아이템 추가</summary>
        public void AddMenuItem(UTKMenuItemData item);

        /// <summary>메뉴 아이템 제거</summary>
        public bool RemoveMenuItem(string itemId);

        /// <summary>재귀적으로 메뉴 아이템 검색</summary>
        public UTKMenuItemData? FindMenuItem(string itemId);

        /// <summary>모든 메뉴 아이템 초기화</summary>
        public void ClearMenuItems();

        // --- IDisposable ---
        private bool _disposed;

        /// <summary>
        /// 모든 메뉴 아이템을 정리합니다.
        /// </summary>
        public void Dispose();

        protected virtual void Dispose(bool disposing);
    }
}

구현 지침:

  1. 메모리 관리:

    • Dispose()에서 모든 MenuItems 재귀적으로 정리
    • ClearMenuItems()도 각 아이템 Dispose() 호출
  2. 성능 최적화:

    • FindMenuItem()은 캐싱 고려 (Dictionary<string, UTKMenuItemData>)
    • 검색 빈도가 높으면 인덱스 사용
  3. 주석:

    • 모든 메서드에 XML 주석
    • 시간 복잡도 명시 (<remarks> 태그)


2. Controller 레이어

2.1 UTKTopMenuController

파일 경로: Assets/Scripts/UVC/UIToolkit/Menu/UTKTopMenuController.cs

책임:

  • UTKTopMenuModel과 UTKTopMenuView 중재
  • 메뉴 아이템 추가/제거/업데이트 로직
  • Command 실행 및 Undo/Redo 연동
  • 언어 변경 처리
  • 메모리 관리 (이벤트 구독/해제)

필수 구현 메서드 (TopMenuController와 동일한 public API):

#nullable enable
using UnityEngine;
using UVC.UI.Menu;
using UVC.UI.Commands;
using UVC.Locale;

namespace UVC.UIToolkit.Menu
{
    public class UTKTopMenuController : MonoBehaviour
    {
        // --- 필수 Public 메서드 (TopMenuController와 동일) ---

        /// <summary>메뉴 초기화</summary>
        public virtual void Initialize();

        /// <summary>메뉴 아이템 추가</summary>
        public void AddMenuItem(MenuItemData newItem);

        /// <summary>메뉴 아이템 제거</summary>
        public void RemoveMenuItem(string itemId);

        /// <summary>메뉴 아이템 활성화 상태 변경</summary>
        public virtual void SetMenuItemEnabled(string itemId, bool isEnabled);

        /// <summary>메뉴 아이템 단축키 변경</summary>
        public virtual void SetMenuItemShortcut(string itemId, string shortcut);

        /// <summary>모든 단축키 갱신</summary>
        public virtual void RefreshAllShortcuts();

        // --- Protected 메서드 ---

        protected virtual void Awake();
        protected virtual void Start();
        protected virtual void OnDestroy();
        protected virtual void HandleMenuItemClicked(MenuItemData clickedItemData);
        protected virtual void ExecuteCommand(ICommand command, object? parameter = null);
        protected virtual void HandleLanguageChanged(string newLanguageCode);
        protected MenuItemData? FindMenuItemRecursive(List<MenuItemData> items, string itemId);
    }
}

구현 지침:

  1. 메모리 관리:

    • OnDestroy()에서 model.Dispose() 호출
    • view.OnMenuItemClicked 이벤트 구독 해제
    • LocalizationManager.OnLanguageChanged 구독 해제
  2. 성능 최적화:

    • FindMenuItem()model에 위임 (캐시 활용)
    • 불필요한 View 업데이트 방지 (상태 변경 시에만)
  3. 주석:

    • 모든 public/protected 메서드에 XML 주석
    • Command 실행 흐름 문서화
    • 예외 케이스 명시

3. View 레이어

3.1 UTKTopMenuView

파일 경로: Assets/Scripts/UVC/UIToolkit/Menu/UTKTopMenuView.cs

책임:

  • VisualElement 기반 UI 생성 및 관리
  • 메뉴 아이템 표시/숨김
  • 사용자 입력 이벤트 전달

필수 속성/메서드:

#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UI.Menu;

namespace UVC.UIToolkit.Menu
{
    [UxmlElement]
    public partial class UTKTopMenuView : VisualElement, IDisposable
    {
        // --- Constants ---
        private const string UXML_PATH = "UIToolkit/Menu/UTKTopMenu";
        private const string USS_PATH = "UIToolkit/Menu/UTKTopMenuUss";

        // --- 필수 Public 메서드 (TopMenuView와 동일) ---

        /// <summary>메뉴 아이템 클릭 이벤트</summary>
        public event Action<MenuItemData>? OnMenuItemClicked;

        /// <summary>메뉴 아이템 생성</summary>
        public virtual void CreateMenuItems(List<MenuItemData> items, VisualElement parentContainer, int depth = 0);

        /// <summary>메뉴 아이템 제거</summary>
        public virtual void ClearMenuItems();

        /// <summary>모든 메뉴 텍스트 업데이트 (언어 변경 시)</summary>
        public virtual void UpdateAllMenuTexts(List<MenuItemData> items);

        /// <summary>단축키 텍스트 업데이트</summary>
        public virtual void UpdateShortcutText(string itemId, string shortcut);

        /// <summary>모든 단축키 업데이트</summary>
        public virtual void UpdateAllShortcuts(List<MenuItemData> items);

        /// <summary>메뉴 아이템 GameObject 가져오기</summary>
        public bool TryGetMenuItemElement(string itemId, out VisualElement menuItemElement);

        /// <summary>모든 하위 메뉴 닫기</summary>
        public virtual void CloseAllOpenSubMenus();

        // --- IDisposable ---
        public void Dispose();
    }
}

구현 지침:

  1. Unity 6 방식 사용:

    • [UxmlElement] 어트리뷰트
    • partial class 선언
    • [UxmlAttribute] 케밥 케이스 사용
  2. VisualElement 기반 구현:

    • UXML 로드: Resources.Load<VisualTreeAsset>(UXML_PATH)
    • USS 적용: styleSheets.Add()
    • 쿼리 결과 캐싱: Q<T>() 결과를 필드에 저장
  3. 이벤트 등록/해제:

    • RegisterCallback<ClickEvent>() / UnregisterCallback<ClickEvent>()
    • 주의: RegisterValueChangedCallback 사용 금지
  4. 테마 연동:

    • UTKThemeManager.Instance.ApplyThemeToElement(this)
    • OnThemeChanged 구독
  5. 메모리 관리 :

    • IDisposable 구현 필수
    • OnDetachFromPanelEvent에서 모든 이벤트 해제
    • _menuItemElements Dictionary 정리
    • _subMenuContainers Dictionary 정리
    • 모든 EventCallback 필드 null 처리
  6. 성능 최적화 :

    • Q<T>() 호출은 생성 시 한 번만 (필드 캐싱)
    • 메뉴 아이템 100개 이상에서도 렉 없어야 함
    • GC Alloc 최소화: LINQ 지양, foreach 사용
    • 불필요한 MarkDirtyRepaint() 호출 방지
  7. 주석 작성 :

    • 모든 public/protected 멤버에 XML 주석 필수
    • 복잡한 로직은 인라인 주석으로 설명
    • 예외 상황 명시 (<exception> 태그)
    • 사용 예제 제공 (<example> 태그)

3.2 UTKTopMenuItem

파일 경로: Assets/Scripts/UVC/UIToolkit/Menu/UTKTopMenuItem.cs

책임:

  • 개별 메뉴 아이템 UI 표현
  • 클릭 이벤트 처리
  • 활성화/비활성화 상태 표시

구조:

#nullable enable
using UnityEngine.UIElements;
using UVC.UI.Menu;

namespace UVC.UIToolkit.Menu
{
    [UxmlElement]
    public partial class UTKTopMenuItem : VisualElement, IDisposable
    {
        // --- UXML/USS ---
        private const string UXML_PATH = "UIToolkit/Menu/UTKMenuItem";
        private const string USS_PATH = "UIToolkit/Menu/UTKMenuItemUss";

        // --- UXML Attributes ---
        [UxmlAttribute("item-id")]
        public string ItemId { get; set; } = "";

        [UxmlAttribute("display-name")]
        public string DisplayName { get; set; } = "";

        [UxmlAttribute("is-enabled")]
        public bool IsEnabled { get; set; } = true;

        [UxmlAttribute("shortcut")]
        public string? Shortcut { get; set; }

        // --- Events ---
        public event Action<MenuItemData>? OnClicked;

        // --- Constructor ---
        public UTKTopMenuItem();

        // --- Public Methods ---
        public void SetData(MenuItemData data);
        public void UpdateEnabled(bool enabled);
        public void UpdateShortcut(string shortcut);

        // --- IDisposable ---
        public void Dispose();
    }
}

4. UXML/USS 리소스

4.1 UTKTopMenu.uxml

경로: Assets/Resources/UIToolkit/Menu/UTKTopMenu.uxml

구조:

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:utk="UVC.UIToolkit.Menu">
    <ui:VisualElement name="top-menu-container" class="top-menu">
        <ui:VisualElement name="menu-container" class="top-menu__items" />
        <ui:VisualElement name="blocker" class="top-menu__blocker" style="display: none;" />
    </ui:VisualElement>
</ui:UXML>

4.2 UTKTopMenuUss.uss

경로: Assets/Resources/UIToolkit/Menu/UTKTopMenuUss.uss

스타일 (StyleGuide 참조):

.top-menu {
    flex-direction: row;
    width: 100%;
    height: 40px;
    background-color: var(--color-bg-secondary);
    border-bottom-width: 1px;
    border-bottom-color: var(--color-border);
}

.top-menu__items {
    flex-direction: row;
    flex-grow: 1;
}

.top-menu__blocker {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.001);
}

4.3 UTKMenuItem.uxml

경로: Assets/Resources/UIToolkit/Menu/UTKMenuItem.uxml

구조:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Button name="menu-button" class="menu-item">
        <ui:Label name="label" class="menu-item__label" />
        <ui:VisualElement name="arrow" class="menu-item__arrow" style="display: none;" />
    </ui:Button>
</ui:UXML>

4.4 UTKMenuItemUss.uss

경로: Assets/Resources/UIToolkit/Menu/UTKMenuItemUss.uss

스타일:

.menu-item {
    padding: 0 12px;
    height: 40px;
    border-width: 0;
    background-color: transparent;
    transition: background-color 0.2s;
}

.menu-item:hover {
    background-color: var(--color-bg-hover);
}

.menu-item:active {
    background-color: var(--color-bg-active);
}

.menu-item:disabled {
    opacity: 0.5;
}

.menu-item__label {
    -unity-font-style: normal;
    font-size: 14px;
    color: var(--color-text-primary);
}

.menu-item__arrow {
    width: 8px;
    height: 8px;
    margin-left: 4px;
    background-image: url('project://database/Assets/Resources/UIToolkit/Icons/arrow_down.png');
}

4.5 UTKSubMenuItem.uxml

경로: Assets/Resources/UIToolkit/Menu/UTKSubMenuItem.uxml

구조:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Button name="submenu-button" class="submenu-item">
        <ui:Label name="label" class="submenu-item__label" />
        <ui:Label name="shortcut" class="submenu-item__shortcut" />
        <ui:VisualElement name="arrow" class="submenu-item__arrow" style="display: none;" />
    </ui:Button>
</ui:UXML>

4.6 UTKSubMenuItemUss.uss

경로: Assets/Resources/UIToolkit/Menu/UTKSubMenuItemUss.uss

스타일:

.submenu-item {
    flex-direction: row;
    justify-content: space-between;
    padding: 8px 16px;
    min-width: 200px;
    height: 32px;
    border-width: 0;
    background-color: var(--color-bg-primary);
}

.submenu-item:hover {
    background-color: var(--color-bg-hover);
}

.submenu-item__label {
    font-size: 14px;
    color: var(--color-text-primary);
}

.submenu-item__shortcut {
    font-size: 12px;
    color: var(--color-text-secondary);
    margin-left: 24px;
}

.submenu-item__arrow {
    width: 8px;
    height: 8px;
    margin-left: 8px;
    background-image: url('project://database/Assets/Resources/UIToolkit/Icons/arrow_right.png');
}

🔄 마이그레이션 순서

Phase 1: 기본 구조 구축

  1. 폴더 생성: Assets/Scripts/UVC/UIToolkit/Menu/
  2. 폴더 생성: Assets/Resources/UIToolkit/Menu/
  3. UXML/USS 파일 생성 (6개)
  4. UTKMenuItemData.cs 구현
    • IDisposable 구현
    • XML 주석 작성
  5. UTKTopMenuModel.cs 구현
    • IDisposable 구현
    • 검색 최적화 (Dictionary 캐싱)
    • XML 주석 작성
  6. UTKTopMenuItem.cs 구현
    • IDisposable 구현
    • 이벤트 정리
    • XML 주석 작성
  7. UTKTopMenuView.cs 기본 구조 구현
    • IDisposable 구현
    • 쿼리 캐싱
    • XML 주석 작성
  8. UTKTopMenuController.cs 기본 구조 구현
    • Model/View 참조 정리
    • XML 주석 작성

Phase 2: 핵심 기능 구현

  1. CreateMenuItems() 구현 (재귀적 메뉴 생성)
  2. ToggleSubMenuDisplay() 구현 (하위 메뉴 표시/숨김)
  3. CloseAllOpenSubMenus() 구현
  4. 메뉴 클릭 이벤트 처리
  5. Command 실행 로직

Phase 3: 상태 관리

  1. SetMenuItemEnabled() 구현
  2. SetMenuItemShortcut() 구현
  3. 언어 변경 처리 (HandleLanguageChanged)
  4. 단축키 갱신 (RefreshAllShortcuts)

Phase 4: 테마 및 스타일

  1. UTKThemeManager 연동
  2. StyleGuide 스타일 적용
  3. 라이트/다크 테마 지원

Phase 5: 테스트, 최적화, 문서화

  1. 샘플 씬 생성 및 기능 테스트
  2. 메모리 누수 점검 (필수):
    • Unity Profiler로 메모리 확인
    • 씬 전환 시 메모리 증가 없는지 확인
    • IDisposable 정상 호출 확인
    • 이벤트 구독 해제 확인
  3. 성능 최적화 (필수):
    • Unity Profiler로 CPU/GC 확인
    • 메뉴 아이템 100개 생성 테스트
    • Update 루프에서 GC Alloc 0 확인
    • 쿼리 캐싱 적용 확인
  4. 완전한 문서화 (필수):
    • 모든 public 멤버: XML 주석 작성
    • 모든 protected 멤버: XML 주석 작성
    • 복잡한 로직: 인라인 주석 작성
    • README.md 작성 (사용법, 예제)

⚠️ 주의사항

필수 준수 사항 (위반 시 재작업)

  1. #nullable enable 파일 선두에 필수
  2. Unity 6 방식: [UxmlElement], partial class, [UxmlAttribute] 사용
  3. 이벤트 등록: RegisterCallback<ChangeEvent<T>>() 사용 (RegisterValueChangedCallback 금지)
  4. UXML/USS 네이밍:
    • UXML: UTKTopMenu.uxml
    • USS: UTKTopMenuUss.uss (접미사 Uss 필수)
  5. 케밥 케이스: [UxmlAttribute("item-id")] 소문자 + 하이픈
  6. IDisposable 구현 :
    • 모든 데이터/View 클래스에 필수
    • _disposed 플래그로 중복 호출 방지
    • RegisterCallbackUnregisterCallback 대칭
    • DetachFromPanelEvent에서 정리
    • 하위 객체도 재귀적으로 Dispose

메모리 관리 체크리스트

  • 모든 new EventCallback<T>() 필드화 및 해제
  • 모든 RegisterCallback() 대칭적으로 UnregisterCallback()
  • UTKThemeManager.OnThemeChanged 구독 해제
  • LocalizationManager.OnLanguageChanged 구독 해제
  • Dictionary<> 전체 Clear() 호출
  • 하위 메뉴 재귀적 Dispose
  • Unity Profiler로 메모리 누수 확인

성능 최적화 체크리스트

  • Q<T>() 결과 필드 캐싱 (생성 시 1회만)
  • Update/OnGUI에서 GC Alloc 0
  • LINQ 사용 금지 (foreach 사용)
  • 문자열 연결 시 StringBuilder 사용
  • 불필요한 MarkDirtyRepaint() 제거
  • 메뉴 아이템 100개 생성 시 60fps 유지
  • Unity Profiler로 CPU/GC 확인

문서화 체크리스트

  • 모든 public 멤버: <summary> 태그
  • 모든 protected 멤버: <summary> 태그
  • 모든 매개변수: <param> 태그
  • 모든 반환값: <returns> 태그
  • 예외 발생 가능: <exception> 태그
  • 복잡한 로직: <remarks> 태그 또는 인라인 주석
  • 사용 예제: <example> 태그 (Controller, View)
  • README.md 작성

코드 스타일

  • 한국어 주석 (XML 문서 포함)
  • BEM 네이밍 (CSS 클래스)
  • 파일 경로 참조: file_path:line_number 형식

📝 테스트 체크리스트

기능 테스트

  • 메뉴 아이템 생성/삭제
  • 하위 메뉴 열기/닫기
  • 메뉴 클릭 시 Command 실행
  • 활성화/비활성화 상태 변경
  • 단축키 표시 및 갱신
  • 언어 변경 시 텍스트 업데이트
  • 구분선 표시
  • 외부 클릭 시 하위 메뉴 닫기

성능 테스트

  • 메뉴 아이템 100개 생성 시 렉 없음
  • 메모리 누수 없음 (Profiler 확인)
  • GC Alloc 최소화 (Update 루프에서 0)

호환성 테스트

  • TopMenuController public API 호환성
  • MenuItemData 재사용 가능
  • 기존 프로젝트와 동시 사용 가능 (UGUI/UIToolkit)

📚 참고 자료

CLAUDE.md 관련 섹션

StyleGuide 이미지

  • StyleGuide/style_guide_Menu.png
  • StyleGuide/style_guide_Buttons.png
  • StyleGuide/style_guide_Typography.png

기존 구현 참조

  • Assets/Scripts/UVC/UI/Menu/TopMenuController.cs (로직)
  • Assets/Scripts/UVC/UI/Menu/TopMenuView.cs (View 패턴)
  • Assets/Scripts/UVC/UI/Menu/TopMenuModel.cs (데이터 구조)

🎓 예상 학습 내용

UIToolkit 특화

  1. VisualElement 계층 구조
  2. UXML 템플릿 인스턴스화
  3. USS 선택자 우선순위
  4. 이벤트 버블링/캡처링
  5. schedule.Execute() 활용

패턴 적용

  1. MVVM 패턴 (ViewModel은 Controller가 대신)
  2. 이벤트 기반 통신
  3. 재귀적 UI 생성
  4. 상태 동기화 (Model ↔ View)

완료 조건 (모두 충족 필수)

기능 완료

  • 모든 파일 생성 완료 (UTKMenuItemData, UTKTopMenuModel 포함)
  • TopMenuController public API 동일하게 구현
  • 샘플 씬에서 정상 동작 확인
  • 모든 기능 테스트 통과

메모리 관리 완료

  • 모든 클래스 IDisposable 구현
  • Unity Profiler로 메모리 누수 0 확인
  • 씬 전환 10회 후 메모리 증가 없음
  • 이벤트 구독/해제 대칭 확인

성능 완료

  • Unity Profiler로 GC Alloc 0 확인 (Update 루프)
  • 메뉴 아이템 100개 생성 시 60fps 유지
  • 쿼리 캐싱 적용 확인
  • CPU 프로파일링 이상 없음

문서화 완료

  • 모든 public/protected 멤버 XML 주석 완료
  • 복잡한 로직 인라인 주석 완료
  • README.md 작성 완료
  • 사용 예제 코드 작성 완료

스타일 완료

  • StyleGuide 스타일 적용
  • BEM 네이밍 준수
  • CLAUDE.md 가이드 100% 준수

작성일: 2026-02-13 작성자: Claude Code Assistant 버전: 1.0