본문 바로가기

유니티/Addressable

[ Addressable ] 02 . Addressable 로 프로젝트 전환하기

[ 학습 흐름 ]
  • 어드레서블 패키지을 사용하기 위해 기본 세팅을 수행한다 .
  • 기존 프로젝트를 어드레서블로 전환한다 .
  • 어드레서블을 로컬에서 Asset Reference / Address / Label 3가지 방법으로 로드해본다 .
  • Lable에 관해 알아본다 .

[ Addressable 시작하기 ]

1 . 설치

[ 패키지 설치하기 ]

  1. Package Manager(메뉴: Window > Package Manager)를 연다
  2. 목록에서 Addressables 패키지를 선택한다 .
  3. Install 을 클릭하여 설치 .

2 . 어드레서블 시스템 설정하기

[ 설정 생성 ]

- Window - Asset Management -Addressable - Group을 통해 그룹창에 진입 .

- Create Addressables Settings 커맨드를 실행하면 어드레서블 시스템이 AddressableAssetsData라는 폴더를 생성.

- 어드레서블 설정을 추적하기 위해 사용하는 설정 파일과 기타 에셋을 저장한다 .


[ Addressable 로 프로젝트 전환하기 ]

1 . 씬 데이터 전환

[ 씬 데이터 ]

- 씬 데이터는 씬 또는 씬의 컴포넌트에 직접추가하는 에셋이다 .

- 애플리케이션이 자동으로 로드한다 .

- 유니티는 씬이 직접 참조하는 에셋/직렬화된 씬 데이터를 하나의 아카이브에 패키지화하여 빌드된 플레이어 앱에 포함.


[ 씬 데이터를 어드레서블로 전환 ]

- 씬 데이터를 어드레서블로 전환하려면 빌드 설정 목록에서 해당 씬을 제거한다 .

- 해당 씬의 어드레서블 옵션을 체크 .

- 이후 씬을 로드할때는 SceneManager 가 아닌 Addressable 클래스 씬 로딩 메서드를 사용한다 .

- 씬 목록에는 어드레서블화된 씬들을 로드하는 하나의 씬만 있어야 하며 해당씬은 어드레서블이 아니어야 한다 .


[ 주의점 ]

- 비어드레서블 씬에서는 유니티 엔진의 컴포넌트 필드에 어드레서블 에셋을(ex ) Asset Reference) 사용이 불가하다 .

- 만약 할당된다면 , 유니티는 해당 에셋을 복사하기에 두가지 버전 (어드레서블 / 빌트인씬)으로 존재한다 .


2 .  프리팹 전환

[ 프리팹 ]

- 게임 오브젝트와 컴포넌트를 사용하여 만들고 , 씬 외부에 저장하는 에셋 .


[ 프리팹을 어드레서블로 전환 ]

- 프리팹 상단의 Addressable을 체크하면 주소가 할당된다 . 

- 해당 주소는 변경 가능하다 . 본인이 원하는 어떤 형태든 가능하다 .

- Window - Asset Management - Addressable - Groups를 통해 확인 가능하다 .

- 그룹은 이동 가능하며 해당 창에 드레그 앤 드롭 함으로써 에셋을 어드레서블로 만들 수 있다 .


[ 에셋 주소 ]

- 어드레서블 관리자는 콘텐츠 카탈로그에서 위 주소를 검색하여 에셋이 저장된 위치를 찾는다 .

- 그렇기에 주소만 지정되어 있다면 에셋이 어디에 있든간에 찾을 수 있는것 .


[ 주의점 ]

- 어드레서블 씬에서 사용되는 프리팹의 경우 어드레서블로 만들지 않아도 , 어드레서블은 씬 계층구조에 있는 프리팹을 씬의 에셋 번들에 포함된 데이터의 일부로 자동으로 포함한다 .

- 만약 해당 프리팹이 둘 이상의 씬에서 사용된다면 프리팹이 어드레서블이 되어야 한다 .

- 비어드레서블 씬에서 프리팹이 쓰인다면 프리팹을 빌드인 씬 데이터로 복사한다 .

- 이러한 데이터들을 분석툴의 Check Scene to Addressable Dulplicate Dependencies로 어드레서블 에셋 그룹과 비 어드레서블 씬 데이터 간에 중복 에셋이 식별 가능하다 .


3 .  Resources 폴더 전환

[ Resources ]

- 프로젝트의 Resources 폴더에 배치 , Resources API를 사용하여 로드하는 에셋 .

- 해당 파일의 에셋을 하나의 아카이브에 패키지화하여 빌드된 플레이어 앱에 포함한다 .

- 즉 , 빌드 용량에 그대로 포함되는 폴더 .


[ Resources를 어드레서블로 전환 ]

Resources.LoadAsync<GameObject>("desert/tank.prefab");

 

- 기존 Resources 폴더에서 로드하는 코드는 다음과 같다 .

Addressable.LoadAssetAsync<GameObject>("desert/tank.prefab");

- 변경된 코드는 다음과 같을 것이다 .

- 만약 Resouces 폴더에 있는 에셋을 어드레서블로 만드려 하면 위의 경고와 함께 Resources_moved 폴더로 옮긴다 .


[ Addressable Asset  로컬에서 로드해보기 ]

1 . AssetReference 사용

[ 스크립트 작성 ]

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

internal class LoadWithReference : MonoBehaviour
{
    // 에디터에서 설정
    public AssetReference reference;

    void Start()
    {
        AsyncOperationHandle handle = reference.LoadAssetAsync<GameObject>();
        handle.Completed += Handle_Completed;
    }

    //성공적으로 로드되면 씬에 생성한다 .
    private void Handle_Completed(AsyncOperationHandle obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Instantiate(reference.Asset, transform);
        }
        else
        {
            Debug.LogError($"AssetReference {reference.RuntimeKey} failed to load.");
        }
    }

    //에셋을 릴리스 한다 .
    private void OnDestroy()
    {
        reference.ReleaseAsset();
    }
}

- 다음과 같이 스크립트를 작성한다 .


[ 사용하기 ]

- Reference에 방금 생성한 에셋을 할당한다 .

- 설정한 Reference가 위와 같이 생성됨을 볼 수 있다 .

- Addressables.Release를 호출하면 해당 에셋의 참조 횟수가 감소하며 , 0이되면 메모리에서 언로드 된다 .


2. 어드레스로 로드하기

[ 스크립트 작성 ]

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

internal class LoadWithAddress : MonoBehaviour
{
    //에디터에서 입력하자
    public string address;

    // handle을 통해 추후 동작과 메모리에서 해제가 가능하다 
    private AsyncOperationHandle<GameObject> handle;

    void Start()
    {
        handle = Addressables.LoadAssetAsync<GameObject>(address);
        handle.Completed += Handle_Completed;
    }

    // 로드 성공시 생성
    private void Handle_Completed(AsyncOperationHandle<GameObject> operation)
    {
        if (operation.Status == AsyncOperationStatus.Succeeded)
        {
            Instantiate(operation.Result, transform);
        }
        else
        {
            Debug.LogError($"Asset for {address} failed to load.");
        }
    }

    //메모리에서 해제
    private void OnDestroy()
    {
        Addressables.Release(handle);
    }
}

[ 사용하기 ]

- 주소를 지정하면 해당 에셋이 로드됨을 볼 수 있다 .


3. 레이블로 로드하기

[ 레이블 지정하기 ]

- 우측 레이블 버튼을 누르면 라벨을 지정 할 수 있다 . 

- 레이블은 여러개를 지정 할 수도 있다 .


[ 스크립트 작성 ]

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

internal class LoadWithLabels : MonoBehaviour
{
    // Label strings to load
    public List<string> keys = new List<string>() {"characters", "animals"};

    // Operation handle used to load and release assets
    AsyncOperationHandle<IList<GameObject>> loadHandle;

    // Load Addressables by Label
    void Start()
    {
        float x = 0, z = 0;
        loadHandle = Addressables.LoadAssetsAsync<GameObject>(
            keys, // Either a single key or a List of keys 
            addressable =>
            {
                //Gets called for every loaded asset
                if (addressable != null)
                {
                    Instantiate<GameObject>(addressable,
                        new Vector3(x++ * 2.0f, 0, z * 2.0f),
                        Quaternion.identity,
                        transform);
                    if (x > 9)
                    {
                        x = 0;
                        z++;
                    }
                }
            }, Addressables.MergeMode.Union, // How to combine multiple labels 
            false); // Whether to fail if any asset fails to load
        loadHandle.Completed += LoadHandle_Completed;
    }

    private void LoadHandle_Completed(AsyncOperationHandle<IList<GameObject>> operation)
    {
        if (operation.Status != AsyncOperationStatus.Succeeded)
            Debug.LogWarning("Some assets did not load.");
    }

    private void OnDestroy()
    {
        // Release all the loaded assets associated with loadHandle
        Addressables.Release(loadHandle);
    }
}

- Load AssetsAsync는 3개의 인자를 받는데 하나씩 살펴보자 .

 

Keys

- 사용할 Label 들을 인자로 받는다 . 위에서는 List 형태로 설정 .

 

Mode

-  Addressables.MergeMode의 다양한 옵션을 통해 키가 여러 개일 때 결과를 병합하는 방식을 지정한다 .

  • UseFirst/None: 첫 번째 키의 결과만 사용 
  • Union: 모든 키의 결과를 병합하여 중복 없이 결과 . 즉 , 합집합
  • Intersection: 모든 키의 결과에서 공통 항목만 모음 . 즉 , 교집합

ReleaseDependencyOnFailure

  • True 일때
    에셋 로드 작업이 실패하면 작업의 일부로 로드된 모든 종속성이 해제된다 .
    이는 해당 종속성을 로드하는 데 사용된 메모리를 정리하고 해제하여 메모리 누수를 방지하는 데 도움이 된다 .
  • False 일때
    에셋 로드 작업이 실패하면 종속성이 자동으로 해제되지 않는다 .
    종속성을 수동으로 처리하려는 경우 또는 해당 종속성을 여전히 필요로 하는 코드의 다른 부분이 있는 경우 사용한다 .

예를 들면 A , B 모두 같은 마테리얼을 사용했을때 해당 마테리얼의 참조 카운트는 2일것이다 . 

True의 경우 한쪽이 실패시 해제되어 1이 될것이고 , 실패시 2로 남아 있을 것이다 .


[ Label ]

1 . 레이블

[ 레이블이란 ]

- 어드레서블 에셋에 하나 이상의 레이블을 태그 할 수 있다 .

- 레이블은 다음의 용도로 사용된다 .

  • 하나 이상의 레이블을 키로 사용하여 런타임에 로드할 에셋을 식별 가능하다 .
  • 할당된 레이블에 따라 그룹의 에셋을 에셋번들에 패킹 가능하다 .
  • 그룹 창의 필터 상자에서 레이블을 사용 , 레이블이 지정된 에셋을 찾을 수 있다 .

[ 레이블 관리하기 ]

-  Window - Asset Management - Addressables - Groups - Tools - Window - Labels를 통해 액세스가 가능하다 .

- 그룹창을 통해 레이블의 지정이 가능하다 .

- 혹은 해당 에셋의 레이블 표시를 클릭, 직접 지정 가능하다 .

 

출처

https://docs.unity3d.com/kr/Packages/com.unity.addressables@1.21/manual/AddressableAssetsGettingStarted.html

 

시작하기 | Addressables | 1.21.17

시작하기 처음으로 어드레서블을 설정하고 사용하는 데 도움이 되는 정보를 안내합니다.

docs.unity3d.com