In this post, I will demonstrate how to place an interface over the game screen. However, I will not go into details on how to create this inventory user interface. In a future post, I will demonstrate how to interact with the inventory. For my game prototype, I want to achieve something simple, like this:
Pretty simple and ugly, but will work for now.
Drawing the Interface
To draw the interface, I created two Widget Blueprints, I can create a new one through the contextual menu in the content folder.
I created a simple interface using two Widget Blueprints: one called WBP_InventoryItemUI and another called WBP_InventoryUI.
WBP_InventoryItemUI: it is used to draw each object space in the inventory with its image and text if there is a collected object. This UI element contains a Text block and an Image, both of which I marked as variables so that I can access them later by their name.
WBP_InventoryUI: it is used to draw the inventory with its object spaces. It has a UniformGridPanel marked as a variable so that I can access it later by its name.
New Inventory Component Variables and Initialization
The InventoryComponent has more variables and a little initialization in the BeginPlay event:
ShowingInventory: a boolean to determine if the inventory is showing. In the future, it will be useful to change the control behavior from moving the player to moving the inventory.
MaxItemColumnIndex: a number to configure the number of columns in the inventory. It starts counting at 0, so if I want 4 columns, I must put the number 3 here.
InventoryUI: to select the widget to create on the screen when showing the inventory.
InventoryItemUI: to select the widget to add on the inventory for each object space.
InventoryUIInstance: to save the UI instance for the inventory.
In the BeginPlay event, there is a little initialization to avoid doing it every time the inventory is shown.
Showing and Hiding the Inventory
I configured a button to show and hide the inventory when pressed. In the ThirdPersonCharacter Blueprint, in the EventGraph, it is called from InputAction_Inventory:
When the button is pressed, the inventory is shown or hidden, depending on whether it was previously showing or not. I used the PlayerInventory component directly from the ThirdPersonCharacter to determine if the inventory is showing and launched its ShowInventory and HideInventory functions.
The ShowInventory function is in the inventory component and looks like this:
It first sets the ShowingInventory variable and then calls the ConfigInventoryItems function that will populate the inventory. Finally, it shows it in the game.
To hide the inventory, I have the HideInventory function, which looks like this:
It first sets the variable, then removes the interface from the screen and finally clears all elements inside the grid using the InventoryGrid element that was previously marked as a variable in the InventoryUI widget.
Configuring Inventory Items
For each space in the inventory, I will add an InventoryItemUI widget. All this logic is executed inside the ConfigInventoryItems, which is called from the ShowInventory function and looks like this:
This function has two private numeric variables, ActualColumn and ActualRow, to control the item's position within the inventory. It starts with a loop that will continue until the inventory is fully drawn. On each iteration, it calls the creation of a new widget that will represent each space in the inventory, then configures it with an empty space or a collected object by calling the "ConfigInventoryItem" function, and finally adds it to the grid by calling the "AddConfiguredInventoryItem" function. This latter function uses and modifies the private variables "ActualColumn" and "ActualRow" to add the next element in the correct position.
Let's examine the "ConfigInventoryItem" function in more detail:
In this function, we receive two variables from the outside: the created widget to be configured, and the index at which to find the corresponding collected object. If there is a collected object in the "InventoryItems" array at the desired index, then the function will configure the name and image to be displayed in the UI by using the widget's public variables. Regardless, the function will return the widget.
Finally, let's look at the "AddConfiguredInventoryItem" function:
This function receives three parameters: the widget to be added, the row index, and the column index. It uses the public variable "InventoryGrid" that we configured in the UI to add the item widget in the desired row and column, and then configures the widget to fill all possible space. Finally, it increases the column and row numbers to use them in the next iteration (the row increases only if it reaches the maximum column index).