Unity 자습서/Addressable

유니티 Addressable #3 - 원하는 타입의 레퍼런스 만들 기

개양반 2020. 9. 7.
728x90

가. 오늘 공부할 내용

유니티 에디터에서 인스펙터를 통해 AssetReference 변수로 번들에 있는 에셋을 참조시키는 방법을 배웠습니다.

AssetReference변수는 모든 에셋 리스트가 표시된다.

하지만, 이렇게 모든 타입의 에셋 리스트가 표시되면 실수를 할 수 있게 됩니다. 예를 들면 스프라이트만 참조해야 하는데 클릭미스로 게임 오브젝트를 참조시킨다는 등의 실수 말이죠. 이런 실수를 방지하기 위해 AssetReferenceGameObject, AssetReferenceSprite, AssetReferenceTexture 등이 존재하지만 이 리스트에 없는 Material 등 특정 타입은 어떻게 해야 하는지 알아보겠습니다.


나. 머터리얼 제작

테스트로 사용할 머터리얼을 하나 제작합니다.


다. 스크립트 작성

1. FilteredReferences.cs 생성 및 작성

아래 코드를 작성합니다.

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

public class FilteredReferences : MonoBehaviour
{
    // AssetReferenceT<원하는 타입> 을 상속 받습니다.
    // AssetReferenceMaterial 를 통해서 Material 타입의 에셋을 참조할 수 있습니다.
    [Serializable]
    public class AssetReferenceMaterial : AssetReferenceT<Material>
    {
        public AssetReferenceMaterial(string guid) : base(guid) { }
    }

    private SpriteRenderer spriteRenderer;

    // Material 타입 에셋을 참조할 수 있는 커스텀 변수입니다.
    public AssetReferenceMaterial materialReference;
    public AssetReferenceSprite spriteReference;

    private void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    public void OnLoadSprite()
    {
        spriteReference.LoadAssetAsync().Completed += SpriteLoaded;
    }

    public void OnLoadMaterial()
    {
        materialReference.LoadAssetAsync().Completed += MaterialLoaded;
    }

    public void OnUnLoadSprite()
    {
        // ReleaseAsset() 을 통해 메모리에 올라간 에셋레퍼런스를 해제합니다.
        spriteReference.ReleaseAsset();
    }

    public void OnUnLoadMaterial()
    {
        // ReleaseAsset() 을 통해 메모리에 올라간 에셋레퍼런스를 해제합니다.
        materialReference.ReleaseAsset();
    }


    private void SpriteLoaded(AsyncOperationHandle<Sprite> obj)
    {
        switch (obj.Status)
        {
            case AsyncOperationStatus.Succeeded:
                spriteRenderer.sprite = obj.Result;
                break;

            case AsyncOperationStatus.Failed:
                Debug.Log("스프라이트 로드 실패");
                break;

            default:
                break;
        }
    }

    private void MaterialLoaded(AsyncOperationHandle<Material> obj)
    {
        switch (obj.Status)
        {
            case AsyncOperationStatus.Succeeded:
                spriteRenderer.material = obj.Result;
                break;

            case AsyncOperationStatus.Failed:
                Debug.Log("스프라이트 로드 실패");
                break;

            default:
                break;
        }
    }
}

#주요 코드

public class AssetReferenceMaterial : AssetReferenceT<Material>
{
        public AssetReferenceMaterial(string guid) : base(guid) { }
}

AssetReferenceMaterial는 제가 만든 클래스 입니다. AssetReferenceT<T> 를 상속받습니다. 생성자를 통해 에셋이 참조될때 해당 guid를 참조시킵니다. 유니티에서 제공하는 AssetReference타입 외 다른 타입의 에셋레퍼런스를 참조시킬때 위 코드를 사용하시면 됩니다.


라. 컴포넌트 연결 및 버튼 추가

1. Loader 오브젝트

Loader 오브젝트의 AddressableSpriteLoader.cs 는 비활성화합니다. 위에서 만든 스크립트를 추가하고 각 변수에 알맞은 에셋레퍼런스를 연결합니다. 

2. 버튼 추가

4개의 버튼을 만들었습니다. 위 스크립트를 이해하신 분들이라면 각 버튼에 어떤 이벤트가 걸려야 하는지 아실거라 생각합니다.

 

3. Send Profiler Events 활성화

Addressables Events Viewer 로 에셋이 메모리에 어떤 식으로 올라가는지 확인할 겁니다.


마. 테스트

스프라이트 로드, 머터리얼 로드, 스프라이트 언로드, 머터리얼 언로드 순으로 버튼을 눌러 확인합니다. 

Addressables Events Viewer 가 작동 안하시는 분들은 Clear 버튼을 한번 눌러주세요.

숫자 1이 현재 메모리에 올라간 수이다.

언로드를 눌러서 메모리에서 에셋이 내려간 것을 확인합니다. 에셋이 내려갔어도 인스턴트화된 게임 오브젝트에는 아무런 변화가 없는 것도 확인합니다. 

댓글

💲 추천 글