Unity 프로젝트를 여러 개 진행하다 보면 매번 같은 코드를 복붙하게 됩니다.
"이거 한 번 정리하면 두고두고 쓸 텐데…" 라는 생각으로 Common 라이브러리를 만들었습니다.
🎯 목표
- 프로젝트 간 재사용 가능한 공용 코드 정리
- GC 최적화, 편의성 극대화
- 한글 주석으로 팀원도 쉽게 이해 가능
- 계층화된 UI 시스템으로 팝업/HUD/화면 전환 일관성 확보
📦 구현한 유틸리티 (18개)
1순위 — 거의 모든 프로젝트에서 필수
| 클래스 | 한 줄 설명 |
|---|---|
| ObjectPool | 프리팹 오브젝트 풀링. Get() / Release() / PreWarm() |
| EventBus | 전역 이벤트 시스템. Subscribe<T>() / Publish<T>() |
| WaitCache | new WaitForSeconds() GC 제거. WaitCache.Get(0.5f) |
| PlayerPrefsHelper | bool, enum, DateTime, JSON 직렬화 지원 |
EventBus 사용 예:
// 이벤트 정의
public struct PlayerDiedEvent { public int score; }
// 구독
EventBus.Subscribe<PlayerDiedEvent>(e => ShowGameOver(e.score));
// 발행
EventBus.Publish(new PlayerDiedEvent { score = 1500 });
WaitCache 사용 예:
// Before ❌ — 매번 GC 발생
yield return new WaitForSeconds(0.5f);
// After ✅ — 캐시된 인스턴스 재사용
yield return WaitCache.Get(0.5f);
2순위 — 모바일 필수 + 코드 간결화
| 클래스 | 한 줄 설명 |
|---|---|
| SafeAreaHelper | 노치/펀치홀 대응 자동 레이아웃 |
| CoroutineExtensions | this.Delay(1f, callback) 한 줄 딜레이 |
| CollectionExtensions | list.GetRandom(), Shuffle() (GC-free) |
| StringExtensions | 숫자 콤마, 시간 포맷, K/M 축약 |
| ColorExtensions | color.WithAlpha(0.5f), Hex 변환 |
CoroutineExtensions 사용 예:
// Before ❌
StartCoroutine(DelayCoroutine());
IEnumerator DelayCoroutine() {
yield return new WaitForSeconds(1f);
DoSomething();
}
// After ✅
this.Delay(1f, () => DoSomething());
3순위 — 게임 로직 지원
| 클래스 | 한 줄 설명 |
|---|---|
| SimpleStateMachine | Enum 기반 FSM. Enter/Update/Exit 콜백 |
| AudioHelper | BGM/SFX 싱글톤. 볼륨, 페이드, 자동 저장 |
| ScreenTransition | 씬 전환 페이드. FadeOutIn(loadScene) |
| DebugLogger | 카테고리 로깅. 릴리스 빌드 자동 제거 |
4순위 — 생산성 부스터
| 클래스 | 한 줄 설명 |
|---|---|
| Timer | 카운트다운/업, 일시정지, 반복, 콜백 |
| VectorExtensions | pos.WithY(0), Flat(), RandomInCircle() |
| MathUtils | Chance(30) 확률, Remap(), Damp() |
| UIButtonExtensions | SetOnClick(), 연타 방지 쿨다운 |
| SceneExtensions | 비활성 포함 씬 내 컴포넌트 검색 |
🏗️ UI 프레임워크
기존 BaseUI는 Show/Hide만 있는 껍데기였습니다. 이걸 레이어 기반 UI 관리 시스템으로 완전히 재설계했습니다.
아키텍처
UIHelper (static) ← 호출 코드에서 사용
↓
UIManager (싱글톤)
├ 레이어별 Canvas 자동 생성
│ HUD(0) → Screen(100) → Popup(200) → Overlay(300)
├ UI 인스턴스 캐시 (Dictionary<Type, BaseView>)
├ 팝업 스택 (List<BasePopup>)
└ Back Key 라우팅 (팝업 → View 순)
↓
기본 클래스
├ BaseView — 전체 화면 (CanvasGroup 페이드 내장)
├ BasePopup — 모달 (딤드 배경, 닫기 가드)
├ BaseHUD — 항상 표시 (HP, 점수)
└ BaseWidget — 재사용 위젯 (스크롤 아이템)
사용 예
// 화면 전환 — Resources/UI/ 에서 자동 로드
UIHelper.Show<MainMenuView>();
// 팝업 + 닫기 콜백
UIHelper.ShowPopup<SettingsPopup>(onClose: () => SaveSettings());
// HUD 갱신
UIHelper.Get<ScoreHUD>()?.Refresh(currentScore);
// 씬 전환 시 전체 정리
UIHelper.ClearAll();
BasePopup 핵심 기능
public class ConfirmPopup : BasePopup
{
[SerializeField] private Button confirmButton;
protected override void OnInit()
{
base.OnInit();
confirmButton.SetOnClick(OnConfirm);
}
// 닫기 전 확인 (false 반환 시 닫기 차단)
protected override bool OnCloseRequested()
{
return hasUnsavedChanges == false;
}
}
- ✅ 딤드 배경 자동 생성/제거
- ✅ 딤드 클릭으로 닫기 (옵션)
- ✅ Back Key 처리
- ✅ 닫기 가드 (
OnCloseRequested) - ✅ UIManager 팝업 스택 연동
📁 최종 폴더 구조
Assets/Scripts/Common/
├── App/ AppManagerBase, SceneBase, Appdelegate, ISceneController
├── Patterns/ MonoSingleton, ObjectPool, EventBus, SimpleStateMachine
├── Extensions/ Object, GameObject, Transform, UI, Coroutine,
│ Collection, String, Color, Vector, UIButton, Scene
├── Utils/ WaitCache, PlayerPrefsHelper, AudioHelper,
│ DebugLogger, Timer, MathUtils
└── UI/ UIManager, UIHelper, UILayer, BaseView, BasePopup,
BaseHUD, BaseWidget, SafeAreaHelper, ScreenTransition
💡 설계 원칙
- IsNull() / IsNotNull() — Unity fake null 대응 전용 확장 메서드로 통일
- GC 최적화 — WaitCache, ObjectPool, GC-free Collection 확장
- Domain Reload 대응 — EventBus, WaitCache에
[RuntimeInitializeOnLoadMethod] - 한글 주석 — 모든 public API에 XML 문서 주석 (한국어)
- MonoSingleton — AudioHelper, ScreenTransition, UIManager 등 DontDestroyOnLoad 자동 처리
🔜 다음 계획
- Addressables 기반 UI 로딩 (Resources 대체)
- DOTween 연동 애니메이션 헬퍼
- 네트워크 HTTP 헬퍼 (UniTask 기반)
- 로컬라이제이션 시스템
이 Common 라이브러리는 Git 서브모듈로 관리하여 여러 프로젝트에서 공유합니다.
새 프로젝트를 시작할 때git submodule add로 바로 가져다 쓸 수 있습니다.
🔄 업데이트 로그
2026-02-12: Coroutine → UniTask 전면 마이그레이션
- UniTask 패키지 도입 (
com.cysharp.unitask) - 코루틴 → async/await 전환:
AudioHelper,BaseView,ScreenTransition,UIButtonExtensions - CancellationTokenSource 기반 취소 패턴 적용 (기존
StopCoroutine대체) - CoroutineExtensions → UniTaskExtensions 전면 교체 (
GetCancellationTokenOnDestroy()기반 자동 취소) - WaitCache 삭제 — UniTask 자체 GC-free 대기 메서드로 대체
UIButtonExtensions쿨다운에서 MonoBehaviour 런너 불필요해짐
반응형