null ref error when removing items from inventory

forzabo

Member
I'm trying to drop the ammo from a weapon when it is unequipped. I'm getting stuck on a null ref error that fires whenever I do the remove. Here's my crufty code:

C#:
   public ItemType old_itemType = null;
    void OnEquipItem(Item new_item, int slotId) {
        Debug.Log("Player equipped " + new_item.name + "slot " + slotId);

        var inventory = player.GetComponent<InventoryBase>();
        if (inventory == null)
        {
            return;
        }

        if(old_itemType != null) {
            Debug.Log("Removing...");
            inventory.RemoveItem(old_itemType, 0, false);
        } else {
            Debug.Log("not Removing...");

        }

        var item = inventory.GetItem(slotId);
        if (item != null)
        {
            var itemActions = item.ItemActions;
            for (int i = 0; i < itemActions.Length; ++i)
            {
                Debug.Log(itemActions[i].name);
                var usableItem = itemActions[i] as Opsive.UltimateCharacterController.Items.Actions.IUsableItem;
                if (usableItem != null)
                {
                    Debug.Log(usableItem.GetConsumableItemType().name);
                    Debug.Log(usableItem.GetConsumableItemTypeCount());

                    var itemType = usableItem.GetConsumableItemType();
                    inventory.PickupItemType(itemType, Globals.instance.cash, -1, true, false);
                }
            }
        }
        else { Debug.Log("no item"); }
    }

    void OnUnequipItem(Item old_item, int slotId)
    {
        Debug.Log("Player unequipped " + old_item.name + "slot " + slotId);
        var itemActions = old_item.ItemActions;
        for (int i = 0; i < itemActions.Length; ++i)
        {
            Debug.Log(itemActions[i].name);
            var usableItem = itemActions[i] as Opsive.UltimateCharacterController.Items.Actions.IUsableItem;
            if (usableItem != null)
            {
                Debug.Log("huh ?");
                old_itemType = usableItem.GetConsumableItemType();
                Debug.Log(usableItem.GetConsumableItemTypeCount());
                Globals.instance.cash += usableItem.GetConsumableItemTypeCount();
                usableItem.SetConsumableItemTypeCount(0);

            }
        }
    }

and here's the stack trace:
Code:
NullReferenceException: Object reference not set to an instance of an object
Opsive.UltimateCharacterController.Character.Abilities.Items.EquipUnequip.OnRemoveItem (Opsive.UltimateCharacterController.Items.Item item, System.Int32 slotID) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/EquipUnequip.cs:1000)
Opsive.UltimateCharacterController.Events.InvokableAction`2[T1,T2].Invoke (T1 arg1, T2 arg2) (at Assets/Opsive/UltimateCharacterController/Scripts/Events/InvokableAction.cs:132)
Opsive.UltimateCharacterController.Events.EventHandler.ExecuteEvent[T1,T2] (System.Object obj, System.String eventName, T1 arg1, T2 arg2) (at Assets/Opsive/UltimateCharacterController/Scripts/Events/EventHandler.cs:450)
Opsive.UltimateCharacterController.Inventory.InventoryBase.RemoveItem (Opsive.UltimateCharacterController.Inventory.ItemType itemType, System.Int32 slotID, System.Boolean drop) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:539)
LevelManager.OnEquipItem (Opsive.UltimateCharacterController.Items.Item new_item, System.Int32 slotId) (at Assets/Scripts/LevelManager.cs:77)
Opsive.UltimateCharacterController.Events.InvokableAction`2[T1,T2].Invoke (T1 arg1, T2 arg2) (at Assets/Opsive/UltimateCharacterController/Scripts/Events/InvokableAction.cs:132)
Opsive.UltimateCharacterController.Events.EventHandler.ExecuteEvent[T1,T2] (System.Object obj, System.String eventName, T1 arg1, T2 arg2) (at Assets/Opsive/UltimateCharacterController/Scripts/Events/EventHandler.cs:450)
Opsive.UltimateCharacterController.Inventory.InventoryBase.EquipItem (Opsive.UltimateCharacterController.Inventory.ItemType itemType, System.Int32 slotID, System.Boolean immediateEquip) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:363)
Opsive.UltimateCharacterController.Character.Abilities.Items.EquipUnequip.ItemEquip (System.Int32 slotID, System.Boolean canUpdate) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/EquipUnequip.cs:871)
Opsive.UltimateCharacterController.Character.Abilities.Items.EquipUnequip.Update () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/EquipUnequip.cs:568)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdateAbilities (Opsive.UltimateCharacterController.Character.Abilities.Ability[] abilities) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:768)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdateUltimateLocomotion () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:696)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.Move (System.Single horizontalMovement, System.Single forwardMovement, System.Single deltaYawRotation) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:469)
Opsive.UltimateCharacterController.Game.KinematicObjectManager+KinematicCharacter.FixedMove (System.Boolean manualMove) (at Assets/Opsive/UltimateCharacterController/Scripts/Game/KinematicObjectManager.cs:202)
Opsive.UltimateCharacterController.Game.KinematicObjectManager.FixedUpdate () (at Assets/Opsive/UltimateCharacterController/Scripts/Game/KinematicObjectManager.cs:751)


Error occurs here, line 1000 of EquipUnequip.cs if (item.itemType.... etc:
Code:
 /// <summary>
        /// An item has been removed.
        /// </summary>
        /// <param name="item">The item that was removed.</param>
        /// <param name="slotID">The slot that the item was removed from.</param>
        private void OnRemoveItem(Item item, int slotID)
        {
            if (item.ItemType.CategoryIDMatch(m_ItemSetCategoryID)) {
                // The item may not be included in the active ItemSet.
                if (m_ActiveItemSetIndex == m_ItemSetManager.GetItemSetIndex(item, m_ItemSetCategoryIndex, false, true)) {
                    var prevImmediateEquipUnequip = m_ImmediateEquipUnequip;
                    // If the ItemSet contains an item that isn't being removed then the character should animate moving to the next ItemSet.
                    for (int i = 0; i < m_Inventory.SlotCount; ++i) {
                        var equipItemType = m_ItemSetManager.GetEquipItemType(m_ItemSetCategoryIndex, m_ActiveItemSetIndex, i);
                        if (equipItemType != null && equipItemType != item.ItemType) {
                            m_ImmediateEquipUnequip = false;
                            break;
                        }
                    }
                    StartEquipUnequip(m_ItemSetManager.GetDefaultItemSetIndex(m_ItemSetCategoryIndex), true, true);
                    m_ImmediateEquipUnequip = prevImmediateEquipUnequip;
                }
            }
        }
 
PS I added a null check before the if... clause and it seems to work as I want ... but that's probably not an optimum solution...
 
What is null when the exception is thrown? item.ItemType?

It looks like you are also trying to remove the item as it is being equipped? If you are just trying to remove the consumable item type when the weapon is unequipped you should be able to do everything within OnUnequipItem instead of using OnEquipItem.
 
Top