endresult_1

In this post, we’re going to implement a basic Inventory System in C++. Create a First Person C++ Project Template and make sure to have a cup of coffee nearby because this will be a lengthy tutorial!

Before we dive in to type our code, here is the end result:

Since our Inventory System includes glowing effects, inputs and user interactions we will breakdown the functionality in order to avoid confusion. This means that we will create our system using the following workflow:

  1. Create a minor aspect of the system
  2. Test its functionality
  3. Repeat

Eventually, by merging all the minor systems, our Inventory System will be working just like the video above.

Throughout the tutorial I’ve used some very basic Assets. You can download them from here.

Moreover, you can find all the source code of this tutorial here.

Setting up our Pickup Class and creating the Glowing Effect

The first thing we’re going to create is the Glowing Effect of our Pickups. When your First Person C++ Project Template loads up:

  1. Add a new C++ class based on the Actor class and name it Pickup.
  2. Inside the Pickup’s header file type in the following code:
Then, switch to Pickup’s source file and inside the constructor initialize your static mesh component and  pickup texture like so:
When you’re done with that, add the following implementation of the SetGlowEffect and Interact functions:
Save and compile your code.

The SetGlowEffect function will make sure to highlight the static mesh of our pickup. This will work when we setup our Post Process effect in the Editor.

Switch to your Editor and create some pickup classes. I’ve created 3 pickups each with a different static mesh and item texture. Everything is included in the .zip file at the start of the post.

Adding a Post Process effect inside our Level

Before we setup our Post Process we need to make sure we have the right material in order for our items to Glow. For my project, I’ve used the material named M_Highlight from 4.8 version of Content Examples of UE4. In case you don’t have this version, the material is included inside the ziped file at the start of the post.

To add the downloaded material inside your project, close your Editor and copy the file inside the Content folder of your project. Then open up your project and the material will be where you’ve copied it.

In case you’re working with 4.10.4 version of UE4 the First Person Map will already include a post process volume. If you’re working with another version you may need to place one yourself. When you have placed a Post Process volume, setup the following options:

PostProcessSettings

Click on the image to enlarge in a new tab

To sum up:

  • Select the Blendables option and add the material you’ve downloaded. (Make sure you select the Asset Reference option when prompted)
  • Mark your Post Process volume as Unbound.

That’s it. We’re done with our Post Process. Let’s move on to our character setup in order to complete the Glowing effect!

Setting up our Character

Open up the source file of your character and add the following code:

Don’t forget to add the “Pickup.h” include right before the .generated.h file.

Switch to your Character’s source file and type in the following code for the above functions:

When you’re done with that, create a Blueprint based on your Pickup class and place it somewhere in your Level. Then, test if the glowing effect works as intented.

Setting up the pickup functionality

After setting up our glowing effect, it’s time to create the pickup functionality for our Character. Go to your Project Settings and add a new Action Mapping named Pickup. Then assign a keybind of your liking (I assigned the button E) like the following screenshot suggests:

action_mapping

Then, go to your Character’s header file again and add the following code:

Moreover, right after your #includes add the following line:

Since we will attach UMG to our Inventory later on, we need to create a somewhat hardcoded value for the total number of the items that a character can pick up. However, by defining a value and use that instead of a hardcoded value is somewhat more flexible for future use.

Then, inside your character’s begin play function, right after the initialization of the last seen item, type in:

Moreover, go to the SetupPlayerInputComponent function and add the following mapping:

Then, implement the PickupItem function:

In case the Inventory is full and there isn’t a nullptr Item inside our inventory the Inventory.Find function will return INDEX_NONE instead of the AvailableSlot. In this case, this means that the engine is telling you that your TArray of items doesn’t have an available slot for a new item.

 

Right now you have the pickup functionality of you inventory. Place a couple of pickups inside your map and test it and make sure their default static mesh/materials are different. The Inventory is exposed so you can test what’s happening inside your inventory from within the editor!

Setting up our Project for the UI logic

In order to create a functional inventory with it’s dedicated window we need to add UMG to our project. However, before doing that, we need:

  1. A Controller to communicate information between our Character and our UMG logic
  2. A GameMode which will tie our Character and our Controller together
  3. A User Widget responsible for the whole Inventory
  4. A User Widget responsible for each individual inventory item

Before adding any classes, go to your project’s header file (I named my project InventorySystem so I will select the “InventorySystem.h” file) and add the following includes:

Moreoever, locate the [YourProjectName].Build.cs file and replace the following line from:

to:

Save and compile your project.

Then, switch to your editor and add the following C++ classes:

  1. A PlayerController (name it MyPlayerController)
  2. A UserWidget (name it InventoryWidget)
  3. A UserWidget (name it InventorySlotWidget)

When you’re done with that add a Blueprint Game Mode and named it BP_MyGameMode. In this case we need the game mode just to tie the controller and the character together. Since we won’t need any C++ for that we will add a blueprint instead.

After you have completed all the steps above, create a Blueprint which is based on the MyPlayerController (I named mine BP_PlayerCon). Then, open up the BP_MyGameMode and tie everything together like the following screenshot:

bp_gamemode

Now that you have completed this step, go to your map and inside the World Settings assign the BP_GameMode.

Setting up our Inventory Slot User Widget

Open up the InventorySlotWidget.h and add the following code:

Switch to your source file and add the following implementations:

Then, switch to your Editor and create a Bluprint based on the InventorySlotWidget and name it UW_InventorySlot. Open up the UMG editor and:

  1. Place a button which covers the whole area
  2. Inside the button place an image which covers the whole area
invslotwidget

Click on the image to enlarge in a new tab

Here is the end result:

I know it looks like an abomination but please bear with me. After that Select the Image you’ve placed inside your button and in the Appearance menu, make a brush binding to the ItemTexture property we’ve created inside our C++. Here is an image to make things easier:

inventoryslot_img

Click on the image to enlarge in a new tab

We’re done with our Inventory Slot Widget, for now at least!

Setting up our Inventory User Widget

Open up the InventoryWidget.h and add the following code:

Save and compile your code. After that, create a Blueprint based on the Inventory User Widget and name it UW_Inventory.

Open up the UW_Inventory and create the following UI:

inventorywidget_hierarchy

Click on the image to enlarge in a new tab

Again, I know it doesn’t look like much, but bear with me!

Each InventorySlot is a UW_InventorySlot and has the Vertical and Horizontal Alignment set to Fill. Moreover, make sure you enter the following values for your inventory slots:

  • All Rows set to 0
  • For InventorySlot_2 set Column to 1
  • For InventorySlot_3 set Column to 2
  • For InventorySlot_4 set Column to 3
inventory_eventgraph

Click on the image to enlarge in a new tab

When you’re done with that, switch to your Event Graph and add the following logic:

We’re done with the Inventory Widget for now.

Go to your Editor and specify a new Action Mapping named Inventory.

Then, open up the header file of your character and add the following function:

Then, switch to your source file and add the “MyPlayerController.h” file. Moreover, locate the SetupPlayerInputComponent and add the following line of code:

When you’re done with that, add the following implementation of the HandleInventoryInput function:

Don’t compile your code yet because we have yet to write the HandleInventoryInput function for our controller.

 

Open up your Controller’s header file and add the following code:

Don’t forget to include the “InventoryWidget.h” file.

Then, switch to the Controller’s source file and add the following code:

Don’t forget to:

  • Add your Character’s file and
  • Change the line 15 to match your character!

Save and compile your code!

Go to your Editor and open up the BP_PlayerCon and set up the UW_Inventory as a reference:

controller_ref

At this step we’re ready to test our code. Place some BP_Pickups inside your level and don’t forget to setup a texture for each and every one of them. Otherwise you will not be able to see your Pickup’s Texture!

Here is my end result after picking up 2 items at this step:

endresult_1

Click on the image to enlarge in a new tab

Since we have the base functionality we now need to update our code. In the next section we’re going to implement a Pause system so that the game won’t continue until you either close the inventory or select an item.

Setting up a pause state

In most games, when the player has an open inventory the game pauses. We would like to achieve this functionality. To create that, we need a bind that gets called even though the game is paused. In order to achieve that:

  • Navigate to your Character .cpp file and locate the function SetupPlayerInputComponent
  • And replace the Inventory action mapping:
with the following code:
Now that we made sure that our Inventory Bind is executed while on pause, let’s add the following features:

  • Pausing and unpausing the game
  • Showing our Cursor
  • Consume Inputs for our Inventory Slots Widgets

To do that, navigate to MyPlayerController.cpp and make the following changes in the HandleInventoryInput:

With the above code we have achieved the Pause and unpause as well as showing and hiding the cursor of our game. You should compile, save and test your code at this state! Let’s move on and create the logic for our Inventory Slot Click status.

For this case, we won’t create a system that will make our Character actually equip our awesome cubes. However we will create a basic Equip functionality just for demonstration purposes.

Navigate to your Character’s header file and add the following code:

Then switch to the Character’s source file and add the following implementation for the SetEquippedItem function:

We’re done with tha Character. Locate the InventorySlotWidget.cpp file and add the following implementation of the SetEquippedItem function (remember that we’ve left that empty):

Don’t forget to include the Character.h file and replace my character’s class to fit your needs.

Save and compile your code. Then, locate the UW_InventorySlot Blueprint and select the Button we’ve added. From the details panel locate the OnPressed event and click the “+” Icon. Then, implement the following logic:

uw_inventoryslot_graph

Save and compile your Blueprint. You now have an Equip functionality!

Creating the Drop Pickup Functionality

In this post we’re going to create a drop functionality. Specifically, the character will be able to drop the currently equipped item. Let’s start!

Add the following function inside the header file of the character:

Then, switch to your source file and add the following implementation:

Don’t forget to add:

  • An Action Mapping using the Editor and its corresponding button
  • The binding inside the SetupPlayerInputComponent that points to the above function!

If you’ve made it so far, I would like to thank you for reading my tutorial! Have fun!

Share postShare on Facebook34Tweet about this on TwitterShare on LinkedIn0Share on Reddit0