【Unity】Addressables: シーンの読み込み

2023年4月30日

Addressablesシステムでは、いつアセットをアプリケーションにロードするか、どのアセットをロードするか、どこからロードするかを制御できます。Addressablesを使用すると、ゲームの初期ダウンロードサイズを縮小し、コンテンツの大部分をオンデマンドでダウンロードできます。また、ゲームを再構築せずに新しいアセットを更新または追加することもできます。これは、季節変動やマーケティングキャンペーンなどの一時的なコンテンツを追加したい場合に便利です。開発中、Addressablesシステムは、チーム内の新しいコンテンツの迅速な反復とテストも可能にします。

シーンの読み込み

パッケージマネージャからAddressablesをインポート

Windowメニュー、PackageManagerからインポートします

タイトルシーンを作成

タイトルのイメージを1つとシーン切り替え用のスクリプトをアタッチするための空のゲームオブジェクト(名前はLoader)を追加します

メインシーンを追加

スクリプトの作成

タイトルシーンのLoaderゲームオブジェクトにスクリプトをアタッチします

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    public AssetReference Scene;

    private void Start()
    {
        Addressables.LoadSceneAsync(Scene, LoadSceneMode.Single).Completed += SceneLoadComlete;
    }

    void SceneLoadComlete(AsyncOperationHandle<SceneInstance> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log(obj.Result.Scene.name + "ロード成功");
        }
    }
}

このスクリプトはUnityのアドレッサブルアセットシステムを使用して、指定されたアセットリファレンスに関連付けられたシーンを非同期でロードします。

以下が、主な処理の概要です。

  1. using ステートメントで必要な名前空間をインポートしています。
  2. SceneLoader クラスを定義しています。このクラスは MonoBehaviour クラスを継承しているため、Unityのライフサイクルメソッド(例えば、Start)を使用することができます。
  3. Scene というパブリック変数を宣言しています。これは、アセットリファレンスを保存するための変数です。
  4. Start メソッドで、アドレッサブルアセットシステムの LoadSceneAsync メソッドを呼び出して、指定されたシーンを非同期でロードします。このメソッドは LoadSceneMode.Single をパラメーターとして受け取り、同時に別のシーンをロードすることはできません。
  5. ロードが完了すると、 SceneLoadComlete メソッドが呼び出されます。このメソッドは、非同期操作のハンドルを受け取ります。
  6. SceneLoadComlete メソッドは、非同期操作の状態が成功しているかどうかを確認し、成功していれば、 Debug.Log を使用して、ロードされたシーンの名前を出力します。

このスクリプトは、Unityのアドレッサブルアセットシステムを使用してシーンを非同期でロードする方法を示しています。また、非同期操作の完了を確認する方法も示しています。

画面遷移するシーンをドラッグ&ドロップ

結果

Mainロード成功

シーンのアンロード

あとでアンロードできるように、シーンがロードされた時に生成されるAsyncOperationHandleへの参照を維持することが重要です

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    public AssetReference Scene;
    AsyncOperationHandle<SceneInstance> handle;
    bool unloaded;

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }

    private void Start()
    {
        Addressables.LoadSceneAsync(Scene, LoadSceneMode.Additive).Completed += SceneLoadComlete;
    }

    void SceneLoadComlete(AsyncOperationHandle<SceneInstance> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log(obj.Result.Scene.name + "ロード成功");
            handle = obj;
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.X) && !unloaded)
        {
            unloaded = true;
            UnloadScene();
        }
    }

    void UnloadScene()
    {
        Addressables.UnloadSceneAsync(handle, true).Completed += op =>
        {
            if (op.Status == AsyncOperationStatus.Succeeded)
            {
                Debug.Log("シーンのアンロード成功");
            }
        };
    }
}

このコードは、Unityエンジンを使用してアドレス可能なアセットシステムを使ってシーンを非同期的にロードし、アンロードするスクリプトです。

usingディレクティブを使用して、必要なUnityエンジンの名前空間をインポートします。SceneLoaderクラスは、MonoBehaviourクラスを継承します。AssetReferenceは、ロードされるシーンを表すために使用されるアドレス可能なアセットの参照です。

Awake()メソッドは、シーンが切り替わったときにゲームオブジェクトを破棄しないようにします。Start()メソッドは、アドレス可能なアセットからシーンを非同期的にロードします。Completedイベントを使用して、非同期操作の完了を待ちます。

Update()メソッドは、Xキーが押された場合にアンロードを実行します。UnloadScene()メソッドは、非同期的にシーンをアンロードし、完了を待ちます。アンロード完了後にコールバック関数を呼び出して、アンロードが成功したかどうかを確認します。

このスクリプトを実行するためには、アドレス可能なアセットシステムをプロジェクトに追加する必要があります。また、シーンがアドレス可能なアセットとして設定されている必要があります。

結果

Mainロード成功
シーンのアンロード成功

参考

アドレスされたアセットの名前を使う方法

Mainシーンのアセットをプロジェクトウィンドウから選択した時のインスペクターウィンドウで、Addressableにチェックを入れる時の名前によってもロードすることができます

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    public string SceneAddress; // アドレス名を保持する変数
    AsyncOperationHandle<SceneInstance> handle;
    bool unloaded;

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }

    private void Start()
    {
        Addressables.LoadSceneAsync(SceneAddress, LoadSceneMode.Additive).Completed += SceneLoadComplete;
    }

    void SceneLoadComplete(AsyncOperationHandle<SceneInstance> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log(obj.Result.Scene.name + "ロード成功");
            handle = obj;
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.X) && !unloaded)
        {
            unloaded = true;
            UnloadScene();
        }
    }

    void UnloadScene()
    {
        Addressables.UnloadSceneAsync(handle, true).Completed += op =>
        {
            if (op.Status == AsyncOperationStatus.Succeeded)
            {
                Debug.Log("シーンのアンロード成功");
            }
        };
    }
}

Addressable,Unity

Posted by hidepon