Can create multiple action bars from the courses code

Hey all!

Just wanted to share that it’s very possible to create a new action bar for utility purposes like potions or other consumables separately from the main one where abilities go.

I created a new script EItemSlotPlacement which is a collection of slot placements.

namespace Game.Inventories
{
    public enum EItemSlotPlacement
    {
        None,
        AbilitiesSlot,
        ConsumablesSlot
    }
}

Within ActionSlotUI script create a serializefield for our EItemSlotPlacement.

[SerializeField] EItemSlotPlacement placementSlot = EItemSlotPlacement.None;

In your UnityEditor you should now see your ActionBars with the new serializefield exposed. Drop down and select your choice for which particular item can be slotted into this container.

Then modify your ActionSlotUI’s ‘AddItems()’ code to these new changes:

public void AddItems(InventoryItem item, int number)
{
     if (item.GetSlotPlacement() != placementSlot)
     {
         player.GetComponent<Inventory>().AddToFirstEmptySlot(item, number);
         return;
     }
     store.AddAction(item, index, number);
}
  1. If the item we wish to drop doesn’t match then we cannot swap or populate the item into that container, meaning the IDragInterfaces should handle that by snapping back to its source. Also it means it will attempt to place the item into the Inventory after failure to find a suitable action slot.
  2. If the item is matched, then regardless if it’s empty or not, it will attempt to swap, and that will then take effect so long as the slot matches the item’s slot placement enum.

We need store.AddItem(item, index, number) as a way to swap between docked items within their correct placements.

And to make this work you’ll need to create a getter inside your InventoryItem and a new serializefield for the EItemSlotPlacement:

[SerializeField] EItemSlotPlacement slotPlacement = EItemSlotPlacement.None;

public EItemSlotPlacement GetSlotPlacement() => slotPlacement;

Then setup your Ability / ActionItem Items with the appropriate placements where they can go.

I duplicated ActionBar and re-named it to Consumables (ActionBar) and the original one re-named to Abilities (ActionBar). I reduced the ActionSlots to just 3 and made sure to update those locations to be for Consumables. Then our original 6 ActionSlots are listed under ‘Abilities’ for placement.

displaybothactionbars
Displaying the different ActionBars.

displayinspectorslots
Displaying the drop down on the InventoryItem under Consumables (Action Bar)

displayingabilityinspector
Displaying the Ability Item’s slot placement for ActionBars.

Lastly I modified my earlier code where I place ActionItems into empty ActionBar slots before attempting to place them into our Inventory to now separate and only populate non-abilities within the Consumables ActionBars and vice versa.

Code inside ActionStore handles that behaviour:

int EquippingActionItem(InventoryItem item, int currentIndex, int maxIndex, int number)
{
     for (int i = currentIndex; i < maxIndex; i++)
     {
         if (!dockedItems.ContainsKey(i))
         {
              AddAction(item, i, number);
              return number;
         }
         else if (dockedItems.ContainsKey(i) && dockedItems[i].item == item && item.IsStackable())
         {
              AddAction(item, i, number);
              return number;
         }
         else if (!dockedItems.ContainsKey(i) && !item.IsStackable())
         {
              AddAction(item, i = +1, number);
              return number;
         }
   }
   return 0;
}

I made it so that only Abilities can populate the first 6 indexes. Then the remaining 3 spots 6 to 9 can only be populated for potions, scrolls, anything consumable.

public int AddItemToActionSlots(InventoryItem item, int index, int number)
{
      if (item.GetSlotPlacement() == EItemSlotPlacement.AbilitiesSlot)
      {
         return EquippingActionItem(item, 0, 6, number);
      }

      else if (item.GetSlotPlacement() == EItemSlotPlacement.ConsumablesSlot)
      {
          return EquippingActionItem(item, 6, 9, number);
      }
      return 0;
}
AddToFirstEmptySlot Modification
        public bool AddToFirstEmptySlot(InventoryItem item, int number)
        {
            foreach (IItemStore store in GetComponents<IItemStore>())
            {
                number -= store.AddItems(item, number);
            }

            if (number <= 0) return true;

            equipment = GetComponent<Equipment>();

            if (item.GetSlotPlacement() == EItemSlotPlacement.StatsEquipableSlot)
            {
                Debug.Log(item.GetSlotPlacement() + "/" + item.name);
                foreach (IEquipStore store in GetComponents<IEquipStore>())
                {
                    EquipableItem equipableItem = item as EquipableItem;
                    EquipLocation equipLocation = equipableItem.GetAllowedEquipLocation();

                    if (equipableItem.CanEquip(equipLocation, equipment))
                    {
                        store.AddEquipmentItem(item, equipLocation);
                        return true;
                    }
                }
            }

            actionStore = GetComponent<ActionStore>();

            if (item.GetSlotPlacement() == EItemSlotPlacement.AbilitiesSlot || item.GetSlotPlacement() == EItemSlotPlacement.ConsumablesSlot)
            {
                Debug.Log(item.GetSlotPlacement() + "/" + item.name);
                foreach (IActionStore store in GetComponents<IActionStore>())
                {
                    number -= store.AddItemToActionSlots(item, index, number);
                }

                if (number <= 0) return true;
            }

            int i = FindSlot(item);

            if (i < 0) return false;
            

            slots[i].item = item;
            slots[i].number += number;
            inventoryUpdated?.Invoke();
            
            return true;
        }

One Edit:

Totally forgot but you also must ensure to update the amount of indexes your player can push up to. Mine is located on my AbilityStore.cs but wherever yours is located reflect the changes so that the player can press the additional action slots else you’ll be left scratching your head as to why you couldn’t activate them through your hot keys.

    void UseAbilities()
    {
        for (int i = 0; i < totalActionbarSlots; i++) // total is 9 for me since 6 action bars + 3 consumable slots.
        {
            if (Input.GetKeyDown(KeyCode.Alpha1 + i))
            {
                actionStore.Use(i, gameObject);
            }
        }
    }

I don’t think I missed anything else, but of course, I have been working and revising some of the course’s code for a few months so this might not be completely modular for any RPG project but you can probably follow the breadcrumbs and get this up and running quite easily!

I have just explored a bit of the IPointerHandle interfaces and found a decent method that handles the logic for the user to be able to click on an item inside their inventory and then have it automatically find an actionslot to equip to if there is availability.

This is really awesome, going to test it to see how I can make it work within the consumables so I can right click them back to the inventory (if there is space)!!

I think the appropriate place is InventorySlotUI

        public void OnPointerClick(PointerEventData eventData)
        {
            if (eventData.button == PointerEventData.InputButton.Right)
            {
                if (GetItem() != null)
                {
                    ActionStore store = GameObject.FindGameObjectWithTag("Player").GetComponent<ActionStore>();

                    if (store.GetAction(6) == null || store.GetAction(7) == null || store.GetAction(8) == null)
                    {
                        inventory.AddToFirstEmptySlot(GetItem(), GetNumber());
                        inventory.RemoveFromSlot(index, GetNumber());
                    }
                }
            }
        }

I’ll totally fix these magic numbers! but it does work for the testing so that if the consumable slots are null then whatever you clicked on with the RMB will automatically equip itself there.

1 Like

Privacy & Terms