コガネブログ

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

【Unity】Addressable Asset System で DontDestroyOnLoad したゲームオブジェクトが参照しているアセットやスクリプトが Missing になってしまう現象の対応方法

概要

Note: If you mark a GameObject in an Addressable loaded scene as DontDestroyOnLoad or move it to another loaded Scene and then unload your original Scene, all dependencies for your GameObject are still unloaded.

If you find yourself in that scenario there are a couple options at your disposal.

Make the GameObject you want to be DontDestroyOnLoad a single Addressable prefab. Instantiate the prefab when you need it and then mark it as DontDestroyOnLoad. Before unloading the Scene that contained the GameObject you mark as DontDestroyOnLoad, call AsyncOperationHandle.Acquire() on the Scene load handle. This increases the reference count on the Scene, and keeps it and its dependencies loaded until Release is called on the acquired handle.

 

Note: Addressable ロードされたシーンの GameObject を DontDestroyOnLoad としてマークしたり、別のロードされたシーンに移動してから元のシーンをアンロードすると、GameObject のすべての依存関係はアンロードされたままになります。

そのようなシナリオに陥った場合、自由に使えるオプションがいくつかあります。

DontDestroyOnLoad にしたい GameObject を単一の Addressable プレハブにする。必要なときにプレハブをインスタンス化し、DontDestroyOnLoad としてマークします。 DontDestroyOnLoad としてマークした GameObject を含む Scene をアンロードする前に、 Scene ロードハンドルで AsyncOperationHandle.Acquire() を呼び出します。これにより、Scene の参照カウントが増加し、取得したハンドルで Release が呼び出されるまで、Scene とその依存関係がロードされたままになります。

  • 例えばシーン内のルートオブジェクトに DontDestroyOnLoad を適用することで
    そのシーンのルートオブジェクトを常駐させたい場合、
    Addressable Asset System で読み込むとシーン読み込み直後は問題ないが、
    シーン遷移後にそのゲームオブジェクトが参照しているアセットやスクリプトが
    すべて Missing になる
  • これを避けるためには DontDestroyOnLoad したいゲームオブジェクトを
    プレハブにするか、シーン読み込みに使用した AsyncOperationHandle を
    Addressables.ResourceManager.Acquire に渡す必要がある
// ResourceManager.Acquire は参照カウンタを増やす関数
Addressables.ResourceManager.Acquire( m_handle );

参考サイト様