Search Unity

SceneLoad making instances null

Discussion in 'Addressables' started by luizbeneton, Aug 22, 2018.

  1. luizbeneton

    luizbeneton

    Joined:
    Apr 8, 2013
    Posts:
    19
    I'm migrating a personal project to test Addressables. I used to have my own Object Pool solution for this project, so I decided to stick with it and use Addressables to load the prefabs only.

    To my surprise, the instances I create using my pool are null when I do a Scene load.
    Is this behavior intended?

    Here is a sample of the code I'm using.

    This would be the main class:
    Code (CSharp):
    1. [SerializeField]
    2. private AssetReference unitDataViewPrefab;
    3.  
    4. private PrefabPoolHelper<UnitDataView> unitPrefabHelper;
    5.  
    6. protected override void PreloadAssets()
    7. {
    8.     unitPrefabHelper = ObjectPool.Get<PrefabPoolHelper<UnitDataView>>();
    9.     unitPrefabHelper.LoadPrefab(unitDataViewPrefab, TryFinishSetup);
    10. }
    11.  
    12. private void TryFinishSetup()
    13. {
    14.     // unrelated code //
    15.  
    16.     // Units
    17.     List<UnitSaveData> _units = initialPlayerSetup.normalSetup.unitData;
    18.     for (int i = 0; i < _units.Count; i++)
    19.     {
    20.         UnitDataView _unitView = unitPrefabHelper.GetNewInstance(unitContainer);
    21.         _unitView.SetInfo(_units[i].persistentData);
    22.     }
    23. }
    Here is how the PrefabHelper class works with Addressables:

    Code (CSharp):
    1. public class PrefabPoolHelper<T> : PoolableClass where T: PoolableMonoBehaviour
    2. {
    3.     private Action OnLoadComplete;
    4.  
    5.     private T prefab;
    6.     private List<T> instances;
    7.  
    8.     private AssetReference assetReference;
    9.  
    10.     public void LoadPrefab(AssetReference pAssetReference, Action pOnComplete = null)
    11.     {
    12.         OnLoadComplete = pOnComplete;
    13.         assetReference = pAssetReference;
    14.  
    15.         assetReference.LoadAsset<T>().Completed += OnAssetReferenceLoaded;
    16.     }
    17.  
    18.     private void OnAssetReferenceLoaded(IAsyncOperation<T> pAsyncOp)
    19.     {
    20.         // In case this was recycled before loading finished
    21.         if (assetReference == null)
    22.             return;
    23.  
    24.         prefab = pAsyncOp.Result;
    25.  
    26.         if (OnLoadComplete != null)
    27.             OnLoadComplete();
    28.         OnLoadComplete = null;
    29.     }
    30.  
    31.  
    32.     public T GetNewInstance(Transform pParent = null, bool pWorldPositionStays = false)
    33.     {
    34.         if(prefab == null)
    35.         {
    36.             LoggerUtil.LogWarning(LoggerTags.ObjectPooling, "Trying to instantiate a null prefab");
    37.             return default(T);
    38.         }
    39.  
    40.         T _instance = ObjectPool.Get<T>(prefab, pParent, pWorldPositionStays);
    41.         instances.Add(_instance);
    42.         return _instance;
    43.     }
    44. }
    What I did was to put a call back on SceneManager.activeSceneChanged to detect a scene change, and to my surprise, items inside "instances" List were all null. There is no way in the code that can nullify items inside that list.
     
  2. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    So are you getting the "Trying to instantiate a null prefab" warning? Or is the prefab loaded, but you're failing to create the instance? I'd recommend doing an if(_instance == null) inside GetNewInstance to make sure you're actually creating the thing.
     
  3. luizbeneton

    luizbeneton

    Joined:
    Apr 8, 2013
    Posts:
    19
    I think I didn't make the issue clear.
    I can load the prefab from an AssetReference no problem (in Editor).
    Then I use my own ObjectPool to create instances, via GameObject.Instantiate() and store them in a list.
    When I do a SceneLoad, the items inside that list are null.
     
  4. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    554
    do you call
    DontDestroyOnLoad
    on the instances?

    if not, the expected behavior is that when you load a scene non-additive, all the existing objects are destroyed, regardless of Addressables
     
  5. luizbeneton

    luizbeneton

    Joined:
    Apr 8, 2013
    Posts:
    19
    Yep, that is usually the case, I just didn't expect it to happen before the callback "activeSceneChanged". I don't think this was the case before Addressables.
    I had to make a SceneManagerHelper, that would call an event OnBeforeSceneChanged so I could recycle my objects before they are destroyed so that my pool is not dirty with old objects.
     
unityunity