Chapter 10. Inventory System and Pickup Items

We want our player to be able to pick up items from the game world. In this chapter, we will code and design a backpack for our player to store items. We will display what the player is carrying in the pack when the user presses the I key.

As a data representation, we can use the TMap<FString, int> items covered in the previous chapter to store our items. When the player picks up an item, we add it to the map. If the item is already in the map, we just increase its value by the quantity of the new items picked up.

Declaring the backpack

We can represent the player's backpack as a simple TMap<FString, int> item. To allow your player to gather items from the world, open the Avatar.h file and add the following TMap declaration:

class APickupItem; //  forward declare the APickupItem class,
                   // since it will be "mentioned" in a member  function decl below
UCLASS()
class GOLDENEGG_API AAvatar : public ACharacter
{
  GENERATED_UCLASS_BODY()

  // A map for the player's backpack
  TMap<FString, int> Backpack;

  // The icons for the items in the backpack, lookup by string
  TMap<FString, UTexture2D*> Icons;

  // A flag alerting us the UI is showing
  bool inventoryShowing;
  // member function for letting the avatar have an item
  void Pickup( APickupItem *item );
  // ... rest of Avatar.h same as before
};

Forward declaration

Before AAvatar class, notice that we have a class APickupItem forward declaration. Forward declarations are needed in a code file when a class is mentioned (such as the APickupItem::Pickup( APickupItem *item ); function prototype), but there is no code in the file actually using an object of that type inside the file. Since the Avatar.h header file does not contain executable code that uses an object of the type APickupItem, a forward declaration is what we need.

The absence of a forward declaration will give a compiler error, since the compiler won't have heard of class APickupItem before compiling the code in class AAvatar. The compiler error will come at the declaration of the APickupItem::Pickup( APickupItem *item ); function prototype declaration.

We declared two TMap objects inside the AAvatar class. This is how the objects will look, as shown in the following table:

FString (name)

int (quantity)

UTexture2D* (im)

GoldenEgg

2

Forward declaration

MetalDonut

1

Forward declaration

Cow

2

Forward declaration

In the TMap backpack, we store the FString variable of the item that the player is holding. In the Icons map, we store a single reference to the image of the item the player is holding.

At render time, we can use the two maps working together to look up both the quantity of an item that the player has (in his Backpack mapping) and the texture asset reference of that item (in the Icons map). The following screenshot shows how the rendering of the HUD will look:

Forward declaration

Note

Note that we can also use an array of struct with an FString variable and UTexture2D* in it instead of using two maps.

For example, we can keep TArray<Item> Backpack; with a struct variable, as shown in the following code:

struct Item
{
  FString name;
  int qty;
  UTexture2D* tex;
};

Then, as we pick up items, they will be added to the linear array. However, counting the number of each item we have in the backpack will require constant reevaluation by iterating through the array of items each time we want to see the count. For example, to see how many hairbrushes you have, you will need to make a pass through the whole array. This is not as efficient as using a map.

Importing assets

You might have noticed the Cow asset in the preceding screenshot, which is not a part of the standard set of assets that UE4 provides in a new project. In order to use the Cow asset, you need to import the cow from the Content Examples project. There is a standard importing procedure that UE4 uses.

In the following screenshot, I have outlined the procedure for importing the Cow asset. Other assets will be imported from other projects in UE4 using the same method. Perform the following steps to import the Cow asset:

  1. Download and open UE4's Content Examples project:
    Importing assets
  2. After you have downloaded Content Examples, open it and click on Create Project:
    Importing assets
  3. Next, name the folder in which you will put your ContentExamples and click on Create.
  4. Open your ContentExamples project from the library. Browse the assets available in the project until you find one that you like. Searching for SM_ will help since all static meshes usually begin with SM_ by convention.
    Importing assets

    Lists of static meshes, all beginning with SM_

  5. When you find an asset that you like, import it into your project by right-clicking on the asset and then clicking on Migrate...:
    Importing assets
  6. Click on OK in the Asset Report dialog:
    Importing assets
  7. Select the Content folder from your project that you want to add the SM_Door file to. For me, I want to add it to Y:/Unreal Projects/GoldenEgg/Content, as shown in the following screenshot:
    Importing assets
  8. If the import was completed successfully, you will see a message as follows:
    Importing assets
  9. Once you import your asset, you will see it show up in your asset browser inside your project:
    Importing assets

You can then use the asset inside your project normally.

Attaching an action mapping to a key

We need to attach a key to activate the display of the player's inventory. Inside the UE4 editor, add an Action Mappings + called Inventory and assign it to the keyboard key I:

Attaching an action mapping to a key

In the Avatar.h file, add a member function to be run when the player's inventory needs to be displayed:

void ToggleInventory();

In the Avatar.cpp file, implement the ToggleInventory() function, as shown in the following code:

void AAvatar::ToggleInventory()
{
  if( GEngine )
  {
    GEngine->AddOnScreenDebugMessage( 0, 5.f, FColor::Red,  "Showing inventory..." );
  }
}

Then, connect the "Inventory" action to AAvatar::ToggleInventory() in SetupPlayerInputComponent():

void AAvatar::SetupPlayerInputComponent(class UInputComponent*  InputComponent)
{
  InputComponent->BindAction( "Inventory", IE_Pressed, this,  &AAvatar::ToggleInventory );
  // rest of SetupPlayerInputComponent same as before
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.205.99