Search Unity

Pink objects in iOS Pack mode

Discussion in 'Addressables' started by n-gist, Aug 11, 2018.

  1. n-gist

    n-gist

    Joined:
    Mar 7, 2016
    Posts:
    41
    Hi, thanks for developing nice package!
    Got this issue. I made one prefab addressable. No matter what material on it, and no matter is material addressable or not, I got object pink if i run it in iOS Packed mode. Fast and Virtual is ok. Fast, Virtual and Packed on Windows is ok. Running in Editor. Tried to change Graphics Emulation settings, didnt helped. Code is regular:

    Code (CSharp):
    1. var characterLoadOperation = SETTINGS.character.character.LoadAsset<GameObject>();
    2. yield return characterLoadOperation;
    3. GameObject loadedCharacter = characterLoadOperation.Result;
    4. characterLoadOperation.Release();
    5. Main.gameObject = Object.Instantiate(loadedCharacter);
     
  2. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
  3. n-gist

    n-gist

    Joined:
    Mar 7, 2016
    Posts:
    41
    This makes sense, thank you.
     
  4. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    Could work (not necessarily), because the editor cheats (explained somewhere, forgot where). Also you're referring to really old documentation. In the editor it might work, outside the editor not.
    But this is the addressable asset system, it takes care of building and loading the bundles for you, so you won't have this problem and the bundles of the appropriate platform target should be loaded.

    So I rather suspect his problem lays in line 4 where the operation is released. Not sure what the method does but if it is an asset release, yeah that would be bad. The asset would be unloaded.

    If the
    SETTINGS.character.character
    is of type
    AssetReferenceGameObject
    why not just use the
    Instantiate<GameObject>()
    method?
    It instantiates the game object after it is done loading. The addressable asset system will handle all the dependencies and stuff for you.
    You can get the GameObject from the IAsyncOperation its Result property.

    In this case you could do something like:

    Code (CSharp):
    1. var characterLoadOperation = SETTINGS.character.character.Instantiate<GameObject>();
    2. yield return characterLoadOperation;
    3. Main.gameObject = characterLoadOperation.Result;
     
  5. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    This is true, and the fact that the symptom is pink textures makes this likely the cause. Bad shaders will render pink.

    That Release call is on the operation, not the asset. Releasing the operation just allows our system to reuse it, reducing garbage collection. It won't affect the asset itself.

    A good question. Remember, that each time you have Addressables do a thing (load or instantiate), we keep a reference count. In the code sample, the loaded asset is stored in a local variable, then instantiated manually. This means we'll have a ref count on the asset, but not the instance. Calling ReleaseInstance would not decrement the count. Instead ReleaseAsset must be called. So that code should either store that loaded asset in a safe place, or call Addressables.Instantiate to properly ref count.
     
  6. n-gist

    n-gist

    Joined:
    Mar 7, 2016
    Posts:
    41
    Hi, answering questions (little bit offtopic).
    I am not using Instantiate directly just because I want more control. In the code i wrote here it looks like I do it just after loading, but it is because I skipped some lines.
    First reason is performance spike, caused by instantiating objects. I want to control, when it will be. Until parallel simulation worlds (or, whatever will it be named) will be released, when we will be able instantiate without spikes.
    Second is, maybe i will edit my object in code, so just keeping a link to have ability to reinstantiate original one (just for a case).
    Third is, Instantiating makes object name "(Clone)" appendix, im using asset link to make names clear like this:
    Code (CSharp):
    1. Main.gameObject = Object.Instantiate(loadedCharacter);
    2. Main.gameObject.name = loadedCharacter.name;
    And yes, I am releasing loaded asset after all of this
    Code (CSharp):
    1. Addressables.ReleaseAsset(loadedCharacter);
    2. loadedCharacter = null;
    Nice to have such discussions about little details like this, thanks for attention =)
     
  7. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Seems totally reasonable to me. Thanks for trying out the system.