Before start you should watch this tutorial from Epic. Creating Inventory isn’t so hard but it requires Arrays and Structs to work with.
What I would like to accomplish:
- Player will have his backpack which will be global inventory with all of the weapons collected,
- Player can choose which weapon he would like to use in mission,
- Inventory should be generic. I don’t know yet which weapons I will use and which stats they will have,
- Game should remember which weapons I’ve chosen so I don’t need to choose them again,
<strong>This Tutorial has been created using Unreal Engine 4.8.2</strong>.
Make sure you are working on the same version of the engine.
We should start by creating new Structure – WeaponBackpackItem. It should contain necessary information about our weapon:
- WeaponToSpawn (Actor) It will be reference to actor that should be spawned in Menu or begin play during gameplay,
- BackpackImage (Texture 2D) texture reference which we will use in UMG inventory,
- IsSelected (bool) This will tell us if this weapon was selected in inventory screen,
- InSlot (int) in which slot weapon was selected,
Basically you can add otherdata here like Damage, Price or whatever you like. I’m not doing this right now because I think I will have menu in 3D and detailed data will be directly in WeaponToSpawn Actor.
USEFUL TIP: When working on structures using blueprints you need to be careful. During this tutorial my editor crashed 3 times when adding new variables to structure or updating arrays which are using structure. There are some known issues with structures that are placed in arrays. Be sure you save your work often! Basically I recommend putting structs and all operations on them to C++.
Now go to ShooterGameInstance
- Create new variable from WeaponBackpackItem and name it Backpack_Weapons. It should be array:
Now let’s fill our array. Create couple of elements (I’ve created 5) and assign different textures. I’m using icons placeholders from here. Just for test. Make sure you have different textures assigned to each elements.
- Create new function: CanAddWeaponToWeaponSelected
– it should have one local variable: HowManySelectedItems.
– And it should return CanAdd (bool), HowManyItemsSelected (int)
– This function will tell us if there is a space in player inventory to select another weapon.
- Create another function: SetBackpackItemSelected
– It should have 3 variables in Input:
This function will update data in Backpack_Weapons. For now it’s setting only InSlot and IsSelected but it can be modified later. Basically you could just pass WeaponBackpackItem as input but for this tutorial I wanted to break this.
This is all in ShooterGameInstance. It will store our backpack weapons information so everyone can assign / or modify the data.
Now create new User Interface -> Widget Blueprint and name it UI_Debug_WeaponInventoryItem
Explaining UMG using text is difficult but I will try it 🙂 |This UMG widget will be our inventory icon. Let’s start by creating Hierarchy.
- Delete CanvasPanel. We will be adding this widget to other widgets.
USEFUL TIP: When doing that you should’t have CanvasPanel. CanvasPanel have information about anchors and our base widget will have those. Duplicating them can affect weird behavior in different resolutions.
- Add Overlay on top,
- Add Button with Horizontal and Vertical Alignment set to center. Go to Style and change Image Size for all of the Brushes to 150×150. Remember to change the Size for all of them! (Normal, Hovered, Pressed etc)
- Add Image which should have center alignment as well and size 130×130.
– Remember to set it as variable so we will have access in blueprint graph,
– Set visibility to HitTestInvisible,
We are making sure that our mouse events will go behind the Image and hit our Button.
Now let’s go to Graph.
- Create new Event Dispatcher: WeaponItemClicked which should have two inputs: WeaponReferenceIndex (int) and WidgetReference (User Widget)
WeaponReferenceIndex will be just an link to our Backpack_Weapons array index.
- Create new variable: WeaponItemReferenceIndex (int) which should have ExposeOnSpawn and Editable selected. Thanks to that we will be able to assign something to this variable when spawning Widget!
- Create another variable: IsInInventory (bool) and set ExposeOnSpawn / Editable as variable above,
- Create new Function: GetGameInstance which will return ShooterGameInstance and will be a pure function.
Being in graph create new event – Event Construct (it should be there already) and let’s do something with variables that we have set Expose On Spawn.
We are changing Image texture and we are disabling button if it’s selected. Simple enough.
Now select Button in Designer view and add OnClicked event.
In graph let’s call our WeaponItemClicked dispatcher.
Thanks to this dispatcher we will know in our base Widget that this button was clicked. This is all in this Widget Blueprint.
Now let’s move to the hardest part. We need to create an UI with all of our inventory items and items that we have selected. We need to implement selection functionality as well.
Create new User Interface Widget Blueprint and name it UI_Debug_WeaponSelection.
I’ve created short video demonstrating Designer Hierarchy, you can watch it here, but I’ll try to explain this by text as well.
- Add Overlay panel. We will show inventory items here so it should be big,
- Add Border and insert it to Overlay.
– Horizontal and Vertical alignment should be set to FILL.
– Brush draw as should be set to Border,
– If border is selected Margin should be set to 1!Thanks to this border we will see where is our inventory.
- Add ScrollBox and insert it to Border
– Horizontal and Vertical alignment should be set to FILL as Border,
- Add UniformGridPanel and name it UniformGridPanel_Backpack. It should be set to FILL as well,
That’s all for this overlay. Let’s move to another one.
Create another overlay and put it on the screen somewhere in bottom.
- Insert border to the Overlay like we did earlier,
- Insert Horizontal Box to Overlay and set alignments as FILL,
- Insert 3 Overlays to Horizontal Box and name them: Overlay_Slot_1, Overlay_Slot_2 and Overlay_Slot_3.
– Size should be set to FILL,
– Alignments should be set to FILL,
– They should have “Is Variable” so we can mess with them in Blueprint Graph.
That’s all here in designer.
Now let’s move to Blueprint Graph and add some variables and functions.
- Create three bool variables: FirstSlotTaken, SecondSlotTaken and ThirdSlotTaken – they all should be set to false by default,
- Create new function GetShooterGameInstance which should return ShooterGameInstance and should be pure, we have done this earlier so I won’t post screen here,
- Create new function FindFirstFreeSlot which should have one OUTPUT – Slot (int) and one local variable CurrentFreeSlot (int),
This function will return first free slot that we can use when selecting a weapon.
Event graph is to big for one screen. Let’s move step by step.
Create Custom Event – CreateBackpack with one input: WithoutSelectedWeapons (bool) try to copy this:
What this is doing:
- It’s iterating for all inventory items in Backpack_Weapons,
- Then it’s creating new widget “UI_Debug_InventoryItem” which we have created earlier. It’s passing data to the widget,
- We are connecting our WeaponItemClicked dispatcher.
- After that it’s adding new widgets to Grid Panel,
- And it’s setting column and row,
- Then it’s checking if the IsSelected true,
- If yes create another widget and place it to the Panels,
This should run only in the beginning of the widget. Here’s Construction Event which is firing CreateBackpack and letting us to select something using mouse.
USEFUL TIP: Event Construct will fire every time the widget will be added to viewport!
It’s setting IsSelected and putting IventoryItem to panel.
The last two dispatchers are connected to the same custom event: ItemClickedInBackpack
Which is removing items from selected weapons panel. It’s really hard to describe those using screenshots so here you can download my Blueprints folder. If you want to test this out just create widget UI_Debug_WeaponSelection.
Implementing game is taking time but writing about this is taking much more effort!