How to change equip Weapon from the Equipment slots

Shanmukh

Member
i am trying to implement a weapon wheel. I used equipment slots for the weapon wheel. I added weapons from the inventory grid to equipment slots. I can't change the character weapon item from the weapon wheel.
 
So far we haven't implemented our own weapon wheel so you should make our own.
In your case an Equipment panel might do the trick, if not don't forget you can always make your own custom item View Slot Container.

The issue you have is that the Item Action that come built-in to equip unequip item, moves the item back to the main item collection on unequip. You want an Item Action that actively equips an item that is soft equipped.

So I updated the CharacterEquipUnequipItemAction to choose whether to move equip or not.
Code:
/// <summary>
/// Item action used to Move an item from one collection to another. It can be used to equip/unequip items too.
/// </summary>
[System.Serializable]
public class CharacterEquipUnequipItemAction : ItemAction
{
    [Tooltip("The name that should be displayed when the item can be equipped.")]
    [SerializeField] protected string m_EquipActionName = "Equip";
    [Tooltip("The name that should be displayed when the item can be unequipped.")]
    [SerializeField] protected string m_UnequipActionName = "Unequip";
    [Tooltip("Actively Equip the item if it is soft Equipped but not part of the active item set.")]
    [SerializeField] protected bool m_NotMoveEquip = false;
    private bool m_Equip;
    protected bool m_MoveEquip;
    
    /// <summary>
    /// Default constructor.
    /// </summary>
    public CharacterEquipUnequipItemAction()
    {
        m_Name = "Equip";
    }
    /// <summary>
    /// Returns true if the item action be invoked.
    /// </summary>
    /// <param name="itemInfo">The item.</param>
    /// <param name="itemUser">The inventory user.</param>
    /// <returns>True if it can be invoked.</returns>
    protected override bool CanInvokeInternal(ItemInfo itemInfo, ItemUser itemUser)
    {
        var characterLocomotion = itemUser.gameObject.GetCachedComponent<UltimateCharacterLocomotion>();
        if (characterLocomotion == null || !characterLocomotion.Alive) {
            return false;
        }
        var inventorySystemBridge = itemUser.gameObject.GetCachedComponent<CharacterInventoryBridge>();
        if (inventorySystemBridge == null) {
            return false;
        }
        
        var item = itemInfo.Item;
        
        if (m_NotMoveEquip) {
            m_MoveEquip = false;
            m_Equip = !inventorySystemBridge.IsItemActive(item);
        } else {
            m_MoveEquip = true;
            m_Equip = !inventorySystemBridge.EquippableItemCollections.Contains(item.ItemCollection);
        }
        
        
        
        if (m_Equip) {
            m_Name = m_EquipActionName;
        } else {
            m_Name = m_UnequipActionName;
        }
        return true;
    }
    /// <summary>
    /// Move an item from one collection to another.
    /// </summary>
    /// <param name="itemInfo">The item info.</param>
    protected override void InvokeActionInternal(ItemInfo itemInfo, ItemUser itemUser)
    {
        var inventorySystemBridge = itemUser.gameObject.GetCachedComponent<CharacterInventoryBridge>();
        if (m_MoveEquip) {
            inventorySystemBridge.MoveEquip(itemInfo,m_Equip);
        } else {
            inventorySystemBridge.Equip(itemInfo,m_Equip);
        }
        
    }
}

This code change requires another change, in the Character Inventory Bridge script, you'll need to add those two functions:
Code:
/// <summary>
/// Is the Item Active.
/// </summary>
/// <param name="item">The item to check if active.</param>
/// <returns>True if active</returns>
public bool IsItemActive(Opsive.UltimateInventorySystem.Core.Item item)
{
    var characterItem = GetCharacterItem(item);
    return IsItemActive(characterItem);
}
/// <summary>
/// Is the Item Active.
/// </summary>
/// <param name="item">The item to check if active.</param>
/// <returns>True if active</returns>
public virtual bool IsItemActive(Item characterItem)
{
    if (characterItem == null) { return false; }
    var slotID = characterItem.SlotID;
    var active = characterItem.IsActive();
    var activeItem = GetActiveItem(slotID);
    return active && activeItem == characterItem;
}


In the Inventory Grid Item Actions Set you'll want to toggle off "NotMoveEquip" for the CharacterEquipUnequipItemAction
And for the Equipment panel Item Actions Set you'll wan to toggle on "NotMoveEquip" for the CharacterEquipUnequipItemAction

I hope that helps.
If not do not forget you can always create your own custom Item Actions and Item View Slots Containers which will give you a lot more flexibility
 
I made a weapon weel with this. it's working fine. when I select weapon it's changing sprite. but when equip a weapon, sprite not change.
I added Debug item action to the equipment slot, it shows "IsEquipped: False".
 
Are you using the latest integration version? If so the "IsEquipped" attribute is no longer used.
instead you need to check on the Character Inventory Bridge to know if an item is "soft" or "active" equipped.
Code:
//Active equipped
var activeEquipped = characterInventoryBridge.IsItemActive(item);

//Soft Equipped
var softEquipped = characterInventoryBridge.EquippableItemCollections.Contains(item.ItemCollection)

By the way if you close and reopen your weapon wheel does your weapon show up correctly?
If so perhaps your Weapon Wheel simply needs to refresh to use the currently equipped items.

Are you using a custom "ItemSlotCollectionView" as your weapon Wheel or are you using something completely different?
 
now it's working. but everything of weapon weel is showing equipped sprite from "Equipped select item view". because everything is under "Equipble slots" in the Player "Inventory" script. how to differentiate which weapon is the player currently using?.
so I want to show the equipped sprite only for the player using the weapon slot.
 
There should be a component called "CharacterEquippedSelectItemViewModule".
replae the "EquippedSelectItemViewModule" by that component and it should do exactly what you want.

I just realised you might not have that component in the current version. Here it is:

Add it to this folder: Assets\Opsive\UltimateCharacterController\Integrations\UltimateInventorySystem\Scripts\UI

EDIT: Removed attached script because of a bug
 
Last edited:
sorry, this script not working. SoftEquipped, ActiveEquipped is not working. so I add a debug message at each case, it's only printing from the Unequipped case. please check it again.
 
I'm very sorry, you are right there was a bug.
Silly mistake I used ItemInfo instead of info. ItemInfo has the cached value of the item, so it was always None. The ItemInfo value is updated after the SetValue function is called.

So here is the updated script, I tested it and it works
 

Attachments

  • CharacterEquippedSelectItemViewModule.cs
    4 KB · Views: 7
there is a small bug. when no weapon is active equipped, one of the last active equipped slot is not converted into soft equipped. it not going to everything into soft equipped, when there is no active equipped.
 
I tried to replicate your issue but it seems to work fine for me.
I active equipped and unequiped multiple weapons and everythin was good.
I equipped some weapons, closed the menu, then I switched to no weapons using the scroll wheel, went back to the menu and everything seemed fine too.

Could you share detailed reproduction steps to get the issue you mentioned? A video could be helpful too, you can use Streamable.com
 
I made equipment slots that are active on the screen like hotbar. that pannel not disable after equip or unequip. Maybe that is the issue. need a refresh after equip or unequip that slot.
 
Ah I see, it works for me since I updated the CharacterInventoryBridge to send an Inventory Update event when an Item has finished equipping.

In the BridgeEquippableProcessing script Add/Replace those functions:

Code:
/// <summary>
/// Constructor.
/// </summary>
/// <param name="inventoryBridge">The inventory bridge.</param>
public BridgeEquippableProcessing(CharacterInventoryBridge inventoryBridge)
{
    m_EquipOnItemSetUpdate = true;
    m_StateChangeOnItemSetUpdate = true;
    m_InventoryBridge = inventoryBridge;
    m_CharacterGameobject = m_InventoryBridge.gameObject;
    m_PreviousActiveSets = new ActiveAndNextItemSetData(ItemSetManager.CategoryCount,ItemSetManager.SlotCount);
    m_RemovingFromItemSet = new List<CharacterItemInfo>();
    m_CurrentItemSet = new List<Item>();
    m_InventoryItemToCharacterItems = new Dictionary<Item, List<Items.Item>>();
    
    EventHandler.RegisterEvent<ItemInfo, ItemStack>(m_InventoryBridge.Inventory,
        EventNames.c_Inventory_OnAdd_ItemInfo_ItemStack, OnAddItemToInventory);
    EventHandler.RegisterEvent<ItemInfo>(m_InventoryBridge.Inventory,
        EventNames.c_Inventory_OnRemove_ItemInfo, OnRemoveItemFromInventory);
    EventHandler.RegisterEvent<Items.Item, int>(m_CharacterGameobject,
        "OnAbilityUnequipItemComplete", OnUnequipItemComplete);
    EventHandler.RegisterEvent<Items.Item, int>(m_CharacterGameobject,
        "OnInventoryEquipItem", OnEquipItemComplete);
    EventHandler.RegisterEvent<Items.Item, int>(m_CharacterGameobject,
        "OnAbilityWillEquipItem", OnWillEquipItem);
    EventHandler.RegisterEvent<List<ItemSetStateInfo>>(m_CharacterGameobject,
        IntegrationEventNames.c_GameObject_ItemSetsWillUpdate_ListOfItemSetStateInfo, OnItemSetsWillUpdate);
}

/// <summary>
/// The item finished equipping.
/// </summary>
/// <param name="characterItem">The character item.</param>
/// <param name="slotID">The item set slot ID.</param>
protected virtual void OnEquipItemComplete(Items.Item characterItem, int slotID)
{
    //Update the Inventory after the Item Set changes to force update the UI and other things.
    m_InventoryBridge.Inventory.UpdateInventory(false);
}
Code:

That should help you update the UI when an Item is equipped.

All of these changes and many more will be available in the next update planned for end of July.
 
Ah then I'm not quite sure why it is working for me and not for you. I made a lot of changes that aren't yet public.
If you can I would recommend you wait for the next major update.

If not you can try to force your UI to update when an Item has been Equipped and Unequipped in a custom script by using the events showed in the code above.

I'm sorry I couldn't help more
 
Top