Ultimate Inventory and Equipment Component

Documentation

Features

  • Jigsaw or slot-based container - supports jigsaw grid, found in games like Diablo or Path of Exile, where each item occupies a specific combination(rectangular) of slots in the grid. Can be also set up to act as the standard slot-based grid, found in most mmo games, where each item occupies a single slot.
  • Adjustable containers and items size - determine how big are player inventory, storage, loot chest or vendor containers. For jigsaw grid, you also determine how many slots each item occupies.
  • Items created through data table - all necessary items data is gathered in a single data table, where you can easily add new or edit existing items.
  • Inventory system - premade functionality which makes a container to act as an inventory.
  • Vendor system - premade functionality which let a user set up random shops where players can be new items or sell theirs.
  • Storage and loot chests - premade functionality which let a user create lootable chests and players storages.
  • Simple pick up and drop functions - easy to follow and extend to suit your game type.
  • Equipment system - create your own equipment slots and define which item types can be equipped to them.
  • Static and skeletal meshes - equipment system supports both static meshes (mainly weapons) and skeletal meshes (ie. armor) which needs to bend with character body.
  • Lockable equipment slots - possibility to create items that require more than one slot to be equipped (ie. two-handed sword requires left and right-hand slot and will automatically unequip items from these slots; or robe which requires torso, head and legs slots.
  • Drag&drop and single-click operations - players can drag and drop items between containers or relocate them with a single mouse click.
  • Stacking and splitting - items can be stacked up to a specific number of pieces and then stacks can be split on demand.
  • Simultaneous access to chests and vendors - multiple players can open the same chest or vendor and every action they perform (store/withdraw/buy/sell) will be seen by all these players.
  • Items tooltip and slot highlights - shows item tooltip when the mouse cursor hovers over the item slot. Additionally, when an item is dragged system highlights all affected slots to reflect possible on drop operation.

Go back to homepage

Ultimate Inventory and Equipment Component

Ultimate Attributes and Stats Component

Ultimate Quests and Achievements System

Simple Notification System

Options Constructor

jRPG Template

Implementation

Let's start with adding AC_UIC_ItemsManager component to the actor that will be responsible for maintaining items and containers. It is the most important component of the system because it contains whole logic and acts as a brain. My suggestion is to add it to the main Player Controller or directly to Player Pawn if you do not use custom Player Controller. Generally, add it to the actor that is easily accessible and is present in game most of the time.

Steps to do:
Open blueprint actor that you want to add "items logic" to.
Navigate to its Components tab.
Click the green +AddComponent button and from the dropdown list choose AC_UIC_ItemsManager.
Click on newly added AC_UIC_ItemsManager and navigate to Details tab.
Find Config category and set up default data.
  • SlotDimensions determines how big are all container slots.
  • DebugEnabled will toggle printing of all debug messages from ItemsManager component.


Now, when you have ItemsManager added to the game you can start adding containers to specific actors. AC_UIC_Container is a component responsible for storing items data assigned to the container. There are 3 basic types of container: Inventory, Stash, and Vendor. It is important to determine a type of all containers added to the game. If you want to create character's backpack functionality you will select Inventory Type. However, if you want to create some kind of chest (storage or loot), you will select Stash Type. You will also need a widget blueprint which will display items added to containers.

Steps to do :
Open your UI widget (the one which will display inventory, stash or whatever you need).
Navigate to Palette tab and find WBP_UIC_ContainerGrid. Add it to your widget. (It won't contain anything because slots will be created on the component initialization).
Click on newly added WBP_UIC_ContainerGrid and access its Details.
Under Default category select ContainerType, it will determine which container's items will be displayed there.
Open actor blueprint and navigate to its Components tab.
Click the green +Add Component button and from the dropdown list choose AC_UIC_Container.
Click on newly added AC_UIC_Container to access its Details.
In Details tab find Config category to edit container's default data.
  • ContainerSize will determine how many slots container has and how they are arranged.
  • ContainerType will determine what actions can be performed on that container.


Few important notes about containers types:
Inventory - acts as a handy bag, by default stores all picked up items, if dragging is canceled dragged items is placed there, unequipped items go there as well. Users can perform few actions when clicked while Ctrl button (by default) is held - store item in Stash type container (if a stash is opened), sell an item to a vendor (if a vendor is opened) or equip the item (if neither stash nor vendor is opened)
Stash - designed to be a storage or loot chest, dragged items can be added there as well as stored items can be retrieved. Only one action can be performed when clicked while Ctrl button is held - withdraw an item from Stash directly to Inventory.
Vendor - used to buy and sell items. Users will automatically get gold when dropping the item to Vendor container (sold items will disappear), users will also automatically pay for the item when starting to drag it. Only one action can be performed when clicked while Ctrl button is held - buy an item and place it in inventory.

Note: If you do not have your UI yet or have problems with adding ContainerGrid, you can use UI widget provided in Demo (WBP_UIC_UserInterface) or see how things are implemented there.
There is one component left - AC_UIC_Equipment. This one is responsible for handling actors equipment. It is similar to Container component because it needs to be added to the actor and only contains equipped items data. Here we can also set up how many slots equipment has and what items can be equipped. In addition to component, equipment also has its own WBP_UIC_EquipmentCanvas widget where you can adjust equipment layout.

Steps to do:
Open WBP_UIC_EquipmentCanvas.
Navigate to Palette tab and find WBP_UIC_EquipmentSlot.
Add as many of them to the EquipmentContainer canvas as you need (you can edit or remove existing slots).
Set up default data for each added EquipmentSlot widget. Under Static category, you will find following variables:
  • SlotSize - maximum size of an equipped item. All equipped items will be adjusted to the size of the slot(lesser items will be centered, so they do not stretch and larger items will be decreased to fit in the slot. to maintain optimum visual experience equipment slot should have the size equal to the largest item that can be equipped there.
  • SlotDimensions - also determines the size of the slot, but this time in pixels. So if SlotSize is 2x3 and SlotDimensions are 64x64 then equipment slot will be 128x192. I would suggest keeping SlotDimensions equal to the ones in ItemsManager.
  • SlotIndex - determines which item from equipment container will be assigned to that equipment slot. Each equipment slot must have unique SlotIndex value.
  • DefaultIcon - image that will be shown when there is no item equipped.
Open your UI widget (the one which will display equipment).
Navigate to Palette tab and find WBP_UIC_EquipmentCanvas. Add it to your widget.
Open actor blueprint to which you want to add equipment functionality.
Navigate to its Components tab.
Click the green +AddComponent button and this time from the dropdown list choose AC_UIC_Equipment.
Click on newly added AC_UIC_Equipment to access its Details.
Under Config category, you will find two variables which need to be set up:
  • EquippedItems - determines how many items can be equipped. Generally, slots should equal to the ones you set up in WBP_UIC_EquipmentCanvas.
  • AvailableEquipment - determines which item subtypes can be equipped to specific slots. Should be equal to the number of slots in EquippedItems.

Creating new items

All items added to the game are stored in DT_UIC_Items data table. You can edit existing ones or create new items there. Data table entries are basing on the S_UIC_ItemStatic structure so if you would like to extend item data you will need to edit that structure.

Below you will find explanations for all variables in item structure:
  • ID - used to identify an item during the game and in blueprints logic. All items IDs must be unique. You can use unique names or simple indexes, whatever makes it easy to distinguish them. IMPORTANT: ID must be the same as the name of the row in the data table.
  • DisplayName - the name of the item that will be displayed to the player (ie. in widgets).
  • Description - description of the item that will be displayed to the player (ie. in widgets).
  • Size - how many slots item takes in the container. TIP: Setting size of all items to 1x1 you will turn jigsaw system to standard slot-based system.
  • Value - how much item is worth (default price for buying and selling).
  • Type - to which group item belongs to (existing items types can be edited in the E_UIC_ItemType enumeration, you can also add new ones).
  • Subtype - to which subtype item belongs to (existing items types can be edited in the E_UIC_ItemSubtype enumeration, you can also add new ones). Subtypes are also used to determine which item can be equipped to specific equipment slots.
  • Image - icon/image that will be displayed to the player (ie. in widgets, during item dragging). Remember to maintain image proportions to avoid distortion. If item size is 2x1, then its width must two times longer than its height (256x128, 200x100, 300x150 and so on).
  • MaxAmountInStack - how many pieces of the specific item can be collected to one stack. IMPORTANT: must be higher than 0, additionally, for all equipment items must be equal to 1. Items with MaxAmountInStack higher than 1 cannot be equipped.
  • AdditionalLockedSlots (only for equipment) - determines which slots will be locked/excluded from equipment when this specific item is equipped. Eg. If you want to create a two-handed weapon you can lock slot where a shield is equipped. One item can lock multiple slots.
  • SkeletalMeshEquip (only for equipment) - this skeletal mesh component will be added to the actor when the item is equipped. Skinned meshes can be used to create equipment parts which need to bend with the body, such as torso armor or trousers.
  • StaticMeshEquip (only for equipment) - this static mesh component will be added to the actor when the item is equipped. Static meshes are mostly used for rigid equipment parts, such as weapons or helmets.
  • StaticMeshEquipSocket (only for equipment) - determines where static meshes are attached to (to which sockets). It requires a paired slot index and socket name. Thanks to this we can equip the same item to different slots without excessive changes. Eg. Let's assume we have two equipment slots with indexes 1 (right hand) and 2 (left hand). We also have a sword which can be equipped to right or left hand. Thanks to this paired values we can set up that when the sword is equipped to slot 1 its static mesh will be attached to the right-hand socket if the sword was equipped to slot 2 it would be attached to the left-hand socket.


Items data can be edited anytime and changes will affect the game at any stage (even if you load the game from save file). However, there are few things to keep in mind.
  • Size changes should be avoided at later stages of development, especially when the game is published. Because if an item is already in a container and we change its size it is highly possible that it will overlap other items.
  • Changing MaxAmoutnInStack won't affect the current number of pieces in the stack. Eg. If you decide to decrease potion max stack amount from 20 to 10 all stacks that player already acquired and have 20 pieces will remain there unless the player decides to split them, then he won't be able to merge them back. But all new stacks will be stacked up to 10 pieces. (Of course, assuming that changes are made late in development and players already have these items).
  • Changing item subtypes won't unequip items automatically if their subtype won't match available ones, but the player won't be able to re-equip this once item is unequipped. Eg. It was made the way that player can equip 2x one-handed sword (to right and left hands). But later it was changed that the only dagger can be equipped to the left hand and only one sword can be equipped (to the right hand). So if the player had a character with 2x one-handed swords equipped it will remain this way, until the player decides to unequip that second sword.

These are small things but should help you to avoid encountering bugs later.

Of course, you could always make it put pieces that exceed MaxAmountInStack directly to inventory when changes are made and same with equipment that doesn't meet requirements after changes. However, you will also need to figure out what to do with items if there is no space in inventory and system automatically splits or unequips them. You could send them to in-game mailbox or store at special NPC (just an idea, all depends on game type).

Add and remove items from containers

To add an item to a specific container you can call one of two functions from ItemsManager component. These functions are: AddItemToContainer(byID) and AddItemToContainer(byStruct). IMPORTANT: If you are making a multiplayer game they should be called on the server side. These functions are very similar, they both require pinned container to which you want to add item to and you can specify amount of the item.

When to use AddItemToContainer(byID) function?
This function will read item data (by matching ID) from data table and add it to container. It is useful if you want to add some kind of random item. Let's suppose there is a sword that has random power bonus (5-15). Each time item is added from data table you could roll random power bonus value. So if you add multiple sword their power bonus would vary.

When to use AddItemToContainer(byStruct) function?
This one will require specified item structure that will be added to container. Main reason to use this function is to add item with specific data to container. Let's stick to that sword with random power bonus used in previous example. Thanks to this function you can add that sword with exact value of power bonus (eg. quest reward gives player a sword with +15 power).

There is one more function responsible for adding items to containers. It is FillContainerWithItems and it will add random items from data table to container given amount of times (It uses AddItemToContainer(byID) function). If you set up to add 100 items and container will be full after 20 rolls it will keep rolling random items up to 100 times. It does so because if it roll stackable item it will be added to existing stack if it is not full. This function can be used to fill vendor or loot chest containers with items, of course you can extend functionality by percentage based rolls, so rare items won't appear as frequently as common ones.



There is one main function in ItemsManager component responsible for removing items. IMPORTANT: As previously it should be called on the server side if it is a multiplayer game. RemoveItemFromContainer will remove an item (specified by ID) starting from the stack that is not full and then in order from the left top slot to the right bottom slot. You can specify whether it should remove items even if there are not enough pieces in a container or it should remove all of them regardless of their amount in a container.


Note: if you want to create an item that player will be able to pick up in the world, there is example BP_DemoUSC_Pickup actor in Demo/Blueprints folder. Of course, it is not the only way to implement Pickups to the game, feel free to make it the way suits your project.

Access and leave stash or vendor containers

There is powerful functionality that provides simultaneous access by multiple players to the same stash or vendor container. Thanks to this, when one player stores, withdraws, buys or sells items other players will see it immediately (of course if they are accessing the same container at this moment). How player access stash or vendor is totally up to the user and will vary depending on a game type and whether it is multiplayer or not.
However, I have added functionality that wraps up accessing containers in both single and multiplayer games. Most of the logic is spread between ItemsManager component (generic events responsible for storing references) and demo PlayerController (demo-specific data, like opening widgets). You can use it as a base to create your own functionality to access storages, chests, and vendors. I reckon in most cases there will be only little changes needed (if any at all).


Note: Simultaneous access required special interaction with the vendor. When buying an item from a vendor you will pay for it immediately when you start dragging it (click on it in vendor window) not when you drop it to inventory. It works this way because when a player starts dragging an item from a vendor other players accessing this vendor needs to know that item is no longer available. That's why it is paid instantly and treated as player's item once it is picked from a vendor.
Also to prevent from messing up vendor container sold items will disappear and won't be added to the vendor container. Of course, there are workarounds, each player could have separate independent vendors components, but it would also mean they will have different items and won't interact with each other when accessing vendor. Optionally, if there will be many requests I may try to implement this workaround and users will be able to choose the one they want to use.


Stacks splitting

To make items managing easier players can use stacks splitting functionality. It will let them take a specific amount of item from a stack (if MaxAmountInStack>1) and drag it to another slot or container. To enable or disable stack splitting call ToggleStackSplitingOperation function from ItemsManager component. In the demo, it is toggled with LeftShift (on when pressed and off when released).
Note: Items with 1 piece of item in a stack will be dragged automatically without popping Splitting Window out.


An item also will be stacked automatically if you drop it on the other item that has a matching ID.

Quick actions

Quick actions are the events that let a player to quickly perform actions in containers instead of dragging items from one container to another. With a single mouse click, players can equip, unequip, buy, sell, store and withdraw items. To enable or disable quick actions call ToggleQuickActionsOperations function from ItemsManager component. In the demo, it is toggled with LeftCtrl (on when pressed and off when released).
Which quick action is used depends on which containers are opened/accessed.
  • Quick Store and Withdraw can only be used if Stash and Inventory containers are opened and it will move items between them, relocating item to the first available valid slot.
  • Quick Buy and Sell can only be used if Vendor and Inventory containers are opened. Items will be immediately sold from inventory and bought from a vendor as long as there is free space in inventory.
  • Quick Unequip can be performed at any time and will remove an item from the equipment slot and place it in inventory as long as there is free space for it.
  • Quick Equip can only be used if neither Vendor nor Stash containers are opened. Clicked item will be equipped to the first equipment slot that meets item requirements. It means that if a one-handed sword can be equipped to right-hand equipment slot (index= 1) and left-hand equipment slot (index=2) it will always be equipped to right-hand equipment slot.