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 권장)










