docs.unity3d.com
    目次を表示する/隠す

    同期ワークフロー

    同期的な Addressables API を使用すると、Unity のアセットロードのワークフローをより厳密にミラーできます。現在、AsyncOperationHandles には WaitForCompletion() というメソッドがあります。これは、非同期操作の完了を強制し、操作の Result を返します。

    API

    TObject WaitForCompletion()

    結果

    WaitForCompletion の結果は、呼び出された非同期操作の Result です。操作が失敗した場合は、default(TObject) が返されます。

    操作が失敗しなかった場合でも、結果として default(TObject) が取得されることがあります。これには、完了と同時に AsyncOperationHandles を自動的に解放する非同期操作が該当します。Addressables.InitializeAsync() やその他の API で autoReleaseHandle パラメーターが true に設定されている場合は、操作自体が成功していても default(TObject) が返されます。

    パフォーマンス

    WaitForCompletion の呼び出しは、Resources.Load または Instantiate 呼び出しと直接比較すると、ランタイムのパフォーマンスに影響が生じる場合があることに注意してください。AssetBundle がローカルの場合、または以前にダウンロードされてキャッシュされている場合は、このパフォーマンスへの影響は無視できる可能性があります。ただし、個々のプロジェクトの設定によっては影響が大きくなる場合もあります。

    いずれかのアセットロード操作で WaitForCompletion が呼び出されると、現在アクティブなアセットロード操作がすべて完了するまで待機します。この理由は、エンジンでの非同期操作の処理方法にあります。想定外のストールを回避するために、WaitForCompletion を使用するのは、現在の操作の数がわかっていて、すべてのアクティブな操作を同期的に完了させようとしている場合にしてください。

    WaitForCompletion の使用時には、パフォーマンスへの影響が発生します。バージョン 2021.2.0 以降を使用している場合の影響は最小限です。それより前のバージョンを使用している場合は、遅延が発生する可能性があり、その長さは、WaitForCompletion が呼び出されたときにロード中のエンジンでのアセットロード呼び出しの数に比例します。

    リモート AssetBundle のフェッチとダウンロードを行う操作で WaitForCompletion を呼び出すことは推奨されません。ただし、特定の状況に適している場合は呼び出すことも可能です。

    サンプルコード

    void Start()
    {
        //ゲームオブジェクトの同期ロードを強制する基本的なユースケース
        var op = Addressables.LoadAssetAsync<GameObject>("myGameObjectKey");
        GameObject go = op.WaitForCompletion();
    
        //処理を実行...
    
        Addressables.Release(op);
    }
    

    シーン

    エンジンの制限により、シーンを同期的に完了させることはできません。Addressables.LoadSceneAsync から返された操作に対して WaitForCompletion を呼び出すと、activateOnLoad が true に設定されていても、シーンが完全にはロードされません。依存関係とアセットが完了するまでは待機できますが、シーンのアクティベーションは非同期で行う必要があります。これは、sceneHandle を使用するか、以下に示すように、SceneInstance の ActivateAsync から返される AsyncOperation を使用することで実現できます。

    IEnumerator LoadScene(string myScene)
    {
        var sceneHandle = Addressables.LoadSceneAsync(myScene, LoadSceneMode.Additive);
        SceneInstance sceneInstance = sceneHandle.WaitForCompletion();
        yield return sceneInstance.ActivateAsync();
    
        //処理を実行... この時点でシーンは完了して統合済み
    }
    
    Note

    シーンのアンロードを同期的に完了させることはできません。シーンのアンロードに対して WaitForCompleted を呼び出しても、シーンとアセットはいずれもアンロードされず、コンソールのログに警告が表示されます。

    Note

    SceneManager API によるメインスレッドでのシーン統合の制限により、シーンのロードに関連して WaitForCompletion を呼び出すと、エディターまたはプレイヤーがロックされる可能性があります。この問題は主に、2 つのシーンを連続してロードし、2 番目のシーンのロードリクエストで、その AsyncOperationHandle から WaitForCompletion が呼び出されたときに発生します。シーンのロードには、メインスレッドに完全に統合するための追加フレームが必要ですが、メインスレッドは WaitForCompletion によってロックされているため、必要な操作がすべて完了していないにもかかわらず、最初のシーンが完全にロードされたことが SceneManager から Addressables に通知されることがあります。この時点でシーンは完全にロードされていますが、Single (単一) モードでシーンがロードされた場合、SceneManager はメインスレッドで UnloadUnusedAssets を呼び出そうとします。その後、2 番目のシーンのロードリクエストによってメインスレッドが WaitForCompletion でロックされますが、ロードは開始できません。これは SceneManager が、次のシーンのロードを開始する前に UnloadUnusedAssets の完了を要求するためです。 この行き詰まりを回避するために、連続するシーンは非同期でロードするか、シーンロードリクエスト間に十分な遅延を確保することを推奨します。

    カスタム操作を使用する同期的な Addressables

    Addressables では、InvokeWaitForCompletion の独自の実装をサポートするカスタム AsyncOperation がサポートされています。このメソッドをオーバーライドして、カスタム同期操作を実装することができます。

    カスタム操作は、ChainOperation および GroupsOperation と併用できます。連結された操作を同期的に完了させる必要がある場合は、カスタム操作に InvokeWaitForCompletion を実装し、そのカスタム操作を使用して ChainOperation を作成します。同様に、GroupOperation は、カスタム操作などの AsyncOperation のコレクションをまとめて完了させるのに適しています。ChainOperation と GroupOperation はどちらも、独自の InvokeWaitForCompletion を実装しています。これらの実装は、依存先の操作が実装している InvokeWaitForCompletion に依存しています。

    WebGL

    WebGL は WaitForCompletion をサポートしていません。WebGL では、すべてのファイルがウェブリクエストを使用してロードされます。他のプラットフォームでは、ウェブリクエストはバックグラウンドスレッドで開始され、ウェブリクエストの終了を待つ間、メインスレッドでは何度も反復する小さいループが実行されます。これが、ウェブリクエストが使用されたときの Addressables での WaitForCompletion の動作です。

    WebGL はシングルスレッドであるため、この小さいループによってウェブリクエストがブロックされ、操作は終了できなくなります。ウェブリクエストが作成元と同じフレームで終了する場合は、WaitForCompletion が問題になることはありません。ただし、これは保証されず、ほとんどの場合は該当しないと考えられます。

    トップに戻る
    Copyright © 2023 Unity Technologies — 商標と利用規約
    • 法律関連
    • プライバシーポリシー
    • クッキー
    • 私の個人情報を販売または共有しない
    • Your Privacy Choices (Cookie Settings)