
Addressables
- Addressables 에셋은 리소스를 효율적으로 관리하고자 Unity에서 기본적으로 제공하는 에셋입니다.
- Resources 폴더의 경우 사용 여부와는 상관없이 모두 Load를 하는데 적은양의 리소스의 경우 문제가 없지만 프로젝트의 사이즈가 커져 관리해야 하는 리소스가 많이 생기게 되면, 게임 로드시에 렉이나 문제를 유발 할 수 있습니다.
- Addressables 의 경우 이런 문제를 해결하고
Label을 이용하여 원하는 시점에 리소스들을 로드할 수 있습니다. - 예를들어, Lobby Scene 리소스, Game Scene 리소스 등을 구분하여 로드가 가능해집니다.
설치
-
[Window] => [Package Manager] => Package : Unity Registry=> Addressables를 Install 합니다.

리소스 등록 및 관리
[Window] => [Assets Management] => Addressables => Group

Addressables Group

- New : 새 그룹을 생성합니다.
- Group : 종류별로 임의의 그룹에 따라서 리소스를 정리 할 수 있습니다.
- 등록 : Project 에서 Drag & Drop으로 등록합니다.
- 삭제 : 리소스를 선택 후 오른쪽 클릭하여 Remove 합니다.

-
PrimeKey :
노란색박스의 안에 있는 것은PrimeKey로 해당 리소스를 특정할 수 있는 Key값 입니다. 처음 등록시 Path가 모두 나오게 되므로 이름을 수정해주어야 편합니다. -
Path :
주황색박스안의 내용이며, 해당 리소스의 경로(Path)값을 나타냅니다. -
Label :
파란색박스안의 있는 것은Label로 임의의 라벨을 생성할 수 있으며, 추가하거나 삭제 할 수 있습니다. 언제 Load할 것인지 구분할 때 사용할 수 있습니다.
Code
LoadAsync
-
PrimeKey가 일치하는 리소스를 로드하는 메서드 - Callback Action으로 해당 리소스를 로드 합니다.
public void LoadAsync<T>(string key, Action<T> cb = null) where T : Object
{
string loadKey = key;
if (_resources.TryGetValue(key, out Object resource))
{
cb?.Invoke(resource as T);
return;
}
if (key.Contains(".sprite"))
{
loadKey = $"{key}[{key.Replace(".sprite", "")}]";
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>(loadKey);
HandleCallback(key, handle, cb as Action<Sprite>);
}
else
{
AsyncOperationHandle<T> handle = Addressables.LoadAssetAsync<T>(loadKey);
HandleCallback(key, handle, cb);
}
}
Addressables.LoadAssetAsync<T>(loadKey)
- 어드레서블 그룹중에서 Key를 입력 받아 해당 타입의 오브젝트를 반환합니다.
- 만약 해당 키가 존재하지 않는다면 Exception을 출력합니다.
LoadAllAsync
-
label을 확인하여 해당 라벨에 포함되는 모든 리소스를 로드합니다.
public void LoadAllAsync<T>(string label, Action<string, int, int> cb) where T : Object
{
var operation = Addressables.LoadResourceLocationsAsync(label, typeof(T));
operation.Completed += op =>
{
int loadCount = 0;
int totalCount = op.Result.Count;
foreach (var result in op.Result)
{
LoadAsync<T>(result.PrimaryKey, obj =>
{
loadCount++;
cb?.Invoke(result.PrimaryKey, loadCount, totalCount);
});
}
};
Loaded = true;
}
Callback Action
- Addressable.Load…. 메서드의 경우 비동기적으로 움직이기 때문에 리소스가 로드되고 있는 와중에도 다른 프로세스를 처리할 수 있습니다.
- 그렇게 때문에 해당 로드가 언제 완료되는지 모르기 떄문에 이벤트를 호출하여 다음 코드를 실행합니다.
- 비동기 로드가 끝나고 호출되는 이벤트는
.Complete가 호출 됩니다. - 해당 이벤트가 호출 되면 Callback을 실행할 수 있도록 코드를 작성합니다.
-
해당 코드에서는 PrimeKey, 로드된 리소스의 개수, 총 로드를 해야하는 리소스 개수를 Invoke 합니다.
- 해당 메서드의 실제 사례는 아래와 같습니다.
MainManager.ResourceManager.LoadAllAsync<Object>("PreLoad", (key, count, totalCount) =>
{
Debug.Log($"{key} Load ({count} / {totalCount})");
if (count < totalCount) return;
MainManager.ResourceManager.Loaded = true;
Initialize();
});
-
PreLoad라는 라벨을 가진Object형태의 리소스를 모두 로드 합니다. - Debug.Log 결괏값은 아래와 같습니다.

- 해당 Callback을 이용하면 Loading Bar등을 구현할 수 있습니다.
- Slider의 value = count, MaxValue = totalCount를 할당하면 리소스가 로드 될때마다 슬라이더가 채워집니다.
아래는 Addressables 기능의 전체 코드 입니다.
private void HandleCallback<T>(string key, AsyncOperationHandle<T> handle, Action<T> cb) where T : Object
{
handle.Completed += operationHandle =>
{
_resources.Add(key, operationHandle.Result);
cb?.Invoke(operationHandle.Result);
};
}
public void LoadAsync<T>(string key, Action<T> cb = null) where T : Object
{
string loadKey = key;
if (_resources.TryGetValue(key, out Object resource))
{
cb?.Invoke(resource as T);
return;
}
if (key.Contains(".sprite"))
{
loadKey = $"{key}[{key.Replace(".sprite", "")}]";
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>(loadKey);
HandleCallback(key, handle, cb as Action<Sprite>);
}
else
{
AsyncOperationHandle<T> handle = Addressables.LoadAssetAsync<T>(loadKey);
HandleCallback(key, handle, cb);
}
}
public void LoadAllAsync<T>(string label, Action<string, int, int> cb) where T : Object
{
var operation = Addressables.LoadResourceLocationsAsync(label, typeof(T));
operation.Completed += op =>
{
int loadCount = 0;
int totalCount = op.Result.Count;
foreach (var result in op.Result)
{
LoadAsync<T>(result.PrimaryKey, obj =>
{
loadCount++;
cb?.Invoke(result.PrimaryKey, loadCount, totalCount);
});
}
};
Loaded = true;
}
마치며
어드레서블의 경우 처음에는 익숙하지 않아서 시간이 좀 걸리지만, 이해하고 나면 정말 편한 기능을 제공합니다.
다만 위에서 알아본 기능은 정말 많은 기능 중 하나에 불과하므로 기회가 된다면 다른 기능도 이용해 보았으면 합니다.