Getting New Error: ArgumentNullException: Value cannot be null

I don’t think this has been asked about this specifically yet but I seem to be getting an error when I try to load from hitting Play or switching scenes now that I have equipment that actually swaps the Player’s weapons. The items work; they can be picked up and do seem to swap into the player’s hands correctly, but there is some sort of issue with the dictionary key that I don’t fully understand. Here is the full error:

ArgumentNullException: Value cannot be null.
Parameter name: key
System.Collections.Generic.Dictionary2[TKey,TValue].FindEntry (TKey key) (at <1f66344f2f89470293d8b67d71308c07>:0) System.Collections.Generic.Dictionary2[TKey,TValue].ContainsKey (TKey key) (at <1f66344f2f89470293d8b67d71308c07>:0)
RPG.Saving.Inventories.InventoryItem.GetFromID (System.String itemID) (at Assets/OurScripts/InventorySystem/InventoryItem.cs:53)
RPG.Saving.Inventories.Inventory.RPG.Saving.ISaveable.RestoreState (System.Object state) (at Assets/OurScripts/InventorySystem/Inventory.cs:248)
RPG.Saving.SaveableEntity.RestoreState (System.Object state) (at Assets/OurScripts/Saving/SaveableEntity.cs:39)
RPG.Saving.SavingSystem.RestoreState (System.Collections.Generic.Dictionary`2[TKey,TValue] state) (at Assets/OurScripts/Saving/SavingSystem.cs:85)
RPG.Saving.SavingSystem.Load (System.String saveFile) (at Assets/OurScripts/Saving/SavingSystem.cs:35)
RPG.Saving.SavingWrapper.Load () (at Assets/OurScripts/Saving/SavingWrapper.cs:49)
RPG.SceneManagement.Gate+d__8.MoveNext () (at Assets/OurScripts/SceneManagement/Gate.cs:60)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <4014a86cbefb4944b2b6c9211c8fd2fc>:0)

The script it is referring immediately to is as follows (and I think untouched from what Sam gave us):

using System;

using System.Collections.Generic;

using UnityEngine;

namespace RPG.Saving.Inventories

{

/// <summary>

/// A ScriptableObject that represents any item that can be put in an

/// inventory.

/// </summary>

/// <remarks>

/// In practice, you are likely to use a subclass such as `ActionItem` or

/// `EquipableItem`.

/// </remarks>

public abstract class InventoryItem : ScriptableObject, ISerializationCallbackReceiver

{

    // CONFIG DATA

    [Tooltip("Auto-generated UUID for saving/loading. Clear this field if you want to generate a new one.")]

    [SerializeField] string itemID = null;

    [Tooltip("Item name to be displayed in UI.")]

    [SerializeField] string displayName = null;

    [Tooltip("Item description to be displayed in UI.")]

    [SerializeField][TextArea] string description = null;

    [Tooltip("The UI icon to represent this item in the inventory.")]

    [SerializeField] Sprite icon = null;

    [Tooltip("The prefab that should be spawned when this item is dropped.")]

    [SerializeField] Pickup pickup = null;

    [Tooltip("If true, multiple items of this type can be stacked in the same inventory slot.")]

    [SerializeField] bool stackable = false;

    // STATE

    static Dictionary<string, InventoryItem> itemLookupCache;

    // PUBLIC

    /// <summary>

    /// Get the inventory item instance from its UUID.

    /// </summary>

    /// <param name="itemID">

    /// String UUID that persists between game instances.

    /// </param>

    /// <returns>

    /// Inventory item instance corresponding to the ID.

    /// </returns>

    public static InventoryItem GetFromID(string itemID)

    {

        if (itemLookupCache == null)

        {

            itemLookupCache = new Dictionary<string, InventoryItem>();

            var itemList = Resources.LoadAll<InventoryItem>("");

            foreach (var item in itemList)

            {

                if (itemLookupCache.ContainsKey(item.itemID))

                {

                    Debug.LogError(string.Format("Looks like there's a duplicate GameDevTV.UI.InventorySystem ID for objects: {0} and {1}", itemLookupCache[item.itemID], item));

                    continue;

                }

                itemLookupCache[item.itemID] = item;

            }

        }

        if (itemID == null || !itemLookupCache.ContainsKey(itemID)) return null;

        return itemLookupCache[itemID];

    }

   

    /// <summary>

    /// Spawn the pickup gameobject into the world.

    /// </summary>

    /// <param name="position">Where to spawn the pickup.</param>

    /// <param name="number">How many instances of the item does the pickup represent.</param>

    /// <returns>Reference to the pickup object spawned.</returns>

    public Pickup SpawnPickup(Vector3 position, int number)

    {

        var pickup = Instantiate(this.pickup);

        pickup.transform.position = position;

        pickup.Setup(this, number);

        return pickup;

    }

    public Sprite GetIcon()

    {

        return icon;

    }

    public string GetItemID()

    {

        return itemID;

    }

    public bool IsStackable()

    {

        return stackable;

    }

   

    public string GetDisplayName()

    {

        return displayName;

    }

    public string GetDescription()

    {

        return description;

    }

    // PRIVATE

   

    void ISerializationCallbackReceiver.OnBeforeSerialize()

    {

        // Generate and save a new UUID if this is blank.

        if (string.IsNullOrWhiteSpace(itemID))

        {

            itemID = System.Guid.NewGuid().ToString();

        }

    }

    void ISerializationCallbackReceiver.OnAfterDeserialize()

    {

        // Require by the ISerializationCallbackReceiver but we don't need

        // to do anything with it.

    }

}

}

Seemed to have solved this issue after noting @SimoninSD82 had a similar issue. The issue seems to have resolved itself when I manually deleted the IDs of the weapon scriptable objects and had new ones generate in their place. Not sure why this happened though; there were IDs already there. I guess something about converting them to work with the inventory system caused some jank?

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms