[Unity] 스크립트로 Runtime 시 Addressables Profile 변경

OOING·2023년 12월 18일
0

기타 프로젝트

목록 보기
3/6

배경

하고자하는 바

현재 프로젝트에서 업데이트 시 극강의 효율을 내기 위해 이런 저런 시도를 감행하고 있는데, 그 중 하나가 바로 스크립트를 이용해서 특정 버튼을 클릭하면 Addressables Profile의 active를 변경하는 것.


profile 옆에 ✔️되어있는 것이 현재 active한 profile

현재 진행중인 프로젝트가 무엇이냐면,
이전에 만들었던 프로젝트들을 하나의 앱에서 실행할 수 있게 하는 것이다. (ㄷㅎㅎㅇㄹ 유니버스 확장)

이전에 만들었던 프로젝트들(총 3개)도 모두 Addressable 시스템을 사용하고 있고, 각각의 Remote Load Path(AWS S3 버켓)이 다르다!!

그러므로 현재 프로젝트(유니버스라고 칭하겠다)에서는

  1. 기존에 만들었던 3개의 프로젝트의 Main Scene을 Addressable Asset으로 만들고
  2. 유니버스에서는 기존 프로젝트 실행 버튼을 클릭하면 해당 프로젝트의 Scene을 Load해야하며
  3. 실행중인 Scene에서도 필요한 Addressable Asset을 Load해야 한다.

즉, 각 프로젝트의 Main Scene을 담을 bucket, 각 프로젝트의 Addressable Asset Bundle들이 담겨있는 bucket 3개. 총 Profile이 4개 필요하다.

왜 귀찮게?

사실 그냥 무지성으로 새 프로젝트에 씬을 import해서 만드는 방법도 있다. 그러면 profile을 변경하는 수고도 없음!

하지만, 굳이 기존 프로젝트들의 Main Scene을 Addressable Asset으로 만드는 가장 큰 이유는 앱들의 업데이트가 지속적으로 될 것이기 때문!!

각 Scene을 Addressable Asset으로 만들어서 Load하는 방식으로 하면, 해당 앱이 업데이트됐다고 해서 이 유니버스 앱을 업데이트할 필요가 없다!
(사실 이렇게 하기 위해 코드도 엄청 뜯어고치긴 했다.. ㅋㅋ 하드코딩 다 날리고 동적으로 할 수 있는 방식으로🥹)

해결 방안

아무래도 기존 프로젝트의 Scene 역시 Addressable Asset으로 만들어서 여간 복잡한게 아니었지만, 대충 설명하자면

PlayerPrefs를 이용해서 선택한 씬이 무엇인지 관리하고, 현재 선택한 씬이 무엇인지에 따라 해당 씬(프로젝트)의 bundle이 들어있는 버킷으로 Remote Load Path를 지정해놓은 profile로 setting을 볌경했다.

Main Scene에서 어떤 버튼을 누르냐에 따라 값을 다르게 줬다는 뜻.

PlayerPrefs에 저장된 값이 1이면 AR, 0이면 2D profile을 로드해야 한다.. 이런 식으로.

코드

using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine.AddressableAssets.ResourceLocators;

private bool isAr;

private void Awake()
{
    if(PlayerPrefs.GetInt(“isAR”) == 1) isAR = true;
    else isAR = false;
}

public void UpdateProfile()
{
    Addressables.InitializeAsync().Completed += operation =>
    {
        if (isAR)
        {
        	OnAddressablesInitialized(operation, "AR");
            // 이후 동기적으로 실행할 코드 작성
        }
        else
        {
        	OnAddressablesInitialized(operation, "2D");
            // 이후 동기적으로 실행할 코드 작성
        }
    };
    // 비동기적으로 실행할 코드 작성
}

private void OnAddressablesInitialized(AsyncOperationHandle<IResourceLocator> obj, string profile)
{
    AddressableAssetProfileSettings profileSettings = AddressableAssetSettingsDefaultObject.Settings.profileSettings;
    string profileId = profileSettings.GetProfileId(profile);
    AddressableAssetSettingsDefaultObject.Settings.activeProfileId = profileId;
    AddressableAssetSettigs.BuildPlayerContent();
}


버튼을 누르면 profile이 동적으로 변경!

반드시 GetProfileId(profile name) 을 통해 profileID를 받아줘야 한다! (이걸 몰라서 좀 헤맸다😫) 그리고 프로필 변경 후, 변경된 load path에서 Addressable asset을 load하기 전에 Build해야한다. 빌드까지 해야 설정이 제대로 반영돼는 것 같다.

난 Active Profile을 변경한 후, 변경된 Remote Load Path에서 bundle을 다운로드해야해서 동기적으로 실행할 코드 부분에 bundle을 다운로드하는 코드를 작성해줬다.

현재 방식의 문제점

이어서 코딩을 하던 중에 이 방식의 문제점을 발견했다!!

만약 profile을 변경하기 전에 로드한 에셋을 사용하고 있다면, 유니티에서 active profile이 변경되었더라도 실제로는 변경 이전의 profile이 그대로 active하다! scene을 addressable asset으로 만들어 적용하던 중 발견했다😭

그래서 Profile을 변경하는 방식이 아닌, 처음부터 여러 catalog를 사용하는 방식으로 변경하기로 했다. 해당 방법은 다음 포스트에 작성!
(두 가지 방식을 다 해보니, catalog를 로드하는 방식이 훨씬 나은 것 같다. 이유도 다음 포스트에..?)

profile
HICE 19

0개의 댓글