Equipping empty weapon with UIS integration wipes clipsize ammo from inventory

Zaddo

Member
I have a problem with inventory dissapearing when equipping an empty weapon with UIS integration. I have included the full stack to show the sequence of how this occurs.

When the empty weapon is equipped, if there is matching Ammo in the inventory, the clipsize is consumed, but it does not get loaded into the weapons clip. It just dissapears.

I think the problem is in the ShootableWeapon.cs script, SetAmmoToshootableWeapon. This calls SetConsumableItemIdentifer which calls ReloadItem that triggers the inventory to be consumed. But when this returns to SetAmmoToShootableWeapon, the ammo amount is set to the ClipRemaining, which wipes the inventory that was just consumed. I don't think that SetConsumableItemIdentifier should call ReloadItem in this situation? (Note, auto-reload is set to nothing, so ShootableWeapon should never try to reload automatically, regardless)

You can see in the stack, this all gets triggered initially via the BridgeEquippableProcessing line 242 when it sets the item info.

In SetConsumableItemIdentifier, the method would return without doing the reload if this evaluated to true: (m_ConsumableItemIdentifier == itemIdentifier) Which led me to think my ShootableWeapon component on the prefab was not setup correctly. But looking at component below, it looked ok? In fact in the ShootableWeapon Awake it changes the value of m_ConsumableItemIdentifier from the value it initialises with to a new value. The initialised value would have matched the evaluation above?

C#:
            if (m_ConsumableItemDefinition != null) {
                m_ConsumableItemIdentifier = m_ConsumableItemDefinition.CreateItemIdentifier();
            }

Thanks in advance for your help. As always, I tried to track the problem down before posting, but I am lost.

I just upgraded to latest versions (But I think this problem was there before and I was just ignoring it)
UIS Version: 1.2
UCC Version: 2.4

1633950519000.png


C#:
    private void SetAmmoToShootableWeapon(AmmoData value)
    {
        if (value.ItemDefinition != null) {
            m_ShootableWeapon.SetConsumableItemIdentifier(value.ItemDefinition.DefaultItem);
        }
 
        m_ShootableWeapon.SetConsumableItemIdentifierAmount(value.ClipRemaining);
        m_ShootableWeapon.ClipSize = value.ClipSize;
    }

        public override void SetConsumableItemIdentifier(IItemIdentifier itemIdentifier)
        {
            if (m_ConsumableItemIdentifier == itemIdentifier) {
                return;
            }

            // Add back the previous consumable item to the inventory.
            m_Inventory.AdjustItemIdentifierAmount(m_ConsumableItemIdentifier, ClipRemaining);

            m_ConsumableItemIdentifier = itemIdentifier;
            m_ConsumableItemDefinition = itemIdentifier.GetItemDefinition();
            // Set the ClipRemaining to 0 so the new consumable item can be loaded from the inventory.
            ClipRemaining = 0;

            ReloadItem(false);
        }



Code:
     Int32 Opsive.UltimateInventorySystem.Core.InventoryCollections.BackPackItemCollection:RemoveItemFromStack (Int32, ItemInfo, Int32, Int32, Int32, Int32)+0x22 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\DeadFear\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\BackPackItemCollection.cs:[177:13-177:45]    C#
     ItemInfo Opsive.UltimateInventorySystem.Core.InventoryCollections.BackPackItemCollection:RemoveInternal (ItemInfo)+0x55 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\DeadFear\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\BackPackItemCollection.cs:[129:17-130:101]    C#
     ItemInfo Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemCollection:RemoveItem (ItemInfo)+0x36 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\ItemCollection.cs:[728:13-728:51]    C#
     ItemInfo Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemCollection:RemoveItem (Item, Int32)+0xf at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\ItemCollection.cs:[739:13-739:53]    C#
     Void Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.CharacterInventoryBridge:AdjustItemIdentifierAmountInternal (IItemIdentifier, Int32)+0x8d at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\CharacterInventoryBridge.cs:[889:25-889:75]    C#
     Void Opsive.UltimateCharacterController.Inventory.InventoryBase:AdjustItemIdentifierAmount (IItemIdentifier, Int32)+0x15 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Scripts\Inventory\InventoryBase.cs:[473:13-473:72]    C#
     Void Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon:ReloadItem (Boolean)+0x18c at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Scripts\Items\Actions\ShootableWeapon.cs:[1593:13-1593:95]    C#
     Void Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon:SetConsumableItemIdentifier (IItemIdentifier)+0x46 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Scripts\Items\Actions\ShootableWeapon.cs:[528:13-528:31]    C#
     Void ShootableWeaponAmmoBinding:SetAmmoToShootableWeapon (AmmoData)+0x25 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\ItemBindings\ShootableWeaponAmmoBinding.cs:[66:13-66:93]    C#
     Void ShootableWeaponAmmoBinding:SetItem (Item)+0xcf at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\ItemBindings\ShootableWeaponAmmoBinding.cs:[154:9-154:46]    C#
     Void ShootableWeaponAmmoBinding:SetItem ()+0x1d at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\ItemBindings\ShootableWeaponAmmoBinding.cs:[119:13-119:40]    C#
     Void Opsive.Shared.Events.InvokableAction:Invoke ()+0x6 at :-1    C#
     Void Opsive.Shared.Events.EventHandler:ExecuteEvent (Object, String)+0x28 at :-1    C#
>    Void Opsive.UltimateInventorySystem.Core.ItemObject:SetItem (ItemInfo)+0xc6 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\ItemObject.cs:[137:13-137:84]    C#
     Item Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing:CreateCharacterItem (ItemInfo, Item)+0x51 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\BridgeEquippableProcessing.cs:[242:13-242:42]    C#
     Item Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing:CreateCharacterItem (ItemInfo, GameObject)+0x2b at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\BridgeEquippableProcessing.cs:[223:13-223:80]    C#
     ItemInfo Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing:OnItemAddedToEquippable (ItemInfo, ItemStack)+0x190 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\BridgeEquippableProcessing.cs:[184:17-184:79]    C#
 
Last edited:

Zaddo

Member
Rest of stack. Sits below previous post. There were too many characters to post together.

Code:
     Void Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing:OnAddItemToInventory (ItemInfo, ItemStack)+0x2f at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\BridgeEquippableProcessing.cs:[771:17-771:67]    C#
     Void Opsive.Shared.Events.InvokableAction`2:Invoke (ItemInfo, ItemStack)+0x8 at :-1    C#
     Void Opsive.Shared.Events.EventHandler:ExecuteEvent (Object, String, ItemInfo, ItemStack)+0x2a at :-1    C#
     Void Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemCollection:NotifyAdd (ItemInfo, ItemStack)+0x23 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\ItemCollection.cs:[431:17-433:47]    C#
     Nullable`1 Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemSlotCollection:SetItemAmount (ItemInfo, Int32, Boolean)+0xcf at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\ItemSlotCollection.cs:[276:13-276:59]    C#
     ItemInfo Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemSlotCollection:AddItemInternal (ItemInfo, Int32)+0xe6 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\ItemSlotCollection.cs:[236:13-236:98]    C#
     ItemInfo Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemSlotCollection:AddItem (ItemInfo, Int32)+0x4 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\Core\InventoryCollections\ItemSlotCollection.cs:[200:13-200:70]    C#
     ItemInfo Opsive.UltimateInventorySystem.UI.Panels.Hotbar.ItemSlotCollectionView:AddItem (ItemInfo, Int32)+0x29 at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Panels\Hotbar\ItemSlotCollectionView.cs:[224:13-224:75]    C#
     Void Opsive.UltimateInventorySystem.UI.Item.DragAndDrop.DropActions.ItemViewDropContainerSmartExchangeAction:Drop (ItemViewDropHandler)+0x19b at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Item\DragAndDrop\DropActions\ItemViewDropContainerSmartExchangeAction.cs:[136:21-136:155]    C#
     Void Opsive.UltimateInventorySystem.UI.Item.DragAndDrop.ItemViewDropActionsWithConditions:Drop (ItemViewDropHandler)+0xf at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Item\DragAndDrop\ItemViewSlotDropActionSet.cs:[235:58-235:97]    C#
     Void Opsive.UltimateInventorySystem.UI.Item.DragAndDrop.ItemViewSlotDropActionSet:HandleItemViewSlotDrop (ItemViewDropHandler)+0x1d at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Item\DragAndDrop\ItemViewSlotDropActionSet.cs:[116:13-116:70]    C#
     Void Opsive.UltimateInventorySystem.UI.Item.DragAndDrop.ItemViewDropHandler:HandleItemViewSlotDropInternal ()+0x1b at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Item\DragAndDrop\ItemViewDropHandler.cs:[206:13-206:70]    C#
     Void Opsive.UltimateInventorySystem.UI.Item.DragAndDrop.ItemViewDropHandler:HandleItemViewSlotDrop (ItemViewSlotEventData)+0x6a at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Item\DragAndDrop\ItemViewDropHandler.cs:[195:13-195:46]    C#
     Void <>c__DisplayClass70_0:<Initialize>b__7 (PointerEventData)+0x4c at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\Item\ItemViewSlotsContainerBase.cs:[266:21-266:78]    C#
     Void Opsive.UltimateInventorySystem.UI.CompoundElements.ActionButton:OnDrop (PointerEventData)+0xe at G:\UnityProjects\DeadFear2\DeadFear2\Assets\Opsive\UltimateInventorySystem\Scripts\UI\CompoundElements\ActionButton.cs:[239:13-239:40]    C#
     Void UnityEngine.EventSystems.ExecuteEvents:Execute (IDropHandler, BaseEventData)+0x8 at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.ugui@1.0.0\Runtime\EventSystem\ExecuteEvents.cs:[85:13-85:76]    C#
     Boolean UnityEngine.EventSystems.ExecuteEvents:Execute (GameObject, BaseEventData, EventFunction`1)+0x78 at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.ugui@1.0.0\Runtime\EventSystem\ExecuteEvents.cs:[262:21-262:45]    C#
     GameObject UnityEngine.EventSystems.ExecuteEvents:ExecuteHierarchy (GameObject, BaseEventData, EventFunction`1)+0x31 at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.ugui@1.0.0\Runtime\EventSystem\ExecuteEvents.cs:[288:17-288:80]    C#
     Void UnityEngine.InputSystem.UI.InputSystemUIInputModule:ProcessPointerButton (ButtonState, PointerEventData)+0x1fc at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.inputsystem@1.0.2\InputSystem\Plugins\UI\InputSystemUIInputModule.cs:[388:21-388:105]    C#
     Void UnityEngine.InputSystem.UI.InputSystemUIInputModule:ProcessPointer (PointerModel)+0x13a at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.inputsystem@1.0.2\InputSystem\Plugins\UI\InputSystemUIInputModule.cs:[232:13-232:67]    C#
     Void UnityEngine.InputSystem.UI.InputSystemUIInputModule:Process ()+0x73 at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.inputsystem@1.0.2\InputSystem\Plugins\UI\InputSystemUIInputModule.cs:[1551:21-1551:47]    C#
     Void UnityEngine.EventSystems.EventSystem:Update ()+0xfc at G:\UnityProjects\DeadFear2\DeadFear2\Library\PackageCache\com.unity.ugui@1.0.0\Runtime\EventSystem\EventSystem.cs:[385:17-385:48]    C#
 

Sangemdoko

Moderator
Staff member
Hi Zaddo,

My guess is that this isn't a bug per say. But actually a limitation. If I am correct your problem is similar to this post:

Looking at your screen shot I see that your Ammo is set to "Mutable". All ammo must be Immutable and common. That should ensure there is a single item instance for each ammo definition and no new instances with new IDs will be created automatically by the system.

Then the check consumable Indentifier == item Identifier should return true since there is a single instance.

The reason mutable items isn't a good option for ammo is because you woulnd need to differentiate two ammo instances with different runtime damage values if they have the same definition. Instead you should do the damage changes constants with different Item Definition ammos, or make the weapon itself be the one that chooses the damage amount.

I hope that fixes your issue.
 

Zaddo

Member
Thanks Sangemdoko, That makes sense. I appreciate the quick response.

I had them as mutable because I was assigning an ID to each stack to track inventory in a multi-player environment. This allowed me to update the server as each stack was consumed. Because the server tracked amounts in each stack, I could save and restore a players inventory exactly as they had it from the server.

I will need to rethink how I manage this. Understanding the limitation with mutable is good.

Thanks again :)
 
Top