Item.EquipItemEvent() First time called GetVisibleObject() throws NullRefernceException

rkeown

Active member
I have a script that's setup in the editor as a Runtime Only Persistent Event Listener. When my game starts, the weapon is automatically equipped, and when the call is Invoked on my listener function, I check make a call to the Item.GetActiveObject(), and it throws a null reference exception. Is this a known bug, or is there a workaround for it?

Its simple code that basically gets the Item component, verifies that it actually exists, and then attempts to get the visible game object using the GetVisibleObject() method.

NullReferenceException: Object reference not set to an instance of an object
Opsive.UltimateCharacterController.Items.Item.GetVisibleObject () (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Item.cs:631)
OTG.Systems.Games.WAS.OpsiveUCC.Items.Connectors.WAS_OpsiveUCCShootableWeaponConnector.OnEquipItem () (at Assets/OTG/Systems/Games/WAS/OpsiveUCC/Items/Connectors/WAS_OpsiveUCCShootableWeaponConnector.cs:252)
UnityEngine.Events.InvokableCall.Invoke () (at <480508088aee40cab70818ff164a29d5>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <480508088aee40cab70818ff164a29d5>:0)
Opsive.UltimateCharacterController.Items.Item.Equip (System.Boolean immediateEquip) (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Item.cs:490)
Opsive.UltimateCharacterController.Inventory.InventoryBase.EquipItem (Opsive.Shared.Inventory.IItemIdentifier itemIdentifier, System.Int32 slotID, System.Boolean immediateEquip) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:354)
Opsive.UltimateCharacterController.Character.Abilities.Items.EquipUnequip.OnPickupItem (Opsive.UltimateCharacterController.Items.Item item, System.Int32 amount, System.Boolean immediatePickup, System.Boolean forceEquip) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/EquipUnequip.cs:219)
Opsive.Shared.Events.InvokableAction`4[T1,T2,T3,T4].Invoke (T1 arg1, T2 arg2, T3 arg3, T4 arg4) (at <fa7bae0bde914e57874fdb6999909243>:0)
Opsive.Shared.Events.EventHandler.ExecuteEvent[T1,T2,T3,T4] (System.Object obj, System.String eventName, T1 arg1, T2 arg2, T3 arg3, T4 arg4) (at <fa7bae0bde914e57874fdb6999909243>:0)
Opsive.UltimateCharacterController.Inventory.InventoryBase.ItemIdentifierPickedUp (Opsive.Shared.Inventory.IItemIdentifier itemIdentifier, System.Int32 amount, System.Int32 slotID, System.Boolean immediatePickup, System.Boolean forceEquip) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:282)
Opsive.UltimateCharacterController.Inventory.InventoryBase.Pickup (Opsive.Shared.Inventory.IItemIdentifier itemIdentifier, System.Int32 amount, System.Int32 slotID, System.Boolean immediatePickup, System.Boolean forceEquip, System.Boolean notifyOnPickup) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:224)
Opsive.UltimateCharacterController.Inventory.InventoryBase.Pickup (Opsive.Shared.Inventory.IItemIdentifier itemIdentifier, System.Int32 amount, System.Int32 slotID, System.Boolean immediatePickup, System.Boolean forceEquip) (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:196)
Opsive.UltimateCharacterController.Inventory.Inventory.LoadDefaultLoadout () (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/Inventory.cs:49)
Opsive.UltimateCharacterController.Inventory.InventoryBase.Start () (at Assets/Opsive/UltimateCharacterController/Scripts/Inventory/InventoryBase.cs:126)
 
When is your code being run? The null reference is probably m_ActivePerspectiveItem, which gets assigned to in Item.Start(). So if your code is being run in Awake or Start, it could be getting called before m_ActivePerspectiveItem is assigned to.
 
Ok, so should I not setup persistent event listeners? If need be, I can just revert back to relying on the Opsive EventHandler, which I'm guessing is the preferred method.
 
The inventory is started before the item is fully initialized so for that particular callback you should use the event handler.
 
No worries, I'll revert back to the included event handlers!

So, my guess is that any components that have exposed UnityEvents don't support early nor late binding, and should only use the Opsive EventHandler

Thanks
 
Top