How does ShootableWeaponAmmoBinding listen to changes to ClipRemaining in ShootableWeapon?

airoll

Member
Hi, I am trying to understand how ShootableWeaponAmmoBinding works. Specifically, if I fire a weapon and it consumes one ammo in the m_ClipRemaining of a ShootableWeapon, how does ShootableWeaponAmmoBinding know to update the AmmoData attribute of the Item?

Just to be clear, it is working fine. However, I'm trying to create a UI hook such that I can show the clip remaining as a UI text object, but I'm not sure where ShootableWeaponAmmoBinding is being notified that the ammo was consumed.
 
The ShootableWeaponAmmoBinding does not update teh AmmoData attribute. It just binds it. So actually the AmmoData does not know what value it has until you get it.

It's not very intuitive but when maybe this explanation makes more sense. When you do ammoDataAttribute.GetValue() or SetValue(...), It checks if the attribute has a binding, if it does it will get/set the value from the binding, if not get/set the override value.

In ShootableWeaponAmmoBinding we are binding the property called "AmmoData", its this line of code:
Code:
m_AmmoDataAttributeBinding = new AttributeBinding<AmmoData>(m_AmmoDataAttributeName, this, "AmmoData");

AmmoData is the property:

Code:
/// <summary>
/// The ammo data is used by the bound attribute to update the shootable weapon or attribute values.
/// </summary>
public AmmoData AmmoData {
    get
    {
        IItemIdentifier consumableItemIdentifier = m_ShootableWeapon.GetConsumableItemIdentifier();
        if (consumableItemIdentifier == null) {
            Debug.Log("consumableItemIdentifier is null");
            return m_AmmoData;
        }
        
        m_AmmoData = new AmmoData(
            m_ShootableWeapon.GetConsumableItemIdentifier()?.GetItemDefinition(),
            m_ShootableWeapon.ClipSize,
            m_ShootableWeapon.GetConsumableItemIdentifierAmount()
            );
        
        return m_AmmoData;
    }
    set
    {
        m_AmmoData = value;
        SetAmmoToShootableWeapon(m_AmmoData);
    }
}

Hopefully this makes more sense.

So know back to what you want to achieve, now you understand that the ammo data binding is not what you want, instead you want to listen to an event.

These are the two events you may want to listen too:
Code:
 Shared.Events.EventHandler.RegisterEvent<Items.Item, IItemIdentifier, int>(m_CachedInventory.gameObject, "OnItemUseConsumableItemIdentifier", OnUseConsumableItemIdentifier);
                Shared.Events.EventHandler.RegisterEvent<IItemIdentifier, int>(m_CachedInventory.gameObject, "OnInventoryAdjustItemIdentifierAmount", OnAdjustItemIdentifierAmount);

There are actually already two UI components that monitors the ammo. One is pure UCC called "ItemSlotMonitor" and the other is from the Integration called "WeaponAmmoItemViewModule"

I hope that helps
 
Top