Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

No MergeMode is set to merge the multiple keys requested.

Discussion in 'Addressables' started by markmozza, Jun 21, 2022.

  1. markmozza

    markmozza

    Joined:
    Oct 16, 2015
    Posts:
    86
    Hi,

    Ive been having a weird issues using addressables, which is probably down to my lack of understanding of how it works. I have a simple mono class which takes an AssetReference and loads it on start. It has been fine in Editor (well it was for a while) but on final build the first item on the list failed to load. I couldnt reproduce the issue in Editor until now.

    Code (CSharp):
    1.  
    2. UnityEngine.AddressableAssets.InvalidKeyException: Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown. No MergeMode is set to merge the multiple keys requested. Keys=, Type=UnityEngine.Sprite
    3. UnityEngine.AddressableAssets.Addressables:LoadAssetAsync<UnityEngine.Sprite> (object)
    4. Managers.AddressablesManager/<AddressAsset>d__6`1<UnityEngine.Sprite>:MoveNext () (at Assets/Scripts/Managers/AddressablesManager.cs:42)
    5. UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
    6. Managers.AddressablesManager:GetAssetReference<UnityEngine.Sprite> (UnityEngine.AddressableAssets.AssetReference,ZForward.AddressableManager.AssetManagement.ScriptableObjects.AssetSo/AssetInstantiateType,UnityEngine.Transform,UnityEngine.Events.UnityAction`1<UnityEngine.Sprite>) (at Assets/Scripts/Managers/AddressablesManager.cs:34)
    7. UI.AddressableImageLoader:Start () (at Assets/Scripts/UI/AddressableImageLoader.cs:20)
    8.  
    But heres the weird thing, i use LoadAssetAsync OR InstantiateAsync which does not take MergeMode. Here is my code.

    Code (CSharp):
    1.     public class AddressableImageLoader : MonoBehaviour
    2.     {
    3.         public AssetReference image;
    4.         public Image destination;
    5.         public GameObject loading;
    6.         private bool _isLoadingNotNull;
    7.  
    8.         // Start is called before the first frame update
    9.         private void Start()
    10.         {
    11.             _isLoadingNotNull = loading != null;
    12.             AddressablesManager.Instance.GetAssetReference<Sprite>(image, AssetSo.AssetInstantiateType.Load, null, OnImageLoad);
    13.         }
    14.  
    15.         private void OnImageLoad(Sprite sprite)
    16.         {
    17.             destination.sprite = sprite;
    18.             destination.color = Color.white;
    19.        
    20.             if (_isLoadingNotNull) loading.SetActive(false);
    21.         }
    22.    
    23.     }
    Code (CSharp):
    1. public class AddressablesManager : Singleton<AddressablesManager>
    2.     {
    3.         // How often in seconds to check for catalog update
    4.         public bool checkForUpdates = true;
    5.         public float updateCheckTime = 30f;
    6.         private float _nextActionTime = 0.0f;
    7.    
    8.         private void Start()
    9.         {
    10.             CheckForUpdates();
    11.         }
    12.    
    13.         private void Update()
    14.         {
    15.             if (!checkForUpdates) return;
    16.             if (!(Time.time > _nextActionTime)) return;
    17.             _nextActionTime += updateCheckTime;
    18.             CheckForUpdates();
    19.         }
    20.  
    21.         public void GetAssetReference<T>(AssetReference assetReference, AssetSo.AssetInstantiateType type = AssetSo.AssetInstantiateType.Instantiate, Transform parent = null, UnityAction<T> onSucceed = null)
    22.         {
    23.             StartCoroutine(AddressAsset<T>(assetReference, type, parent, onSucceed));
    24.         }
    25.  
    26.         private static IEnumerator AddressAsset<T>(AssetReference assetReference, AssetSo.AssetInstantiateType type = AssetSo.AssetInstantiateType.Instantiate, Transform parent = null, UnityAction<T> onSucceed = null)
    27.         {
    28.             AsyncOperationHandle handle = type switch
    29.             {
    30.                 AssetSo.AssetInstantiateType.Instantiate => Addressables.InstantiateAsync(assetReference),
    31.                 AssetSo.AssetInstantiateType.Load => Addressables.LoadAssetAsync<T>(assetReference),
    32.                 _ => throw new ArgumentOutOfRangeException()
    33.             };
    34.  
    35.             yield return handle;
    36.        
    37.             if(handle.Status == AsyncOperationStatus.Succeeded)
    38.             {
    39.                 onSucceed?.Invoke((T)handle.Result);
    40.             }
    41.         }
    42.    
    43.         private static void CheckForUpdates()
    44.         {
    45.             Addressables.CheckForCatalogUpdates();
    46.         }
    47.    
    48.         public static void ForceUpdates()
    49.         {
    50.             // We had to update to 1.19.X to get this function
    51.             Addressables.CleanBundleCache();
    52.             CheckForUpdates();
    53.         }
    54.    
    55.     }
    Im really lost to what is causing this. Any help will be appreciated.

    Below is an image of what its doing on Mobile. First run always works fine (All images load fine), as soon as we restartthe app, the top left image, which is first to load, doesnt actually load.

    Capture.PNG
     
    Last edited: Jun 21, 2022
  2. markmozza

    markmozza

    Joined:
    Oct 16, 2015
    Posts:
    86
    So there was multiple issues that i didnt reckonise at first. The errors i was getting above was due to a reference i left over in the scene so it was trying to load twice.

    This however didnt fix the issue of the first image not loading. This issue was due to me trying to update addressable on app start.
    Code (CSharp):
    1. Addressables.CheckForCatalogUpdates();
     
  3. pillakirsten

    pillakirsten

    Unity Technologies

    Joined:
    May 22, 2019
    Posts:
    346
    Hi @markmozza are AddressablesManager.Start() and AddressableImageLoader.Start() running at the same time when the first image is being loaded?

    Addressables has an initialization process that occurs automatically when calling an Addressables API (i.e. LoadAssetAsync or CheckForCatalogUpdates) for the first time. I think what's happening here is that the image is being loaded before initialization has completed.
    https://docs.unity3d.com/Packages/com.unity.addressables@1.20/manual/InitializeAsync.html

    So what you could do is manually call Addressables.InitializeAsync to trigger the initialization process. Once that operation has completed, then try to load the images.
    https://docs.unity3d.com/Packages/c...ddressableAssets_Addressables_InitializeAsync
     
  4. markmozza

    markmozza

    Joined:
    Oct 16, 2015
    Posts:
    86
    Hi @pillakirsten, We resolved the issue now. It was my lack of understanding, it was exactly how you said. Thanks for the update.