Resource Based Inventory - Godot 3.2 Intermediate Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good morning afternoon or evening wherever and whenever you are my name is benjamin in this video we're going to be making a resource based inventory in the godot game engine by the end of the video you'll have something that will look about like this it will have the basics of an inventory where you can drag and swap items around in this inventory and these items will be based off of item resources and we'll get into that let's get started first you're going to open up godot and create a new project come into this folder here and i'll call this resource or we'll just call this inventory tutorial create folder i'm just going to use gles 3.0 and we're ready to get started we'll start in the project settings we'll come to our window we'll set it to 320 by 180 and we'll set our test width to 720 let's see 1280 by 720 we'll set our stretch mode to 2d and our aspect to keep just by default now if we come into a 2d scene we're going to create an inventory container this will just be a container that we can put our inventory scene in we'll do another node we'll we'll look for a color rect and we'll set this to take up the full screen we'll make it black then we'll call this inventory container we'll put a center container node in it like this make sure that takes up the entire rect as well and for and uh we'll save here we'll save this scene inventory container so this this inventory system uses resources like i said as the model for kind of how we're going to structure our code and so we'll start with the resources let's come over here and make a new folder we'll call this items and inside this folder i'm going to copy over some images and these images come into the folder oh i can't i can't do that let's see if i can just drag them in here and these images are going to be yep that seemed to work there i'll provide a link in the description where you can do that so we're going to need to re currently they're going to be blurry so we're going to need to re-import them so if you click on the image and then you go to presets and then do 2d pixel and then do re-import it will import that in properly and then we can do set as default and then we can re-import in each of these did that work it didn't we'll select all of them and maybe try 2d pixel re-import see if it worked okay so i held shift to select them all then came up here to import presets switch to 2d pixel imported them all now i'm going to select all of these make sure you don't select your background and delete them we'll come into our scripts create a new script and this will inherit from resource not from node i'll call this item dot gd and we'll give it a class name [Music] item and we can come and give it some properties that we want to be able to define on each item so we'll start with export string var name export texture of our texture that doesn't need to have a default now that we've created our first script that extends resource here we can come over into items and let's actually drag this into items that script so it should be here and come into items here right click do new resource and search item now it'll show up because of our class name because we gave it a class name it will show up here automatically we can double click on this and we can make our very first item we'll make it a sword so sword.tres now if i double click on this sword we're going to get our properties over here these variables for this item we can set the name to sort and we can drag our texture in and set the texture to that now we can do this for each of our items we'll create a new resource it'll be an item this one will be potion and then once i double click on potion i can name it and we can give it this uh image let's do that for each one here do it for our ring and one more [Music] tall shield who doesn't want a tall shield right tall shields are the best shields okay so then that allows us to define uh the difference so each of these resources is a type item but we're able to define different a different name in a different texture and i may go into this in later videos but you can add more things like descriptions or how many there are or whatever you want to this base item type let's clear that there okay so we've got our item resource and that's good that's a good starting point but now what we need is a resource for our inventory so we're going to create a new script again and this will also inherit from resource [Music] and we'll call it inventory we'll give it a class name [Music] and it's not going to have the same properties that we had for items because well in this case we're only going to have one technically there might be a situation where you would have more than one inventory but in our situation we're just going to have one but this data here this inventory class is basically going to have uh its main job is going to be holding the collection of items which will just be an array that we that we have it set to and then signaling out whenever one of those items gets changed so we'll have the data that will hold the items and then we'll signal out whenever an item gets changed that way our ui can properly update based on whatever changes were made so we'll start with our signal this signal will be items changed and it will take it will take an argument called which is going to be an array called indexes so that will just list off the different items that were changed so we might have multiple items changing at once and so we want to send out a signal saying okay item 0 and item 5 both got changed so update those accordingly then we'll have our export array and it will be resources and we'll save our items and this is oops this is going to be just a a 1d array now a lot of people are like well but at the start you showed that your items are you had nine item slots and they were in a grid right and yeah most of the time you would want to use a 2d array for your grid however godot's grid container node actually just uses a list of child nodes so it's not set up in any sort of a 2d array it's basically a single array so it's actually beneficial for us to use a 1d array just a single array in this case and we're going to set we're going to have 9 items and they're all just going to be null for now by default [Music] let's see how many how many i'm at am i at they're seven okay i think that's nine one two three four five six seven eight nine perfect now our inventory is going to have three different functions here so the first one will be set item and this will just take an item index and an item that we want to set and we'll just do pass for now we'll have a swap items this will take an item index and a target item index [Music] and we'll have a remove item and this will take an item index i'm going to check real quick just to make sure my audio seems to be working properly it looks like it does it looks like it is hopefully it's the right microphone and such okay so uh this will obviously just remove an item from the inventory so let's start with set item because it's the easiest our previous item equals items item index so this is saying okay when we set an item there might actually be another item there already so let's store that real quick so we'll grab the item that might already be there and we'll say items item index equals item so there we go we're setting the new item right we're taking this and setting it to this index then we're going to emit a signal emit signal items item changed that's items it's supposed to be items changed items changed in this case we only have the one item that has changed so we're just gonna do an array and it will be item index but make sure it's still an array even though there's only one item this still needs to be an array okay and finally the last thing we'll do is return the previous so as we're accessing the api for inventory here like as we're using this function we may want to have we may want to have the the item that was there before and do something it do something with it so we can return that back out just in case we want to do something with it now let's do remove items it's actually re remove item it's actually really similar so just we're going to actually copy paste this here so previous item that's the same but when we set it we just set then set it to null now then we emit the signal again and then we return the previous item so when they remove an item they also get access to the item that was there just in case they want to do something with it now we'll do swap items var target item equals items target item index so we're getting our target item our item equals items item index so we get the the first item so we're getting our target and our first item makes sense now we're going to swap them items target item index equals item and items item index equals target item there we go so we've swapped them now and finally we want to emit our signal emit signal items changed [Music] and then our array needs to contain both our item index and our target item index because they both got changed and that's it that's our inventory now we need to come into our resources over here do new resource look up inventory and we'll just name this inventory.tres now we have our inventory set up let's clear this i don't know what that was about okay we have our inventory container scene here and we have it's our center container here now we need to create an actual inventory display and this will be a scene that will display our inventory we'll create a new scene here we'll go to other nodes and we'll search for grid container grid container seems like a good pick for an inventory right for an inventory display and we'll name this [Music] inventory display we'll set its layout to take up the entire screen and we'll save this scene okay once we've done that we're going to create another scene here this will be our inventory slot so we'll do a user interface node here oops let's change that one actually do let's delete it other node and this one will be a center container and it will also take up the entire screen let's do corrector and we're going to give it inventory slot display we'll give it a name called inventory slot display and we'll give it a textureect texture correct and that will actually display our inventory item and this textureect let's let's start by giving it an item here we'll drag a potion in here just to display that and we want to give it a minimum size so we're going to come into and we'll give it into uh our rect here on the texture rect and you'll set the we'll actually name this item texture rect there we go and you'll set the min size to be 18 and 18. and the reason we're doing this is to make sure that even if this sprite image here is smaller it still displays on an 18 by 18 grid that will help our inventory be consistent and uniform so that's our min size there and we'll do stretch mode does this matter i don't think stretch mode matters we'll just leave it what it is for now actually it does matter it does matter and here's why uh we'll save this inventory slot display we'll come into i need to open up i forgot to grab one of the resources here so i'm going to grab that real quick this you'll already have this resource but we need the empty inventory slot drag that over empty inventory slot looks good okay [Music] okay so now we can see what an empty inventory slot is going to look like we'll select this i'll drag an empty inventory slot you can see it's clear up here in the corner the min size did fix it see if we didn't have min size on then it would be too small here so we did fix them in size but we need the stretch mode to be keep centered that way it'll stay in the center like that okay now if we come into our inventory display we're going to have three columns because we're gonna have nine inventory slot displays so let's do that we'll create we'll click on our instant scene here we'll do inventory slot display and then i can just click on this and do control d one two three four five six seven eight times to duplicate it and that will give us our nine inventory slots however they're clear up here in the corner uh we don't want them to do that so if we come into our inventory slot display here and we click on our center container we want to set our size flags to be expand horizontally if you come back here well we gotta save probably come back here you can see they expanded horizontally now and then vertically we won't expand as well now they expand out vertically so they take up as much space as they possibly can then we'll do our inventory display and we'll set our custom con constants to be 0 and 0 here and that just means that they'll uh they'll always have the smallest possible distance between them when it's when it's cramped when it's like condensed down so now if we take our inventory display and we come into our center container here for the inventory container and we instance our inventory display in here you can see that it gets compressed all the way down that's because it's inside of a center container but it takes up as much space as it can with each of these inventory slots being 18 by 18. so the min size here in our in here if we actually remove this you can see that our inventory gets really tiny and doesn't have enough space that's why the min size here is so important to set this to 18 to by 18. that's the minimum size that our inventory slot can possibly be can't be smaller than that and that gets this nice looking inventory again we should be able to run our game select our inventory container scene and get this visually so that's pretty cool so we've started working on the ui that will display the data that we created all right let's look at our data here so our inventory if we click on our inventory.tres has an array but all of these are empty so let's start by setting uh let's give us a sword and a couple potions maybe we'll drag in a couple potions here and we'll do a diamond ring and we'll do our tall shield we put it here maybe farther into our inventory so we just set some items in our inventory here let's run the game and nothing happens we're not seeing those items in the inventory why is that well because our inventory display isn't actually connected to the inventory so that's what we have to do now so let's attach a script to our inventory we're going to have to have a script for inventory slot display and our inventory display so let's attach two scripts one to our inventory display [Music] and one to our inventory slot display okay let's start with our inventory slot display and we're going to create a small little function here called display item or maybe update update display now let's call it display item i like that and it will take an item and all we'll do is we'll say if item is item so make sure that's not null then we need to get access to our item texture so on ready var item texture rect equals item texture act then we'll say item texture act dot texture equals item.texture else item texturerec dot texture equals load and then we'll do we'll do the empty inventory slot dot png like that okay might be good to preload this but for now we'll just do this so now we have a display item function inside of our inventory slot display now we'll come into our inventory display inside of here we need to get access to our inventory resource we can do this by pre-loading it and we'll grab inventory.tres so that will load this inventory data into our script here so we can do stuff with it and the first thing we want to do is in our ready function we want to connect to the items changed inventory dot connect items changed self and we'll connect to a function called on items changed now let's write that function it will take indexes and that will just be our array of indexes right we'll say for item index in indexes update oh and we got to do some we got to do we got to write some functions here so let's write a couple new functions that we're going to need the first one we're going to need is update inventory slot slot display item index it'll take an item index this is this function will just update a very specific inventory slot display so var inventory slot display equals get child item index so that will get the inventory slot display that corresponds to the item in the inventory var item equals inventory dot items item index that gets the item that corresponds to the item index that we got passed in for this function inventory slot display dot display item item and we we use the function that we created right here to properly display this item in this inventory slot display now we can call our update inventory slot display and we can pass in our item index so whenever an item changes right it will call this function that will update the it basically just says oh did the data change update the the display accordingly according to the data so that it matches properly with the data we're going to create another function here update update inventory display for item index in inventory dot items dot size this is going to loop through the entire inventory update inventory slot display item index and it will update every single one of them so that's something we also we want to do that right when the game starts update inventory display that way right when our our our inventory display loads it checks it loops through every single item in the inventory and updates each display slot so it updates the display to match the data now if we run our game we should see and we do see here that our inventory is being properly displayed and if we go change that inventory here so let's say we have another tall shield for example maybe we put a potion at the end so we make some changes and run that we now see those changes reflected inside of our inventory display here looks good now for dragging and dropping the items around we're going to use godot's built-in drag and drop functions that relate to control nodes and so the first thing we need to do is inside of our inventory slot display we also need to get access to our inventory inside of inventory slot display here we're going to have our inventory equals preload and then load the inventory.tres next we need to have a function called get drag data this function takes a position but i i never i don't use this position so i just put an underscore at the start so we don't get a warning there we're just going to pass for now and we need another function [Music] can drop data also takes a position that i'm not going to use also takes data we will be using that pass and finally we'll have a drop data function and this will take a position that we won't use and a data that we will use looks good right these are functions built into godot inside of the you the control nodes and you can actually look them up in the documentation if you want to read a little bit more about them i'm going to show you how to use them and kind of explain them in this video but there is you know it might be good to kind of supplement the video with the documentation might give you a better idea of how everything's going to work so first let's do can drop data because this is the easiest one this tells godot whether this ui this control node can accept drop data okay and drop data is usually passed as a dictionary i don't think it has to be actually but i usually do a dictionary that's kind of what they show in the documentation so we'll say return data is dictionary and data dot has item so this function will return true telling godot that this can accept drop data if the data is a dictionary and the data has an item in it so we know that the drop data is for an item pretty easy now let's do let's do our drop data right here this is the function that actually drops the data into our control node so we'll say var my item index will start by getting our own index bar well let's not let's not handle dropping the data until we gather it even though gather getting the drag data is a little bit more complicated uh i do want to do it first because then the drop part will make more sense so first we need to get an item index for the current inventory slot we're on so that we can just use get index [Music] this is actually the index of the inventory slot relative to the others here but it corresponds with the index in our inventory it'll be the same one once we do that we can get the item inventory dot remove item item index now remember how our remove item actually returns the item out we're gonna store it here now we're removing it from the inventory and storing it inside of this variable if item is item that's essentially a check to make sure that it's not null if this is null then we don't want to do anything with it our data we'll create an empty dictionary here and we'll say data.item equals item that will create a new key in our dictionary and it will store the item in that key which then makes this work right here because it will have an item data dot item index now we also want to remember the index that the item was in and that's going to be the index that we just got it from right here and we're remembering that in case we accidentally drop this item somewhere else we can return it back to where it was before so that's going to be in our data too now you could just return data here but it wouldn't show anything when you were dragging the item around the mouse would just be the item would be there but it wouldn't visually show anything so how are we going to visually show something well there's a function called set drag preview and we're going to use that but it takes a control node as an argument that will be dragged around in the room so we'll have to create one and we'll use a texture rect for this so var drag preview equals texture rect.new so create a new text direct drag preview dot texture equals item.texture since we have access to the item here we can grab its texture and make that the drag preview texture and then we can call set drag preview drag preview pass in the drag preview okay so we get our item make sure it's an item we create some data it gets removed from the inventory right then we set a drag preview this all should be working our drop data isn't going to be working but we can test the that we can grab it you can see we can now grab that it just doesn't work when we try and drop it nothing happens so let's get our drop data or let's uh let's do our drop data for handling when the item gets dropped we'll need an item index again so this is when this is when we're clicking on an inventory slot this is when we're dropping an item back onto an inventory slot so we're going to get our own item index [Music] we're going to say we're going to get our item too and then we're going to swap items with the item with the data [Music] basically [Music] my item index and data dot item index so what is this doing this is taking the data's item index which is where the item that we picked up where that was before right so let's say we pick up a sword now there's nothing there it's null we maybe we have an item here or maybe we're null it doesn't actually matter we don't care but let's say we have an item here like we have a potion this is going to put that potion where the sword was and it's going to take the null spot and put that right here so now we'll be left with a null spot and i can show you this actually how this looks so if we take this this shield and we try and drop it on this sword what's going to happen is it's going to swap this spot with this spot so this will become null and this will become a sword and you can see that happened so we swapped the null spot with the sword spot we swapped their locations and the shield just got forgotten about and that's not what we want we want to put the shield here so that's what we have to do next we have to say inventory dot set item and then we call my item index and data dot item so my item index is the place we're dropping it to right not the place that we got it from and we'll set it to the item that we have from the drop data now if we run we can see that it now swaps them properly there you go now this doesn't have item stacking we can't stack these potions we can't stack these shields that's a feature that i might want to explore in another video uh so we have you know a number that displays how many there now there's a bug here which is if we drag this out into space here it just gets destroyed and the solution that i came up for fixing this was to have our inventory container also kind of smart about catching data that gets dropped in it so this takes up the whole screen right the inventory container uh so we're going to give it a script and we'll give it two functions well we'll give it access to the inventory [Music] pre-letter preload our inventory again and then we'll say can drop data and we'll do an underscore under position here because we're not going to use it and we'll do the same thing we did before return data is dictionary and data dot has item so if the data has an item then yeah we can drop data here now what do we do when we drop that data well we're not going to use position again but we will use data inventory dot set item data dot item index data item we just set the item back to where it was previously at its old index now if we save and run i don't remember if this works just like this it doesn't now why doesn't it work well it doesn't work because our center container here is actually on top it takes up the whole screen too and it's on top of our inventory container here so we have to go into the mouse settings here and we have to have this ignore the mouse so our center container will now ignore the mouse that allows our inventory container to capture that mouse input and i think it'll work now if we drag this off the screen you can see i haven't tried dragging it clear off the screen that doesn't seem to work so there we go we've got the basics dragging and dropping this around i do think uh i'd like to make a follow-up video to this i don't know for sure if i will honestly but i would like to so we'll see how things go i'd like to make a follow-up video to this because i think it could use a little bit more refining and polishing but this does give you the general idea for how i do my inventory systems in my games which is i i use data they're very data uh oriented i use resources for each of the items and i use an inventory resource for that and then whenever that inventory changes it then signals out and whatever ui needs to know will get that signal and update accordingly update visually accordingly that's kind of my system hopefully you found this video helpful and you learned something from it it was a bit of a longer video but i think it was an interesting one and it talks about some more advanced techniques and features inside of godot and i think those are interesting to cover so let me know if you enjoyed it be sure to like the video and subscribe i do also want to mention i haven't i mentioned in a community post but i haven't mentioned here that my one bit get out course right now i think is 97 off so it's almost 100 off you can get the course for much cheaper uh and so i'll have a link at the end of this video a link in the description where you can check out that sale the sale ends at the end of this month so it's getting close to an end here i've had a bunch of people sign up which has been a little bit more work for me in regards to doing support on discord but that's a good thing that's a good problem to have i do enjoy doing that support and working students through any questions they might have even if it's not related to the course sometimes and so that's a big benefit that you get with the course is access to my private discord server for support so if you're interested in that be sure to check it out and i will talk to you all later
Info
Channel: HeartBeast
Views: 47,466
Rating: undefined out of 5
Keywords: Tutorial, RPG, Pixel Art Game, Indie Game, Game Development, Learn gamedev, Gamedev, Inventory, Resources, Godot Scriptable Objects, Godot Tutorial, Godot 3.2, Intermediate Tutorial, Long Tutorial
Id: rdUgf6r7w2Q
Channel Id: undefined
Length: 42min 0sec (2520 seconds)
Published: Thu Sep 24 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.