서비스
교육 철학

유니티 에셋 관리 (Resources , Assetbundle, Addressables)

Abstract

📌
Unity 에서 "프리팹을 코드로 불러오는" 방법은 세 가지가 있고, 뒤로 갈수록 나중에 나온 것입니다 — Resources → AssetBundle → Addressables. 이 페이지는 셋을 비교합니다. 이 위키의 프레임워크(YamYamCoding 에디션)는 Addressables 를 골랐고, 그래서 여기를 읽어 두면 ShowEntity("Zombunny", …) 의 "Zombunny" 가 무엇이고 왜 그렇게 쓰는지가 이해됩니다.
세 방식을 한 문장씩
방식
한 문장
지금의 위치
Resources
특정 폴더에 넣어 두면 경로 문자열로 꺼낼 수 있다
프로토타입·아주 작은 게임. Unity 도 대규모 사용을 권하지 않는다
AssetBundle
에셋을 파일 묶음으로 따로 빌드해 필요할 때 읽는다. 묶기·의존성·버전은 직접 관리한다
Addressables 의 밑바닥 기술. 직접 다루는 것은 기존 프로젝트나 특수한 요구가 있을 때
Addressables
에셋에 "주소"를 붙여 두면, 어느 번들에 있든 어디서 받아 오든 주소 하나로 꺼낸다
새 프로젝트의 기본 선택
Addressables 는 AssetBundle 을 대체하는 다른 기술이 아니라 AssetBundle 위에 자동화를 얹은 것입니다. 번들은 여전히 만들어지고, 그것을 묶고 찾고 세는 일을 대신 해 줄 뿐입니다.
프레임워크는 이것을 어떻게 쓰나
게임 코드는 Addressables.LoadAssetAsync 를 직접 부르지 않습니다. 프레임워크의 호출이 안에서 대신 부릅니다.
이 페이지의 방식 (Addressables 직접)
프레임워크를 거치면
LoadAssetAsync<GameObject>("Zombunny") → Instantiate → 나중에 Destroy • Release(handle)
ShowEntity(id, typeof(Enemy), "Zombunny", "Enemy", data) → 나중에 HideEntity
핸들을 어딘가에 보관해 두었다가 직접 해제
프레임워크가 보관·해제. 게임 코드에는 핸들이 보이지 않는다
매번 새로 인스턴스화
인스턴스를 풀에서 재사용
await 또는 Completed 콜백으로 결과 받기
ShowEntitySuccess 이벤트 또는 로직의 OnShow 로 받기
그래서 프레임워크 사용자가 Addressables 에 대해 알아야 할 것은 에디터 쪽 작업 세 가지로 줄어듭니다.
1.
Groups 창에 에셋을 등록한다 (Window → Asset Management → Addressables → Groups)
2.
주소를 짧은 키로 바꾼다 — 기본값은 Assets/Art/Prefabs/Zombunny.prefab 같은 전체 경로다. Zombunny 로 줄이고, 코드에서 그 문자열을 그대로 쓴다
3.
Play Mode Script 를 Use Asset Database 로 둔다 — 개발 중 번들을 빌드하지 않고 바로 실행하기 위한 설정. Library/ 에 저장되어 git 으로 공유되지 않으므로 프로젝트를 받은 사람마다 한 번씩 해야 한다
ToyboxNightmare 의 등록 현황
Prefabs 그룹 하나에 25개 — 캐릭터 2, 적 5, 아군 2, 투사체·이펙트 5, UI 폼 2, 사운드 클립 8, 배경 1. 주소는 전부 Girl, Zombunny, HUDForm, PlayerHurt 같은 짧은 한 단어입니다.
⚠️
이 위키의 프레임워크와 다른 점 · 본문을 읽을 때 주의할 점
•
본문 "주소 명명 규칙"은 "Characters/Heroes/Warrior" 처럼 계층형 주소를 권합니다. 일반적으로는 좋은 관례이고, 예제 게임은 규모가 작아 짧은 한 단어를 썼습니다. 어느 쪽이든 코드의 문자열과 정확히 같기만 하면 됩니다. 단, 씬만은 프레임워크가 Assets/ 로 시작하고 .unity 로 끝나는 이름을 요구하므로 전체 경로를 주소로 씁니다.
•
본문의 로딩 예제(await handle.Task, InstantiateAsync, ReleaseInstance)는 Addressables 를 직접 쓸 때의 코드입니다. 프레임워크를 쓰는 게임 코드에는 나오지 않습니다. 직접 쓰게 되는 경우는 패치 다운로드처럼 프레임워크가 다루지 않는 영역입니다(Resource Updating(리소스 업데이트)-Addressable).
•
본문 예제 LoadSingleAsset 은 핸들을 해제하지 않습니다. 설명용으로 줄인 것이고, 실제로는 인스턴스를 다 쓴 뒤 Addressables.Release(handle) 을 해야 번들이 내려갑니다. 프레임워크가 감춰 주는 것이 바로 이 짝 맞추기입니다.
•
빌드 스크립트 이름과 모니터링 도구 이름을 현재 버전(Addressables 2.x)에 맞게 고쳤습니다. 또 "Resources 의 모든 에셋이 메모리에 상주한다"는 설명은 정확하지 않아 고쳤습니다 — 상주하는 것은 에셋이 아니라 색인입니다.

Resources vs Asset Bundles vs Addressables 비교

Resources System

특징

•
Unity의 가장 기본적인 에셋 관리 시스템
•
Resources 폴더에 배치된 에셋들을 런타임에 로드
•
간단하고 직관적인 사용법

장점

•
간단함: 복잡한 설정 없이 바로 사용 가능
•
즉시 사용: 별도 빌드 과정 없음
•
동기 로딩: Resources.Load()로 즉시 로드 가능

단점

•
시작 시간·메모리 부담: 에셋 자체가 전부 메모리에 올라오는 것은 아니지만, Resources 폴더 전체의 색인이 앱 시작 때 로드되어 에셋이 많을수록 실행이 느려지고, 로드한 에셋을 언제 내릴지 관리하기 어렵다
•
빌드 시간 증가: 모든 에셋이 빌드에 포함됨
•
유연성 부족: 동적 다운로드나 업데이트 불가능
•
플랫폼 최적화 어려움: 모든 플랫폼에 동일한 에셋 포함

사용 예제

// 동기 로딩 GameObject prefab = Resources.Load<GameObject>("Prefabs/MyPrefab"); // 비동기 로딩 ResourceRequest request = Resources.LoadAsync<Texture2D>("Textures/MyTexture"); yield return request; Texture2D texture = request.asset as Texture2D;
C#
복사

Asset Bundles

특징

•
에셋들을 번들 단위로 묶어서 관리
•
런타임에 동적으로 로드/언로드 가능
•
원격 서버에서 다운로드 가능

장점

•
메모리 효율성: 필요한 번들만 로드
•
동적 컨텐츠: 런타임에 새로운 컨텐츠 다운로드
•
플랫폼 최적화: 플랫폼별 번들 생성 가능
•
압축: 번들 압축으로 용량 절약

단점

•
복잡한 관리: 의존성 관리가 어려움
•
수동 설정: 번들 빌드와 로딩 코드를 직접 작성
•
중복 문제: 의존성 에셋의 중복 포함 가능성
•
버전 관리: 수동으로 버전 체크 및 업데이트 관리
•
경로 변경: 번들에 들어있는 Asset Path변경의 번거로움

사용 예제

// 번들 로드 AssetBundle bundle = AssetBundle.LoadFromFile(path); // 에셋 로드 GameObject prefab = bundle.LoadAsset<GameObject>("MyPrefab"); // 번들 언로드 bundle.Unload(false); // 에셋은 유지 bundle.Unload(true); // 에셋도 함께 해제
C#
복사

Addressable Assets

특징

•
Asset Bundle의 고급 버전으로, 자동화된 에셋 관리
•
주소(Address) 기반 에셋 참조
•
의존성과 메모리 관리 자동화

장점

•
자동 의존성 관리: 의존성 자동 해결
•
간편한 사용: Asset Bundle의 복잡함 없이 간단한 API
•
유연한 배포: Local/Remote 배포 자동 전환
•
메모리 최적화: 자동 참조 카운팅
•
Hot-fix 지원: 런타임 컨텐츠 업데이트
•
프로파일링: 상세한 메모리 및 성능 분석

단점

•
학습 곡선: 초기 설정과 개념 이해 필요
•
빌드 시간: 번들 분석 및 빌드 시간 추가
•
Unity 버전 의존성: 비교적 최신 기능

사용 예제

// 비동기 로딩 var handle = Addressables.LoadAssetAsync<GameObject>("MyPrefab"); GameObject prefab = await handle.Task; // 메모리 해제 Addressables.Release(handle);
C#
복사

2. 언제 어떤 시스템을 사용할까?

Resources 사용 시기

•
프로토타입 개발: 빠른 테스트가 필요할 때
•
소규모 프로젝트: 에셋 수가 적고 복잡도가 낮을 때
•
항상 필요한 에셋: 게임 전반에 걸쳐 계속 사용되는 에셋

Asset Bundles 사용 시기

•
커스텀 관리 필요: 특별한 로딩 로직이 필요할 때
•
레거시 프로젝트: 이미 Asset Bundle로 구축된 프로젝트
•
세밀한 제어: 번들 로딩/언로딩을 직접 제어해야 할 때

Addressables 사용 시기 (권장)

•
현대적 프로젝트: 새로운 프로젝트 시작 시
•
DLC/업데이트: 런타임 컨텐츠 업데이트가 필요할 때
•
메모리 최적화: 효율적인 메모리 관리가 중요할 때
•
팀 협업: 복잡한 의존성을 자동으로 관리하고 싶을 때

성능 비교

항목
Resources
Asset Bundles
Addressables
메모리 효율성
⭐
⭐⭐⭐⭐
⭐⭐⭐⭐⭐
로딩 속도
⭐⭐⭐⭐⭐
⭐⭐⭐
⭐⭐⭐⭐
구현 용이성 (별이 많을수록 쉽다)
⭐⭐⭐⭐⭐
⭐⭐
⭐⭐⭐⭐
유지보수성
⭐⭐
⭐⭐
⭐⭐⭐⭐⭐
확장성
⭐
⭐⭐⭐⭐
⭐⭐⭐⭐⭐

Addressable Assets System 프로젝트 적용 방법

패키지 설치
Window → Package Manager → Unity Registry → Addressables 검색 → Install
Plain Text
복사

초기 설정

1.
Addressables Groups 창 열기
•
Window → Asset Management → Addressables → Groups
2.
첫 설정
•
Create Addressables Settings 클릭
•
Default Local Group (Default) 자동 생성됨

에셋을 Addressable로 만들기

방법 1: Inspector에서 설정

에셋 선택 → Inspector → Addressable 체크박스 활성화
Plain Text
복사

방법 2: Groups 창에서 드래그 앤 드롭

에셋을 Addressables Groups 창의 그룹으로 드래그
Plain Text
복사

방법 3: 스크립트로 설정

using UnityEditor.AddressableAssets; using UnityEditor.AddressableAssets.Settings; // 에셋을 Addressable로 설정 var settings = AddressableAssetSettingsDefaultObject.Settings; var entry = settings.CreateOrMoveEntry(assetGuid, settings.DefaultGroup); entry.address = "MyAssetAddress";
C#
복사

에셋 로딩 코드 예제

using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; public class AddressableLoader : MonoBehaviour { // 단일 에셋 로드 public async void LoadSingleAsset() { AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("MyPrefabAddress"); GameObject prefab = await handle.Task; Instantiate(prefab); } // 인스턴스 직접 생성 public async void InstantiateAsset() { AsyncOperationHandle<GameObject> handle = Addressables.InstantiateAsync("MyPrefabAddress"); GameObject instance = await handle.Task; // 사용 완료 후 해제 Addressables.ReleaseInstance(instance); } // 라벨로 여러 에셋 로드 public async void LoadAssetsByLabel() { AsyncOperationHandle<IList<GameObject>> handle = Addressables.LoadAssetsAsync<GameObject>("UI", null); IList<GameObject> assets = await handle.Task; foreach (var asset in assets) { Instantiate(asset); } Addressables.Release(handle); } }
C#
복사

빌드 설정

1.
Build Scripts 설정
•
Groups 창에서 Build → New Build → Default Build Script
2.
Profile 설정
•
Window → Asset Management → Addressables → Profiles
•
Local/Remote 경로 설정
3.
그룹 설정
•
각 그룹의 Build & Load Paths 설정
•
Bundle Mode (Pack Together/Pack Separately) 선택

주소 명명 규칙

카테고리/서브카테고리/에셋명 예: "Characters/Heroes/Warrior" "UI/MainMenu/StartButton" "Audio/BGM/MainTheme"
Plain Text
복사

메모리 관리

•
항상 Addressables.Release() 호출
•
큰 에셋은 사용 후 즉시 해제
•
Unity Profiler 의 Addressables 모듈로 핸들·번들 상태 모니터링 (예전의 Event Viewer 창은 Addressables 2.x 에서 없어졌다)

빌드 최적화

•
자주 바뀌지 않는 에셋은 별도 그룹으로 분리
•
의존성이 많은 에셋은 Shared 그룹에 배치
•
번들 크기를 적절히 유지 (1-10MB 권장)