Retrieve Item from Hotbar

Stormi

Member
I am trying to set up an ability system within the inventory system by using separate item categories/definitions and filling these with all the relevant attributes I need to trigger the animations, particle effects etc. In general I see absolutely no reason, why I should not end up with a satisfying solution but I am a bit stuck in regards to fetching the item in a hotbar.

In regards to equipped items I use the namespaces

using Opsive.UltimateInventorySystem.Core;
using Opsive.UltimateInventorySystem.Equipping;
using Opsive.Shared.Game;

and then something along the line of (only referencing the relevant code here now):

C#:
private Equipper equipper;
private Item equippedWeapon;
private int weaponDamage;

var playerInventory = InventorySystemManager.GetInventoryIdentifier(1).Inventory;
equipper = playerInventory.gameObject.GetCachedComponent<Equipper>();
equippedWeapon = equipper.GetEquippedItem("MainHand");
equippedWeapon.TryGetAttributeValue("Damage", out weaponDamage);


This works nicely so I tried to somehow replicate the approach by adding the namespaces

using Opsive.UltimateInventorySystem.Core.DataStructures;
using Opsive.UltimateInventorySystem.UI.Panels.Hotbar;

and then doing the following:

C#:
private ItemHotbar itemHotbar;
private ItemInfo equippedAbility;
private string triggerName;

var playerInventory = InventorySystemManager.GetInventoryIdentifier(1).Inventory;
itemHotbar = playerInventory.gameObject.GetCachedComponent<ItemHotbar>();
equippedAbility = itemHotbar.GetItemAt(1);
equippedAbility.Item.TryGetAttributeValue("TriggerName", out triggerName);


I didn't find a solution to directly fetch the Item, since GetEquipped() wasn't available here, so I went through the ItemInfo with GetItemAt() but the problem is that I'm not getting the itemHotbar in the first place because playerInventory.gameObject.GetCachedComponent<ItemHotbar>(); is always returning null.

In the end, I simply want to be able to get the items slotted in the hotbar during runtime and then retrieve the desired attributes in order to use them in custom scripts, just like I do with the items fetched via the equipper already.

Thanks a lot for any help here.
 
So the first mistake is the line
Code:
itemHotbar = playerInventory.gameObject.GetCachedComponent<ItemHotbar>();
GetCachedComponent is the same as the default GetComponent except we cache the value.
That means it's looking for the ItemHotbar component on the player game object... and of course that does not work because the ItemHotbar is in the UI.

Second mistake ItemHotbar is an ItemViewSlotContainer not an Equipper, so the GetEquippedItem of course does not exist.
You were right to use GetItemAt to get the item.

Note that the ItemHotbar already comes with a system to trigger Item Action built-in so you could have used that instead of calling the actions externally. That being said there can be multiple reasons you would want to do what you are doing so you do not have to use our solution if you don't want to.

So the question here is how to get the Item Hotbar from anywhere in code.
To do this you can make use of the DisplayPanel "Unique Name".
Make sure your ItemHotbarPanel is correctly set

1610095974201.png
Code:
public static void GetItemHotbar()
{
    //Get the display Panel manger by ID.
    var panelManager = InventorySystemManager.GetDisplayPanelManager(1);
    //Use the Unique Name set in the inspector.
    var itemHotbarPanel = panelManager.GetPanel("Item Hotbar");
    //Get the Item View Slot Container Binding which references the Item Hotbar
    var itemHotbarPanelBinding = itemHotbarPanel.gameObject.GetCachedComponent<ItemViewSlotsContainerPanelBinding>();
    // Get the itemHotbar from the binding
    var itemHotbar = itemHotbarPanelBinding.ItemViewSlotsContainer as ItemHotbar;
   
    //Now you can get whatever you want from the itemHotbar!
    var itemInfoInSlot0 = itemHotbar.GetItemAt(0);
}

... Now that I think about it, I could add that function that does all that in the InventorySystemManager, it would save you from writing 4 lines of code... and I could make it such that it would also allow you to get the other types of ItemViewSlotContainers (InventoryGrid, Equipement, etc...) I think that's a good idea, I'll try to add that for the next update



EDIT: You can add the following function to the InventorySystemManager script

C#:
/// <summary>
/// Get an Item View Slot Container.
/// The Display Panel Requires an ItemViewSlotsContainerPanelBinding pointing at the Item View Slot Container.
/// </summary>
/// <param name="panelManagerID">The panel Manager ID.</param>
/// <param name="panelName">The name of the Display Panel.</param>
/// <param name="containerName">The Item View Slot Container name.</param>
/// <typeparam name="T">The type of Item View Slot Container.</typeparam>
/// <returns>The Item View Slot Container.</returns>
public static T GetItemViewSlotContainer<T>(uint panelManagerID, string panelName, string containerName = null) where T : ItemViewSlotsContainerBase
{
    //Get the display Panel manger by ID.
    var panelManager = GetDisplayPanelManager(panelManagerID);
    //Use the Unique Name set in the inspector.
    var panel = panelManager.GetPanel(panelName);
    if (panel == null) { return null;}
    
    //Get the Item View Slot Container Binding which references the Item Hotbar
    var panelBindings = panel.gameObject.GetCachedComponents<ItemViewSlotsContainerPanelBinding>();
    for (int i = 0; i < panelBindings.Length; i++) {
        var itemViewSlotContainer = panelBindings[i].ItemViewSlotsContainer;
        if ((string.IsNullOrEmpty(containerName) || containerName == itemViewSlotContainer.ContainerName)
            && itemViewSlotContainer is T containerOfType) {
            return containerOfType;
        }
    }
    
    return null;
}

Then you'll be able to use this instead of the code I sent you before:

Code:
//New Function!
var itemHotbar = InventorySystemManager.GetItemViewSlotContainer<ItemHotbar>(1, "Item Hotbar");
//Now you can get whatever you want from the itemHotbar!
var itemInfoInSlot0 = itemHotbar.GetItemAt(0);
 
Last edited:
I had to also add the namespaces "Opsive.Shared.Game" and "Opsive.UltimateInventorySystem.UI.Panels.ItemViewSlotContainers" to the InventorySystemManager Script but aside from that, it worked like a charm, thanks a lot. I can now set up abilities by creating items for them in a unique category, fill these items with everything I need (like particle prefabs, trigger names for the Animator, etc.) and then extract the attributes whenever the ability is executed.

I'll take another look at the built-in action trigger system (already wrote a custom action for the use of health potions to test it out) but I'm pretty sure, I'll still get a lot of benefits from the additional methods you gave here :)
 
Top