Issue with last throwable item (UCC/UIS)

ChristianWiele

Active member
Hi,

I am working on integrating UCC/UIS with the PUN add-on and ran into an issue with the throwable objects. You can recreate the issue on the demo scene where it doesn't seem to have consequences.

- start the demo scene and equip the 5 grenades from the inventory (default loadout).
- for the first 4 grenades the m_Thrown variable in line 622 of ThrowableItem.cs is true when the StopItemUse() method is called. Everything is correct, as the grenade has been thrown.
- for the last grenade m_Thrown is false when StopItemUse() is called. The reason is that the inventory forces a stop as the item amount has reached 0, but before the item has actually been thrown.

As a consequence, another ThrowItem() is issued, which causes a duplicate key exception when the script tries to spawn the grenade in line 541.

Is there any option to postpone the forced stop by the inventory til after the item has been thrown?

Unity 2020.3
UCC 2.3.2
UIS 1.1.7
PUN add-on 1.1.11

Here's the full trace from my object:

Code:
ArgumentException: An item with the same key has already been added. Key: BloodOrangeThrowableObject PUN(Clone) (UnityEngine.GameObject)
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) (at <695d1cc93cca45069c528c15c9fdd749>:0)
Opsive.UltimateCharacterController.AddOns.Multiplayer.PhotonPun.Game.PunObjectPool.NetworkSpawnInternal (UnityEngine.GameObject original, UnityEngine.GameObject instanceObject, System.Boolean sceneObject) (at Assets/Opsive/UltimateCharacterController/Add-Ons/Multiplayer/PhotonPUN/Scripts/Game/PunObjectPool.cs:119)
Opsive.UltimateCharacterController.Networking.Game.NetworkObjectPool.NetworkSpawn (UnityEngine.GameObject original, UnityEngine.GameObject instanceObject, System.Boolean sceneObject) (at Assets/Opsive/UltimateCharacterController/Scripts/Networking/NetworkObjectPool.cs:53)
Opsive.UltimateCharacterController.Items.Actions.ThrowableItem.ThrowItem () (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Actions/ThrowableItem.cs:541)
Opsive.UltimateCharacterController.Items.Actions.ThrowableItem.StopItemUse () (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Actions/ThrowableItem.cs:623)
Opsive.UltimateCharacterController.Character.Abilities.Items.Use.AbilityStopped (System.Boolean force) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/Use.cs:866)
Opsive.UltimateCharacterController.Character.Abilities.Ability.StopAbility (System.Boolean force, System.Boolean fromController) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Ability.cs:692)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.TryStopAbility (Opsive.UltimateCharacterController.Character.Abilities.Ability ability, System.Boolean force) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1440)
Opsive.UltimateCharacterController.Character.Abilities.Items.EquipUnequip.StartEquipUnequip (System.Int32 itemSetIndex, System.Boolean forceEquipUnequip, System.Boolean immediateEquipUnequip) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/EquipUnequip.cs:416)
Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.CharacterInventoryBridge.Equip (System.Int32 categoryIndex, System.Int32 itemSetIndex, System.Boolean forceEquipUnequip, System.Boolean immediateEquipUnequip) (at Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Scripts/CharacterInventoryBridge.cs:525)
Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing.UnequipIfActive (Opsive.UltimateCharacterController.Items.Item characterItem, System.Boolean immediate) (at Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Scripts/BridgeEquippableProcessing.cs:382)
Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing.OnItemRemovedFromEquippable (Opsive.UltimateInventorySystem.Core.DataStructures.ItemInfo itemInfo, System.Boolean immediateRemove) (at Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Scripts/BridgeEquippableProcessing.cs:336)
Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.BridgeEquippableProcessing.OnRemoveItemFromInventory (Opsive.UltimateInventorySystem.Core.DataStructures.ItemInfo itemInfoRemoved) (at Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Scripts/BridgeEquippableProcessing.cs:786)
Opsive.Shared.Events.InvokableAction`1[T1].Invoke (T1 arg1) (at <27da9e1afec54f2fb2a11d46a234f9df>:0)
Opsive.Shared.Events.EventHandler.ExecuteEvent[T1] (System.Object obj, System.String eventName, T1 arg1) (at <27da9e1afec54f2fb2a11d46a234f9df>:0)
Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemCollection.RemoveInternal (Opsive.UltimateInventorySystem.Core.DataStructures.ItemInfo itemInfo) (at Assets/Opsive/UltimateInventorySystem/Scripts/Core/InventoryCollections/ItemCollection.cs:598)
Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemSlotCollection.RemoveItem (System.Int32 slotIndex, System.Int32 amount) (at Assets/Opsive/UltimateInventorySystem/Scripts/Core/InventoryCollections/ItemSlotCollection.cs:297)
Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemSlotCollection.RemoveItem (Opsive.UltimateInventorySystem.Core.DataStructures.ItemInfo itemInfo) (at Assets/Opsive/UltimateInventorySystem/Scripts/Core/InventoryCollections/ItemSlotCollection.cs:320)
Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemCollection.RemoveItem (Opsive.UltimateInventorySystem.Core.Item item, System.Int32 amount) (at Assets/Opsive/UltimateInventorySystem/Scripts/Core/InventoryCollections/ItemCollection.cs:689)
Opsive.UltimateCharacterController.Integrations.UltimateInventorySystem.CharacterInventoryBridge.AdjustItemIdentifierAmountInternal (Opsive.Shared.Inventory.IItemIdentifier itemIdentifier, System.Int32 amount) (at Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Scripts/CharacterInventoryBridge.cs:802)
Opsive.UltimateCharacterController.Inventory.InventoryBase.AdjustItemIdentifierAmount (Opsive.Shared.Inventory.IItemIdentifier itemIdentifier, System.Int32 amount) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:473)
Opsive.UltimateCharacterController.Items.Actions.ThrowableItem.UseItem () (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Actions/ThrowableItem.cs:479)
Opsive.UltimateCharacterController.Character.Abilities.Items.Use.LateUpdate () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/Use.cs:638)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.LateUpdateActiveAbilities (Opsive.UltimateCharacterController.Character.Abilities.Ability[] abilities, System.Int32& abilityCount) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1042)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.LateUpdateUltimateLocomotion () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1028)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdatePositionAndRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:843)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdatePositionAndRotation (System.Boolean fromAnimatorMove) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:517)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.OnAnimatorMove () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:1453)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.OnAnimatorMove () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1772)
 
I found a simple fix that you hopefully can apply to the source code: You only need to set m_Thrown to true before updating the inventory

Instead of kin 477 - 481 of ThrowableItem
Code:
            ThrowItem();
            if (m_Inventory != null && !m_InfiniteUse) {
                m_Inventory.AdjustItemIdentifierAmount(m_Item.ItemIdentifier, -1);
            }
            m_Thrown = true;

Set it to
Code:
            ThrowItem();
            m_Thrown = true;
            if (m_Inventory != null && !m_InfiniteUse) {
                m_Inventory.AdjustItemIdentifierAmount(m_Item.ItemIdentifier, -1);
            }
 
Thanks for debugging. This looks related to your other post:


I've made the change so m_Thrown gets set within ThrowItem.
 
Top