19. UE – How to equip inventory items with custom server

In this blog post we’re integrating with the custom built Java server that can be found here and specifically implementing item equip functionality that was built in this blog post.

In the video we will cover most/all blueprints and see a demo of this in action.

Equipping items video

I will try go step by step with what was required to be done to achieve it using Unreal Engine.

As before the API integrations have been done with a free VaRest plugin from UE marketplace.

In general, these are the functionalities I was aiming to achieve here:

  • On inventory item right click, show an extended menu where user can equip/drop item
  • From item menu, click drop to call API to drop the item and refresh inventory
  • From item menu, click equip item to call API to equip it, then refresh inventory and equipped items
  • On inventory item double click, equip the item and refresh inventory
  • From equipped items icon, double click to un-equip the item, refreshing inventory and equipped items

Let’s jump straight in.

Display item menu on right click

In order to display the menu, first you want to create the widget for the menu.

Create a widget blueprint

The widget can be designed however you like, but this is how I’ve implemented it:

Design for my item menu

In this way, if my menu starts to grow too large I can keep it smaller because of the scrollbox, but this is optional and not required.

In general, it should just be widget containing some buttons for you to press.

Once the widget is created you can spawn it when you right click an item slot.

So from my previous posts, I created a styled item slot widget.

Styled item slot widget

This will be the widget containing your item slot – don’t worry too much about the differences in style between the one above and yours, as the implementation should stay generally universal.

For reference, the slot above was created in these two blog posts, but I don’t think they are needed as pre-requisite.

Handling right click on the button

So the first thing you will notice is that buttons don’t support right clicks…

Buttons don’t support right clicks

So instead, you will go into the graph view and click Add button on top left corner and under override function select On Mouse Button Down.

Find On mouse button down override

Note that this is not for just the button component, but rather the entire widget – so place this carefully.

When you click this override, it will take you to the next view where you have a call when a mouse is pressed.

You will want to create a Is Mouse Button Down function where you can select the right mouse button for input.

Check whether the right mouse button is pressed

Add a branch to ensure that the right mouse is pressed, as this event captures both left and right mouse clicks (Note that if you have a button in widget, it will consume the left mouse click event).

And now you can safely create the menu widget here, when right mouse button is pressed.

If you leave it at that, it will create the widget at top left corner which is not what you want, so I also added a bit of code to position this menu next to the mouse.

Position item menu next to the mouse

I position the widget where the mouse is, with a small, 30×30 offset. Note that you should disable the remove DPIScale boolean so that it will work correctly when you re-size the window.

I also added another custom event on the graph, such that when the mouse leaves the menu, it will close the menu.

When mouse leaves the menu, close itself

This is mainly to avoid more complicated solutions of tracking click events outside this widget, which is possible and we can cover in future.

Ok now I want to handle on button pressed events, to drop and equip items.

Handling Drop item from the menu

Ok from the designer view of your item menu, locate the drop button and add a On Clicked event to it.

From the drop item button, add On clicked event

Then inside the blueprints you can handle this call.

Handle on item drop button event

I’ve refactored the drop event into the TopDownCharacter blueprint, but it can live in many places, e.g. Inventory widget or even Game mode widget. To be honest I am not yet sure where the best place is for it yet, but I’ve set it into TopDownCharacter incase there will be other game objects which will force the player to drop items in future for example, and it would be easier to reference it from there.

After calling the API to drop the item, remove the menu from parent.

Dropping item API has already been covered in a previous blog post so will not go into too much detail, but the blueprints for the API can be found here.

Dropping Item API call

The main principal is that we create a new API request, specifying the character who has the item, the item location in the inventory and the location to drop the item in game world.

Then we also call refresh inventory event, which will be displayed below and referenced in multiple other locations.

Refresh inventory

Refresh inventory is a simple call which fetches the inventory widget and asks itself to refresh

Refresh inventory blueprint

This is basically the call in the Inventory constructor, where it pulls the data from server and re-synchronizes itself.

Inventory pulling data from server

This functionality was covered in this blog post.

Equipping items

There’s two ways of equipping items, one from the menu on click to equip, another by double clicking the item slot.

We don’t want to repeat code and I decided the functionality to equip it will live in the item slot (as its the one that spawns the menu).

First of all, Button widgets do not support double clicks…

So I use the button on click event here.

Use button on click event

And use the following implementation for checking if its double click

Simple implementation for checking double click

I am not sure why buttons don’t natively support this.

The main thing to look at here is that when we press a button we toggle a button pressed variable to ON if it wasn’t already. Then if you click again within 0.3 seconds, it will execute your function (in my case Equip Item with API.

Equip item with API

I tried to fit the blueprint into one image here so may look squeezed

Handle Equip item over API

What is it doing? It’s simply executing the following JSON request that we can see in postman, and asking inventory to refresh itself.

Equivalent call in Postman

i.e. we’re replicating the required headers and adding the body data, which has the Item Instance ID, for the item you wish to drop.

The Item Instance ID can be found from the Character Item payload in this case, which is already part of the slot information as it was used to draw the item.

The API requests for equipping items were covered in this blog posts in my case, but change them as per your requirements as different servers will require different inputs.

For Inventory refresh we also want to refresh the equipped items here so re-draw them incase we affect more than 1 item (e.g. 2h weapons can remove 2 slots etc)

Refreshing inventory will also refresh equipped items

Displaying equipped items

In the previous screenshot we can see that we’re asking the equipped items widget to refresh itself.

The equipped items widget is this one:

Equipped items widget

i.e. its a widget that references all equipped item slots (notice one is selected on left menu as example).

Each of the Equip Item slots is very similar to the item slots, but it has a slightly different design and the icons are drawn a little differently

Design for equip item slots

The way the icon is populated is via construct by populating an image into the content box component (border component).

Populating item into equipped item widget

This means that by default, when ItemInstance is not set, we will draw the EmptyWidgetIcon determined in the inventory menu

Set the Empty Icon Widget as exposed on spawn

If the Item Instance IS set, then draw the icon from the instance.

We have this on Refresh Widget custom event.

So this is how we populate the icons inside the slots themselves, and the Equipped Items Widget is the one that tells these slots what to draw.

Here’s the blueprints from Equipped Items Widget for getting the contents.

Equip Items widget – getting the data to draw – part 1

This API request is mimicking this request to the server:

Postman GET request to fetch equipped items

I also had to create a new structure to represent my equipped items model:

Structure for equipped items

And as usual I created a helper method for converting the VA Rest json response into this structure:

VA Rest JSON to structure for Equipped Item

As we can see, we’re able to re-use a lot of models and helpers here which is great.

Now for the extension of Equip Items widget blueprints we can reference the above.

Equip items widget blueprints – part 2, collecting data

The Populate Equipped Items custom event can be found here:

Populate Equipped items custom event

And lastly I created a custom function for returning the slot widget based on slot category here:

Get the slot widget by category

This Get Slot Widget By Category is getting the widget based Item category, which in my case is like BELT or CHEST etc.

And again for reference, it refers to the slot items in this EquippedItemsWidget

Equipped items widget – showing the equipped slots

Note here is also where we define the default empty icon to draw, when an item in not equipped.

Un-equip item from equip slot

The logic here is that when you double click the item from equip slot, we will un-equip it.

From the equip slot designer, find the button and add on clicked event

Find on clicked event on your equip slot button

In the same way that we handled equip, we check here if the button was double clicked

Check if the button was double clicked

When the item was double clicked, we call Handle unequip item custom event.

The event does the following

Unequip item over API

In a similar way, this is emulating the following API request:

Unequip item API request

Where the item instance ID is the item that’s referenced in the slot.

After its done, we just want to refresh all contents, for inventory, itself and the equipped widget.

Refresh relevant widgets

The custom events can be found here:

Refresh all data

This is essentially re-using all created blueprints to refresh themselves, i.e. as if you had to re-construct those widgets. This synchronizes the client with server.

Conclusion

We now have a basic connection of inventory with server where we’re able to pick up items, drop items and equip them.

There was some interesting limitations with buttons and I would actually advise people to potentially use border widget instead of button as some limitations are frustrating to work with.

E.g. next I’d like to do drag functionality for the item slots, but the button is consuming the left mouse button input so its not registered. This should not be a problem with border. Also for reference, they also have events similar to button for example on mouse button down.

Mouse button down event

The main reason I haven’t done this is because I’ve got my buttons programmed with different styling for normal, hovered or pressed.

Button styling

Note this can be achieved with Border as well, but its a bit more hassle as you’d have to override the hovered and pressed events to update styling. Long term this is still probably easier though.