コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】Addressables でローカルカタログの読み込みに失敗したか確認する例

ソースコード

using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;

public class Example : MonoBehaviour
{
    // ローカルカタログの読み込みに失敗した場合、
    // 以下のようなエラーや例外が発生するのでそれで確認できる
    // RuntimeData is null.  Please ensure you have built the correct Player Content.
    // System.Exception: Invalid path in TextDataProvider : 'Library/com.unity.addressables/aa/XXXX/
    // System.Exception: Unable to load ContentCatalogData from location Library/com.unity.addressables/aa/XXXX/YYYY.json on second attempt.
    // System.Exception: Failed to load content catalog. ---> System.Exception: Unable to load ContentCatalogData from location Library/com.unity.addressables/aa/XXXX/YYYY.json on second attempt.
    // OperationException : ChainOperation failed because dependent operation failed
    private static readonly string[] ERROR_MESSAGES =
    {
        "RuntimeData is null.  Please ensure you have built the correct Player Content.",
        "Invalid path in TextDataProvider : ",
        "Unable to load ContentCatalogData from location ",
        "Failed to load content catalog.",
        "OperationException : ChainOperation failed because dependent operation failed",
    };

    // ゲーム開始時に呼び出されます
    private async void Start()
    {
        // Addressables を初期化します
        await InitializeAsync();
    }

    // Addressables を初期化します
    private static async Task InitializeAsync()
    {
        var isCommunicationError = false;

        // Addressables 内部でエラーや例外が発生した時に呼び出されます
        void OnLogMessageReceivedThreaded( string condition, string trace, LogType type )
        {
            // 既にエラーを検知している場合は無視します
            if ( isCommunicationError ) return;

            // 通常のログと警告ログは無視します
            if ( type == LogType.Log || type == LogType.Warning ) return;

            // ローカルカタログの読み込みに失敗した系のメッセージならエラーとみなします
            isCommunicationError = ERROR_MESSAGES.Any( x => condition.Contains( x ) );

            // Addressables 内部でエラーや例外が発生した時に呼び出される関数を解除します
            Application.logMessageReceivedThreaded -= OnLogMessageReceivedThreaded;
        }

        // Addressables 内部でエラーや例外が発生した時に呼び出される関数を登録します
        Application.logMessageReceivedThreaded += OnLogMessageReceivedThreaded;

        // Addressables を初期化します
        var result = Addressables.InitializeAsync();

        // 初期化が完了するのを待機します
        await result.Task;

        // Addressables 内部でエラーや例外が発生した時に呼び出される関数を解除します
        Application.logMessageReceivedThreaded -= OnLogMessageReceivedThreaded;

        if ( isCommunicationError )
        {
            Debug.LogError( "ローカルカタログの読み込みに失敗しました" );
            return;
        }

        Debug.Log( "成功" );
    }
}