[Music] hello and welcome to this tutorial Series in this series we're going to be covering how to make a Minecraft style inventory system in the system we're going to be able to have a backpack chest uh hot bar going to be a to pick up items from the ground we're going to have them stack going to have different Max stack sizes also going to be able to split Stacks combine stacks and drag and drop stuff out of the inventory the way this two tutorial system is going to work is it split into seven Parts there's eight videos in total cuz I've got like a part 5.5 which will come out midweek um on that week and that's a code review so at that point in the project I'm just going to go through all of the code and kind of refresh ourselves what all of the codes do in so there's eight videos but seven Parts each video is going to come out here on YouTube weekly but the full series is recorded and it's available over on patreon.com dpos so if you want Early Access you can support me me over on patreon and you'll get the full series right now and at the end of each episode I've exported the scripts for like as they were at the end of that episode and again if you support over on patreon you'll get access to the scripts as well as Early Access the link for that is in the description below if at any point you get kind of confused or loss you want a bit more information uh leave a comment under that video or join the Discord server which again is linked in the description below NE me or someone else in the community will be able to help you hopefully solve the issue that you're having some things that this series isn't going to cover is just a set expectations is there's no saving and loading of the inventory that's almost like a save load system is almost its own of the series and there are lots of tutorials out there that would allow you to do that but if this series is well received and there's a lot of support um I I am thinking of doing an expansion sort of video series to this to show you how to make a save and load system and save our inventories some of the things I might do in the future with this course is I I wouldn't mind to do like a shop inventory system where you can sell and buy items but again that's not included in this video it's a big time commitment to make series like this where they're all done kind of in advance so I didn't want to go too far into a complex system people not like the series so if you do and you want to support these videos make sure you share and like them and comment and if they're positively received then I will do an expansion so save load MPCs but let's just jump into the project I'll show you exactly what we are going to have by the end of this course okay so you can see that we've got our um Tomatoes here on the ground we can pick them up and they can stack by holding down the shift key we can split a stack so we can take two off that stack and have it you see that we can now combine stack so I can press the two and put it on the three they become five if I split them again so the maximum stack of these Tomatoes is five if I try and combine the three with the three it'll fill one stack up to its maximum and it'll leave one stack on it on the mouse which I can then Place back down we can also come up here and we can get these potatoes these don't um stack at all they've got a Max stack size of one so they just uh you know go into the next available slot you see our hot bar is full now if I press B and bring up our backpack when we start to walk over stuff now it'll go into our backpack so I can pick up these other potatoes and these other tomatoes so they're all all of the tomatoes I know there's two more here so if I pick up these so this stack is now full and this spare one went into our backpack I can come over to these chests here and open the chest and you've got our chest panel here and this is the large chest we've also got the small chest and this fills out dynamically these panels don't have any slots in them and it responds dynamically to the inventory system that you pass into it then of course I can move stuff out of my backpack over into the chest I can take out the ones from my heart bar and place them in the chest I can come over here and open this chest place in some potatoes and press escape and walk away from them go back open up the chest and we've got our chest the stuff that we stored in our chest here so I can take them back out take these potatoes out I can even split this stack place it in here put the other part of the stack into this chest I can open up this chest take these back out and then combine them back into this chest so with the all kind of Link in you can move stuff through dynamically the way these work is it's not drag and drop it's you can click once on a slot and then it follows the mouse around and then we can click to place it back in a slot so this is where we're going to be at the end of episode 7 and each uh episode's going to cover a different topic so part part one and two are going to be about creating and finishing the backend sort of Code system part three we're going to create the UI part four will be about interacting with the UI and being to click on different slots part five we're going to be splitting and combining the stacks part 5.5 which will come out midweek is a code review just to go over and make sure that we're all on the same page with the code part six is going to be creating the chests and then part seven we'll be creating the player backpack system so with all that said I hope you enjoy the series episode one is up now on YouTube as I said the full course is already available over on patreon and going forward here on YouTube episode 2 will release in a week and then episode 3 a week after that Etc so make sure you subscribe to see them as they go up and in the meantime thanks for watching and I'll see you in the next one [Music] bye hello welcome to the first video in the inventory tutorial series if you haven't watched episode zero I highly recommend doing that cuz that's just going to go over kind of an introd ction to the system uh demoing how it works as well as talking about kind of the skill level um that this tutorial is aimed at and how you can get the access to the files and all that sort of stuff so if you're coming across this video and this is the first one um I do recommend watching episode zero but with that said let's just get straight into uh episode one this first video or it may be two videos we'll see how we get on it's actually going to cover the system part of our inventory system the way to think of this is you know we've got um the code the code version all the one zeros this is the uh the system and then we've also got the um you know the UI element this actually going to display our inventory as you would expect in a game so there's going to be an inventory screen with different inventory slots each of these slots will have an item in it um and it'll have an amount of the item which is the the stack amount so we're going to be covering this part in the first sort of one or two videos and then once we've got the framework for the system set up we'll start to build on the UI and as we need new functions um of the system from the UI for example um splitting a stack is something that we'll need to do we can go back and we can um add this to our system and expand in our system but we need a framework first for the UI to have just something to display in the first place and the way the system is is going to work is there's going to be three parts there's going to be a inventory holder think of this as uh you know we've got a player and then they've got their hot bar which you could think of as a utility belt they they might have a backpack you see a holder can have multiple uh systems and that's different to the actual the inventory system is all of this but they we will have a class called invent inventory system hopefully that's not confusing so we've got the code system and the UI sort of representation of this system and then we've got a inventory holder which is our player with a backpack and hot bar utility belt uh this could also be you know a chest will hold an inventory system so the system is going to be a container for all of our inventory slots so you can see on the UI representation we've got the inventory system and then it's made up of different slots so system and Slots kind of go hand in hand here to talk about them so we've got the holder which is like a player or a chest that can have one or multiple systems and a system is made up of one or multiple slots so again the system is a container for slots and an actual slot is one of these individual squares so you know we've got our inventory slot which could have a that's a really bad sword but has got a sword in it and uh they've got two swords in their inventory slot in another slot they may have a potion and they could have five potions and they can have as many slots as they want um in each system and you can have multiple systems so a chest would have a system with say 10 slots the hot bar has got um you know normally in a game you'd have a hot bar across the bottom of the screen like this each and it'd have a number of slots on it and the player B to play press 1 two 3 for all the way through to zero on their keyboard so that's 10 slots so a hot bar would have 10 slots back pack could maybe have 20 the chest could have uh 15 slots in it so each of these holders has the systems which have the slots inside them and hopefully this will make sense as we start to build upon this and it's this kind of system that allows us to have stackable items so each slot is going to keep track of the item it has and the stack size and we can Define how big this stack size can get within the sort of items property so the item may be flagged to have a Max stack size of uh five so our potion here say we've got a Max stack size of five and we've got five in our inventory and then we pick up another potion on the ground um we can see that this is currently at its maximum capacity so we'll just fill the next next slot with the potion that we've just picked up so hopefully this all makes sense if it doesn't or you want some more clarity let me know in the comments below and I can do some follow-up videos to talk about this as I said as we actually go through the code um hopefully this will all start to begin to make sense so let's just jump over into Unity okay so this is just a blank 3D project uh within Unity you know we could have had a 2d project it doesn't matter which pipeline you're using just create a new project um and just so you know uh not again not that it should matter but I'm using Unity 2020.3 22 F1 the first thing we want to do is um you know we we need to Define what exactly an item is uh just so we can have something to store in an inventory so I'm just going to right click and go to create folder and I'm just going to and I'm just going to call this script and within our scripts folder I'm just going to make a new folder called item scripts I'm just going to right click here create C script and I'm just going to call this uh inventory item data I'm just going to open this up in visual studio so the first thing to do with our inventory item data is to get rid of mon behavior and we're going to derive from scriptable object which means we don't need these and to make these uh visible in the inspector we just want to come up here and open the square brackets and go create asset menu uh menu name is equal to uh inventory system slash inventory item so now when we go back over to Unity uh we can go I'm going to go back to our asset folder right click create uh folder and I'm just going to call this scriptable objects and now we can right click create inventory system and we've got our inventory item which I'm just going to call test item you can see that there's no sort of properties on that just yet and so we can go ahead and create those for the inventory system um all we're going to really care about here is we need a public Sprite for the um items icon and we need a and we can define a public int uh for our maximum stack size so for this tutorial these are going to be the only things that we need to use however this is going to feed into the rest of your game presumably so um when defining an item some other stuff you may want is a public int um you know ID uh public string for the display [Music] name uh you could have a text area uh with a description and you know you can Define whatever it is in your uh game an item is you may have an item type or a weapon type um or armor type uh you know whatever you want your inventory item to be that's that's down to you but uh the ones that we're going to use actually in the inventory system is an icon so we can see what item we've got in the inventory and then we need a Max stack size um which as I explained will Define how many of that item uh an inventory slot can actually hold just going to make sure that's saved and let's go back over to our inventory system uh project then I'm going to go back to scriptable objects and you can see that our test item now has an ID a display name description uh a slot for an icon and a maximum stack size for now I'm just going to put five in the maximum stack size and we'll import some Sprites later on when we need them I'm going to leave ID alone but for this I'll just say test item one and this is a test test item okay that's great so um I'm going to rename that to test item one and then we can make a another inventory system inventory item and we could say test item two test item two description this is another test item and we can hold one of these this has got a Max stack size of one right so we've defined what um an inventory item is now so now we can make a slot to actually hold the item so let's go back over to our scripts folder and I'm just going to right click create um folder and I'm going to call this one the inventory script open this up and then I'm going to right click create cop script inventory slot again this isn't a mono Behavior it's not going to sit anywhere on the scene um so it doesn't need the monor behavior it doesn't need start or update uh what it does need is um it needs to be marked as system. serializable so we can actually see these in the inspector then I want to serialize field again so we can see these um in the inspector I want a private inventory item data which is that scriptable object we've just made and I'm going to call this item data and then we want a serialized field private in called uh stack size so this this is going to keep track of how many of the item data we've got access to and then I'm just going to make some public properties so we can get this uh stuff elsewhere so I'm going to say um inventory item data equals item data not equals sorry we use this um use this separator for the expression body definition and then we want to do the same for the public int um stack size so we can't accidentally change these from outside the script but we can get a reference to them using the public properties and then we need uh when we're making an inventory slot uh what we do want to do is we want to make a Constructor so we can say public inventory slot and this is going to take in some um Source data uh for example test item one test item two um sord of Doom uh whatever the inventory slot is going to contain um we can pass in a source and we can also pass in an amount of the item if we want to uh construct it with more than one item so item data equals source and then we can say stack size is equal to the amount that we've passed in but I'm also going to want a public inventory slot uh with no parameters that sets the item data to null and stack size is oh stack size equal to -1 so that's essentially null as well and the reason we're doing this is because if we go back over here our bag or you know the hot bar the hot bar has the slots on it regardless of whether there's an item in them these are all slots that exist but there's no item in there so there's null so my mouse now instead of my uh tablet so the item is equal to null even though the slots there there's no item in it and it doesn't have any amount in it either so we'll set the uh amount to minus one just so we know that that's also null as well and we can check for that if we need to anywhere down the line but these slots they they exist they're they're made they're ready to go they're ready to hold an item but in their default empty State they don't have anything in them that we can make an inventory slot with nothing in it or we can make one that's full of stuff and give it an amount of that stuff and actually what's probably better is we may want to um clear a slot as well at some point down the line so we can say public void clear slot and then we can actually do this here and then just call clear slot from our um Constructor and then we're not having to write this code out again because we probably want to be able to empty out a slot for example if we if we delete an item we can just clear this slot instead of creating a new slot and replacing replacing them we can just set this slot back to empty and then um what we want to do is we can make two methods here so we can say public bull add to stack and we can say int amount and then we can just say stack size plus equals amount and and public void remove from stack and we can pass in an amount as well and this will be stack size minus equals the amount that we're passing in and before we add to the stack it's probably good if we have um a method that checks whether there is actually room left in the in the stack and if there's not going to be enough room in the stack for the amount that we want to pass in um then let us know how much room is actually left in the stack we can just make two more methods here so we can do a public bull room left in stack which will take in the amount to add and it'll pass back out the int uh amount remaining I'm going to make another version of this method that just takes in the AM uh the amount to add cuz we may not always need to know how much is remaining um so we can just do public bll room left in stack and make sure these are named the same and this will just take in an amount to add so we'll do this one first so we can say if stack size plus the amount to add so if we've uh if we've picked up two of an item we're going to pass in two on the amount to add so stack size plus amount to add is less than or equal to the item data which again is that scriptable object we've made uh the item data. Max stack size then we can just return true because if we add this amount to the stack size then we're not going to encroach on the maximum stack size size so if our maximum stack size was five we had a stack size of three and we tried to add two to the stack then that would equal five so that'd be fine cu the stack would be it would have room left in the stack to add this amount to it so it's just going to return true otherwise there's not enough um room in the stack so we'll just return false so for example if this was four and we tried to pass in two and the maximum stack size was five then four plus 2 six that's bigger than the maximum stack size there's not enough room left in the stack for this amount so for this version we can just return our other version of the method passing in the amount to add but we also need to pass back out the amount remaining and the way we can do that is we can say amount remaining is equal to the item data do Max stack size minus stack size and we'll need this later on for splitting stacks and combining stacks for example using this um as an example again if the maximum stack size was five the current stack size was four and we were trying to add two to it which would take it to six we want to combine the items and leave one item kind of on the mouse so just to explain that from our test project if I pick up some items here so the maximum stack size for these Hearts is five and I've got three here and I'm going to pick up three and I want to combine them together so I'm going to place two from the mouse and leave one on the mouse so I'm going to go up to the maximum stack size you see that we've added two we've got one left we put that back down but I can put the four on the one which brings it to five and that's all done through checking the whether there's room left in the stack and then we will we'll work that out um later so it's good to have these here now but we won't use them till a little bit later on and there's one more method that needs to go into the inventory slot class and that's about how to split Stacks but we'll come back to that when we actually need that one so with that done let's go back over to Unity and we're going to create another um script so now we've defined what exactly a slot is and that we can clear them and manipulate them in some way we can right click create C script and we can start now uh working on our inventory system as in the system that holds the slots so again this isn't going to be a mon Behavior so we can get rid of that and we can get rid of the stting update and again we want this to be system do serializable and then we can do serialize field and this is going to be a private list of inventory slots so this is going to hold the amount of inventory slots that we that we want so inventory so we can just call this um inventory slots and then we want a private int which is going to be our inventory size which we're going to pass in from our holder which we'll set in the inspector so just private in inventory size and we just want to make a public getter for our public list of inventory slot and I'll just call this inventory slots and it will return our inventory slots actually we can get rid of the private int inventory size and what we could do we can do a public int inventory size and then we can pass back our inventory slots. count which should be safe to do because when we make a new because in the Constructor when we make a new inventory system we will be taking in a size and that will set up the inventory list as the very first thing it does so that should be safe we also need to add to using statement so we're going to be using Unity engine. events we can alert whoever cares that R our inventory has changed I'm going to be using system. link um to do some stuff as well so we'll uh include that in our using statement so then we can make a public inventory system Constructor which is going to take in a size all this is going to do is it's going to create an inventory slot list passing in the size that's come through it now list you know they can grow and Shrink but we know we're going to need this many so we may as well just do it now and construct the list with the size and then we can just say for INT I equal z i is less than size I ++ and then we can do inventory slots do add new inventory slot and we're going to make an empty one which is going to be null and with a stack size of minus one so that's our inventory system done so when we' create a new inventory system we're going to pass in the size of the system and then that's going to make um enough inventory slots to fill fill the system sorry I forgot we didn't put our action in after I said we would so we're doing a public Unity action and we're going to pass in the slot that changed uh on inventory slot changed so this is going to be an event that fires when we add an item to our inventory so let's go back over to Unity again and now we can Define um our inventory holder so again uh C script inventory holder and I'm just going to mark this as system. serializable this can be a mono Behavior okay so in our holder script we just need to make a serialized field private int inventory size so we're going to set that in the inspector and again here we need to be using Unity engine. events and this is going to come into play later um but we're just going to make a public static Unity action passing in uh an inventory system and this is going to be on Dynamic inventory display requested so just ignore this for now uh you know it kind of says what it's going to do on the name of it but we'll come back to that when we need it so as well as the event we want a um public static we can serialize another field here and this will be a protected inventory system which which is going to be called inventory system and again I'm going to make a public geta for this so we can get it when we need to from other scripts inventory system and this will pass our this will get our inventory system so then in our awake method we can say the inventory system is equal to a new inventory system with our inventory size so other the scripts are going to inherit from this this is why this is protected not private and by default all inventory holders will have one inventory system on them for example chests uh will have one inventory system on them but we're going to make a player inventory holder which will have um two inventory systems it'll have its backpack and it'll have a um but for now this will this will do fine so we've got inventory holder uh um with one inventory system so let's just see this uh how this looks now in the inspector so if I make um just an empty object and we'll call this player We'll add we'll build up on this um as we go along so I can add our inventory holder script to this and I can give it an inventory size of 10 so our inventory system in the minute is kind of it's zero size it's empty but with our inventory size of 10 when I hit play you can see that that's created 10 slots and each slot on our inventory takes in uh an item data with a stack size so the way this looks in our test project if I go over to my player top down player with inventory I've got my player inventory we have an inventory system here if I just hit play we walk over some items you can see seen it now there's five items which is represented here with our item data which is our test item and we can pick it up and move it between different slots so that's what we're building towards that's the visual representation of the system so that's how that looks obviously it's a bit boring and plain here so the last thing to do in this video let's just make it so our player can actually pick something up from the ground so I'm just going to make a capsu underneath our player um object that we've just made here I'll just call this uh Graphics cuz it's the player kind of graphic and I'm just going to move it up so it's sat on the floor I'm going to remove its captal collider and I'm going to put the collider on our player uh the actual player object and I'll just make I'll put box collider why not and we'll let move this up make it bigger I'm just going to right click create an empty and I'll call this um test item one reset the transform on this I'm going to create um 3D object and I'll create a sphere and I'll just move that up move our item well I use the term item lightly here just going to come over to our assets folder and create a um material I just say red just pick a nice kind of pale red color so here's an item here's our player so what we need for our player layer to actually pick up this is we need a mono Behavior to sit on our test item so go back over to your item scripts folder under scripts and I'm going to create a new C script and I'm just going to call this um item pickup so in our item pickup script um it's going to need a uh sphere collider or some sort of collider for our player to kind of hit and collide with I'm just going to require component type of sphere collider and I'm going to do a um public float pickup radius which I'll just set to one for now we can always change it in the inspector if it's too much or not enough and then it's it's going to need some public um it's going to need some item data to show which kind of item it's actually representing and then um we just need a reference to our sphere collider called uh let's say my collider in an awake function let's get a reference to our sphere collider so get component sphere collider and I'm going to say my collider do is trigger is equal to true my cider do radius is equal to our pick up radius now in our ont trigger enter function so ont trigger enter going to create a variable called um inventory so just VAR inventory and we're going to say this is equal to other. transform. getet component and it's going to look for an inventory holder on the thing that hit it if it finds an inventory holder so if inventory is not equal to null so we could just say if uh what we could do is say if inventory uh we could just return so if there's no inventory if this is null if it hasn't found an inventory holder script we'll just return out of this we don't care about what's next but if uh inventory isn't null then we can just say um if inventory do uh inventory system then we're going to want to add it to the inventory so add to inventory which doesn't exist we need to Define that we need to make that so we got go back over to our inventory system. CS file we can just make a public void uh sorry public bull add to inventory and this is going to take in um the item so the inventory item data and we'll just call this uh uh item to add and it's going to take in an INT which will be the um amount to add and for now I'm just going to directly and I wouldn't this isn't how it's going to work obviously um but I'm just going to add this directly to our uh to the first item slot in the list just so we can see this all working I'm set this equal to a new inventory slot and I'm going to pass in the item to add and the am amount to add and then I'm just going to return return true this is not how we're going to be doing it um properly we need to when we actually do this properly we're going to be checking whether the inventory already contains the item and if it does add it to the stack and if it's if the Stack's full we'll get a free slot that isn't full Etc um but just to see this kind of working um I'm just botching it to kind of overwrite that first slot so we can say add to inventory we can pass in our item data and we'll just say one for the amount to add because there's one item in the world with the physical representation you may want it so for example in Minecraft if you drop 10 uh torches all 10 are represented in that one item pickup so this could be 10 um but for me I'm just going to have one in the inventory there I'm just going to destroy this object if if I've successfully added myself to the inventory which is indicated by whatever we return so in this case I'm just returning True by default because we're overwriting the slot then I'm going to destroy this item if we don't add ourselves to the inventory we won't do anything so we'll just come back over to our project and and then we just need to add to test this a rigid body to our player turn off use gravity check is kinematic now if we select our player uh we've got our inventory system here we've got our test item here we can drag our item pickup on it and then we can say the item data this is um test item one but the pickup radius here um and also our sphere collider is dropped down because we moved our sphere up so instead I'm going to P sphere Center and then we'll just bring up our test item and I'm going to remove this sphere collider from our 3D object and actually we need to say destroy this Dot Game object as well not just to this so if we've got a player selected you can see the inventory holder script there if we hit play so we've got 10 slots the first slot's empty if we go forward we pick up the item it deletes from the world then we add one of that item to our test um inventory and we add that item to the very first inventory slot and again I've just hardcoded that um to always go into that first slot and overwrite it and make a new slot this isn't how we're going to be doing it properly the next video we're going to search our inventory slots and see if we can find the item that we want to pass in and if we can we're going to add the amount to it if we can't find it we'll get a free slot and add it to the next free slot that's available and by free slot I mean a slot with no data in it and if it can't find a free slot and it can't add it to an already existing item then obviously inventory is full so would return false and then the item pickup wouldn't destroy itself from the world but for now I think that's quite a good place to leave this first video if you're watching these as they go out the full series is currently up over on my patreon which is patreon.com dpos you can also get the files for each lesson so I'm going to export this script as it is currently now out as a package and I'll so you can download the packages in stages as you go and again there are all over on patreon if you need help with anything in this video that we've covered uh feel free to leave a comment below or better yet go over to the Discord which is again is linked in the description over on the Discord either me or someone else on the Discord could jump in and try and help you that's probably the best way to get help other than uh YouTube comments cuz you can actually share links to your code Etc watching these on YouTube as they go out the next video will be up in one week but in the meantime thanks for watching and I'll catch you in the next video [Music] bye okay so welcome to episode two of our inventory system tutorial series uh in the last episode we left it where we've got our test item here we have a player we can move the player over the item we can move the player over the item and the item data gets added to our inventory and we've got a stack size of one but I hardcoded it um to just directly add itself to inventory slot zero um this isn't the correct implementation this was just so we could see it working so in this video we're going to be working on um checking whether we can uh the inventory already contains the item if it does add itself to the stack of the item it doesn't it'll search for a free slot in the inventory and add itself there and if it can't do that then obviously the backpack's full so it will return false and nothing will happen the item will stay on the ground and it won't destroy itself because this only happens if we return true in our add to inventory script so in our item pickup we're saying if the add to inventory was successful then destroy the object from the world if it wasn't just do nothing so let's go back over to our inventory system. CS file so the two functions that we've kind of have mentioned so far we need to check whether our inventory contains an item and if it does we need to add it to that stack and if not we need to see whether there's a free slot so the first thing we want we're going to do is we're going to make a public void sorry we're going to make a public ball called contains item and this is going to take in uh the invent and this is going to take in some uh invent item data which is the uh item to add and it's going to pass back out an inventory slot if if one exists it's going to pass back out the slot that the item is contained within if we do actually contain the item so I'm just going to at the moment just to get rid of the red squiggly line I'm just going to set inventory slot to null and return false and this is what we'll do at the end of the function anyway and the so the next method we need to make is a public bull has free slot and this is just going to pass back out the very first free slot that it comes across so uh out inventory slot free slot and again if it can't find a free slot then we'll just um we'll null out the inventory slot and we'll return false and we'll we'll Implement these properly in just a second let's go back to our add to inventory script we're going to say here if contains item and we're going to pass in the uh the item to add and we're going to get back out the inventory slot that the item is contained in if if it does contain the item so if it contains the item uh we're going to add to the stack of that slot so add to stack uh amount well amount to add I've called it so amount to add and then we're going to say hey the inventory slot has been changed so on inventory slot changed and we're going to say if that's if that's been subscribed to if there's listeners of that event if if it's not null then uh invoke it and pass through the inventory slot that has changed and then in our UI we can find the corresponding actual like Square slot of the UI and we can update just that slot and then we just want to return true now if it doesn't contain the item we're going to want to check whether it's got a free slot so else if has free slot uh and it's going to pass back out an inventory slot which will be our free slot so I'm just going to put a note here so check whether item exists in inventory get the first available slot so here we can say free slot is equal to new slot uh inventory slot and then we can pass in the uh item to add and the amount to add as well and then we could just say on inventory slot changed do invoke pass in our free slot and actually so instead of making uh a new slot here we we can just manipulate the free slot itself directly so let's go over to our uh inventory slot and let's actually make a public void update inventory slot and this can take in an inventory item data called data and [Music] amount here we can just say item data is equal to data and stack size is equal to amount so that way we don't have to destroy and make a new inventory slot we can just call free slot. update inventory slot and we can pass in the item to add and the amount to add as well then again we can check whether our inventory slot changed event has anything subscribe to it and if it does we can invoke that event and we can just return true because again we were successful at adding it to our inventory and then if we it doesn't contain the item and it or and it doesn't have a free slot then we just return false and actually after we so if we go back to our contained item script we don't want to just get the um slot that um has the item we want to get a list of slots so we just want to type in uh list and then we're going to get back out an inventory slot list I'm just going to copy this I'm just going to put that here as well because in this um contains item method we're actually going to use a link function so we're going to say the inl slot is equal to inventory slots where and we'll open up some brackets and we'll say uh I so for item i. dat is equal to our item to add and then we can send that to a list so if you haven't used um the system. link namespace before um there's a lot of helpful stuff you can do in inventory slots uh with system. link so for example we could get inventory slots first and we could say the first slot so I could be anything so we could we could say slot so we could say first slot where the slot do item data do Max stack size is greater than five as an example so there's a lot of stuff you can do with system. link I highly recommend looking more into it if you haven't come across it before so just to make this more human readable so we've got inventory slots. where so this is going to check all of our inventory slots and it's going to create a list of inventory slots and fill it where the item or I slot this could be anything so so where our inventory slots item data is equal to the item that we want to add then just put that in a list so and this is going to be our out list here and then when we're checking whether it contains the item we can say um return and then we can say that does the inventory slot do count or is it is the count greater than one if the inventory slot. count is greater than one then we can return true CU it obviously contains the item and if it's less than one we can return false because it doesn't contain the item the item count size would be zero so now we're getting a list back out not an individual slot so now we need to check those slots to see whether there is room left in the stack which is that method that we made earlier on our inventory slot so I we can now say for each variable slot in this in slot list we're going to check does that slot have room left in its slot I'm going to check does that slot have room left in stack so we say room left in stack and you see we've got one of two here these are the two overloaded methods that we've made um we don't need to know how many are remaining we just need to know if we add this amount to the stack will it fit this amount to add here so say amount to add if there is room left in the stack then we're going to get this we going to pop it in here but this is going to be called slot it's going to be the slot that we're looking at in our inventory slot list which we've got from our contained item so our item pickup is going to get hit by our player and we're going to try and add itself to the inventory in our add to inventory script we're going to pass through the data that we want to add to our inventory and the amount of that data or the amount of the item that we want to add we're going to check with our whether the inventory system contains this item and if it does contain it then we're going to get a list of all of the slots that have the item in it and then we're going to check that list and we're going to check for a slot that actually has room left left in the in the stack if the Stack's full or there's not enough room to add so if say the maximum stack size was five we had four in the stack already and we were trying to add two there wouldn't be enough room for the two to go into the stack so it check the next slot and the next to the next and we need to get rid of the else if here cuz I found that it didn't work as intended when it was an elive so we're going to see whether it contain the item if it doesn't it'll move on anyway and it'll check do we have a free slot if it does contain the item it's going to look for the item and see whether one of the slots can take the amount if it can it'll return true and call our inventory slot changed. invoke if it can't then that's fine it'll move on and it'll check for a free slot so this should be uh all working let's go back to the editor and check it works and if it doesn't work let's debug it so I'm just going to come back to play here um got our test item I'm just going to make multiples of this test item now we got three four five six I believe we had test item so a Max stack size of five so if we click on our play here and we keep a track on of the inventory system over here and we hit play so we're going to go over this first item and nothing happens CU why would it work first time let's see what the problem is here I feel like it might be this issue we're having here I feel like it might be this here this condition um so let's just debug do log in slot. count I feel like it might be because if there isn't anything in it the count would be zero uh then that list isn't going to be initialized okay so we're getting count as zero back out what we could do instead let's um check whether this is null so is our slot list null if it is null then it'll be false we're going to return false because we haven't found anything and if it isn't false and if it has found something um some data in our inventory that equals this item then it'll return true cuz this won't be null so let's just leave that debug. log in for now let's just see if this works we'll hit play and we'll drag our player over oh you know what our mistake is we haven't set up the free slot method that's why well we're always returning false so we can't find a free slot to add it to that was my mistake so let's just finish this method before we get ahead of ourselves so here we're going to say free slot equals uh inventory slot do uh slots do first or default which is another system link um method and we're just going to say the first inventory slot I where the data in that slot is null so if it's null that inventory slot is obviously empty and when going to get the first slot that meets this criteria here and then just like our contains item we can do we can just return free slot is free slot null so has it found a empty slot if it has found an empty slot free slot would not be null so it' be true if it hasn't found one then free slot would be null so it would be false and we wouldn't have found a free slot so let's let's go back over to Unity and try this now go we can add our items as we drag our player we can see that stack size four stack size five so our maximum stack size is five as we go over this next item we should go to the next free slot which is this one here and there you go so stack size one this is our new slot if we made a another copy of this item here but instead we called this test item two and let's just make this um let's make another material and we'll just call this a green set it to a green color assign that here I'm just going to swap these places round so our test item two here this green one let's set that to test item 2 I'm just going to make another copy of it here and in our test item two we set the data the max stack size to one so as our player goes over we're going to pick up five then we're going to pick up one of our test item two and then we're going to check our inventory for this see that we're at the maximum stack so we'll get the next free slot which won't be slot two because this is going to be in it so we'll get the next one after that so let's hit play and we can see that all working so let's drag our player forward so we've got our five test item ones test item two goes into the first three slot that it found test item one again but our stack size is full so it's going to go into the next free slot that was available it won't go over this one or overwrite that one and then as we go over this so the stack size was one that's the maximum for test item two so we've gone into the next free slot so if I copy these and we make another row if I get a player and fill up our inventory will that have filled up the inventory no let's um let's just set the stack size of test item one to one also so as we pick up these items so our inventory is full now when we go over these items our inventory will be full we won't successfully add it to our inventory so they won't delete so you see as we go through them they're not coming up off the ground because they can't successfully add themselves to our inventory if we deleted um an item and made it back to its null State we could add another into our inventory and it go into that free slot okay so that's part two done of our inventory system it was a bit shorter than part one um but we had kind of you know we' set up a quite a good framework in the first video to just build upon in this second one you can see that the functionality is kind of now working as you would expect so going forward uh we are going to build on the system a little bit in the back end but we're going to start putting the UI elements together and showing how we can update the UI based on what is actually in our inventory again I hope this is all making sense so far if it's not or you'd like anything kind of clarified feel free to join the Discord server which is linked in the description or leave a comment below if you're watching these live as they come out the whole series of this is over up on uh patreon which is patreon.com dmos you'll get the access to the full series and all of the project files as well so the scripts that we're we're building um I'm organizing the scripts by lesson in packages so you'll be able to get the package for the lesson that you following the patreon is linked in the description below as well but that's everything for this video thanks for watching and I'll see you in the next one [Music] bye okay welcome to episode three of our inventory system Series so in this episode we're going to be covering um setting up this kind of scene to make it a bit more like playable I want to be able to move around as the character properly instead of draging the bean around like this and I'm going to put some chests in the scene so when we start working on the UI we can have things to go and interact with and we'll start putting the UI together as well so let's just jump straight into it uh where I left off in the last episode our players got an inventory uh list here a list of slots and as we go over the slots they fill up and eventually once the inventory is full stuff won't pick up off the ground and items can have different stacks is so if we set test item one which is the red spheres to a stack size of five and we hit play then we click the player as we go over we can pick up five of test item one stack size of item two is um one so we'll pick up them and then we can start a new stack here of five more test item ones that Stacks full so we'll start to put um so the other two two went into the next free slot there so that's where we are that's where we're at um the first thing I want to do then is uh I just want to make it so we can actually like you know move around with WD and to do that in this series we're going to be using the new input system so I'm going to go up to window package manager going to go to Unity registry select input system and then hit install this is going to install and it'll ask us to restart the editor once um it's installed you just need to hit yes to that and it'll restart our project so I'll catch back up with you after that's done okay so we're back uh in unity here after it's reset um after the pro project has restarted so you can see that the input system is now uh in our project so I'm just going to close this down um and we'll come back back to moving the character in a sec but let's just make a bit of a scene to actually move around um let going to delete all of these test items apart from test the original test item one and two just cuz I want them a bit more organized um I'm going to right click create 3D 3D object and make a plane I'll Center this in the world I'm just going to scale it up we'll make a new material make this kind of a grayish color gray I'm going to create an empty object I'm going to call this a small chest and again Center that in the scene I'm going to right click um 3D object make make a cube bring this up going to make another material called Brown while I'm here I'm just going to make another one called gold oh for our to represent our chest I'm going to just duplicate this Cube Bring It [Music] Forward move it up and then let's scale it down and make this gold so that's our small chest and then let's make uh oh what have I done and then we'll make big chest and we'll make that slightly bigger so we've got small chest and big chest let's move our small chest uh just back over there big chest back shate we might make more chests later on well in fact we will make more chests later on we've got our Bean here I'm just going to add another um going to add a 3D cylinder oh and I'm just going to give him some eyes just so we can see which direction they're pointing now let's add a script called um Player move movement this I'm just going to get the character controller. move script if you just search for Unity character controller script and it's this one um let's just steal this up from the bottom up to there and then we can come back to our scripts let's just paste paste that in so we've got our character controller um here because we're using the new input system instead of this get axis horizontal get axis vertical for now let's just um remove these I'll just put zero because we're using the new input system I'm just going to get rid of this uh the jump in stuff cuz it doesn't seem to work ever anyway for this character controller um so we can get rid of jump height whatever uh let's go back to our project I'm just going to drag this player movement script over into scripts make a new folder for materials pop our materials over there to keep organized I'm going to create a new folder called input and in input I'm going to create a new input actions called player controls and I'm going to open this up I'm going to call our action map player here and I'm going to choose pass through Vector 2 under binding under add binding I'm going to add a 2d Vector composite and I'm just going to delete uh this binding that was made already so for up I'm going to have the W key the Downs the S key left is the a key right is the D key and I'm going to save the asset and then I'm going to close this click generate C assets I'm going to click the player controls and click generate C class and hit apply over in our player movement script I'm just going to say play Private player controls called player controls and in start we can say player controls is equal to new player controls and then in our un enable function we want to say play controls. enable and in our on disable function we just want to say player controls. disable and then in update uh so this X was the um horizontal axis so we can say player controls dot player dot new action okay we don't want it to be called new action uh we need to go back to our player control input action asset and I should have called this movement hit save X out of this this back to our script so this is movement do read value Vector 2 x we do contrl c contrl v and we'll do uh Y for the z-axis okay so if you don't um understand the input system if you not used it before I'll explain these in just a second um but the first thing actually is um I've changed the start method to uh awake and I'm going to change this to get component instead of add component and then I'm going to come up here and I'm going to say require component type of character controller and I've also put the kind of null operator here so player controls question mark do enable so if player controls isn't null then enable them and if the if it's not null and we disable we'll disable them as well so back in our project let's add the player movement script to our character controller and you'll see that it's it's in the ground there the captal collider um we just need to raise this up by one so our character controller is now on the ground so the way the input action asset is working so we called it player controls that's the input action asset which is also the name of the script that was generated when we clicked generate C Class inside there we have an action map called player we create an action called movement and then under that we put a 2d Vector which is controlled by um up and down and S and then left and right is a and d and if you think of this as like a 2d kind of uh sort of of a unit circle we've got our Circle again I'm on my mouse here so it's not going to be perfect this is our y AIS this is our x axis got a and d control our x axis W and S control our Y axis so if I'm holding W down we're going to be up here so that's going to be um one if I'm holding s down this will be minus one a it'll be minus one on the X X and then x uh D sorry it'll be plus one on the X so in our script when we're reading the value we've got player controls which again was the name of the input action this is the actual action map player movement was the action that we made and then we're reading the vector 2 value of that and we're taking the x value for the X of our movement vector and we're taking the Y value for the Z of our uh Vector 3 so the Y is going to be forward so that was W and S and then the x is a and d for left and right so all things working as they should be um let's just move our camera into a better position so just so we can see our objects and um chest as we start moving we can walk around and pick up the items uh uh we're going very slowly so I'm just going to go back to our player movement script and I'm going to um I'll just make this public because we could have serialized the field but I'm just going to make it public so we've go back to our player uh player speed let's set that to five let's see if that's better there we go we're moving around a lot better now so we can we can move around we've got our chests which we can bump into we can't interact with them yet but we will work on that okay so we've got our Bean um I don't like the colors I've chosen there go I've got a blue Bean we've got our test items we've got got a chest which we'll interact with later okay so now we need to start working on our actual um UI so let's right click create a uh UI canvas and we'll just call this uh we'll just leave that called canvas because we're using the new input system uh on our event system we just need to click this here replace the input system with the new input system module we do that that's all working fine so we go to our canvas and we want to say screen space um overlay that's fine but we want to come down to UI scale mode and change to scale with screen size and I'm just going to put in uh 1920 by 1080 as and the first thing I'm going to do Under This is I'm going to um come to our canvas I'm going to right click create empty and I'm just going to call this mouse object and our Mouse object is going to have uh an image and it's also going to have some text I'm going to use text text mesh Pro we just need to import TMP Essentials so I'll just hit that we'll close this window and I'm going to hit the 2D button up here select our Mouse object and then press F just so we fly over to that and then I'm going to just position this so I'm just going to type in 10 just so I can get kind of what it looks like uh let's Center it going to make it uh black I'm just going to put this in the corner here of our image so actually we don't want to center it um on the alignment we want to right align it bring this up here and let's resize this box CU obviously if we had uh 100 items we want it to come out from that right hand side we don't want it to be centered so we'll do let's put 99 as a default and I'm going to bring it away from that corner um and check Auto size that'll fill the Box uh nicely and actually reduce [Music] the max the maximum size a little bit and I'll just place that there so this is our Mouse object our Mouse object uh we're going to add a script I'm going to come over to uh inventory scripts I'm going to right click create C script and we're going to say inventory uh I'm just going to call this m uh Mouse item data we'll open this up and for now let's just get a reference to the image um so we need to be using unityengine.ui and we need to use TM Pro and let's get a Public Image reference to our uh item Sprite and we get a public uh TM Pro ugui text smash Pro you you gooey um and we'll say item count so we go to our Mouse object and let's just add the uh Mouse item data script and we'll just drag in image and drag in text for now and then um on void awake I'm just going to set the item Sprite do color equal to color do uh clear to make it invisible and I'm going to say item count. text equal to just a null string so when we hit play that'll disappear so that's great we don't we don't need to see that if we're not currently uh actively holding an item so that's our Mouse object which we will come back to later um now let's create a panel so create UI panel and we're going to start making the hot bar so I'm just going to call this hot uh player hot bar and let's check the whole thing I'm going to click um here the anchor presets button I'm going to hold down alt you see that we changed the pivot in the snaping so I'm going to hold down all I'm going to change the um anchor pivot to the bottom center see that that moved there so now as we start to like scale so you'll see now that that kind of snaps to the bottom so if I start to resize this it's kind of anchored at the bottom of the screen so let's just drag that down there for our panel here um I'm just going to add a Content size fitter and we can set that to Preferred size for both of those and then I'm going to have a horizontal layout group in that I'm going to give uh some padding of 15 with a spacing of 10 child alignment I'll leave at um upper left and child Force expands that's fine so I'm going to make a inventory slot to go on our hot bar and this is going to be kind of it's going to match the slots on the back end like we're going to pair it with a slot on the back end so to our hot bar I'm just going to right click create empty and I'm just going to call this inventory slot uncore U I and then underneath this uh game object I'm going to right click and I'm going to go to UI and choose image and it's just going to be like just like the mouse slot so we're going to have an image and we're going to have um UI text for text mesh Pro and in fact let's just copy let's make a duplicate I'm going to rename this to item count control D to duplicate it and I'm just going to drag it under our inventory slot UI and then reset the position on the X and Y rename it to remove the one there let's just zoom in and position it where we want it we want it down at the bottom of our inventory slot and to the actual top level parent of inventory slot I'm just going to add a component I'm going to add a button component and this is how we're going to interact with the screen so it's not going to be a drag and drop kind of style interface it's going to be a you click on the slot to pick it up and then you click on another slot to place it down the reason for that is because I want this to be able to work on game controllers and you can't drag and drop on a game controller unless you were manipulating the mouse with a joystick and I don't really like that this is going to be more Minecraft style or stard Valley style you can highlight this slot click it go to a different slot place it so we're going to put a button on our inventory slot UI for the Target graphic uh we need to add um an image so I'm just going to choose image we drag our image under the graphic of the button that's fine for now we can put a um Source image in there um in a second but I'm now going to um come back over to our assets right click create folder prefabs and under our prefab folder I'm going to drag our inventory slot UI I'm going to make a prefab out of it and then I'm just going to duplicate this um nine times so we've got 10 slots on our hot bar so contrl D until we've got uh 10 10 inventory slots and you can see our hot bar here I'm just going to remove gizmos out of this scene so you can see that we've got our inventory slots here on our hot bar and then we've got a placeholder for our Mouse slot so on our inventory slot UI uh prefab we're going to add a script to it so I'm going to go back to our scripts folder and I'm going to make a folder called UI scripts I'm just going to go in here right click create C script I'm going to call this inventory slot underscore UI and I'll open that up in visual studio so this is obviously a mono Behavior Uh we don't need these two using statements but we will need um using Unity engine. UI we'll need to use text mesh Pro again so using TM Pro and we can get rid of start an update for now um and instead what we're going to do is we're going to serialized field private image Sprite uh item Sprite it can do a serialized field for the private text mesh proi which is our item count serialized field um private inventory slot our assigned inventory slot which is our our backend slot that's represented by the actual UI elements we can make a private button called button I'm going to make a public uh property so a public inventory slot um assigned inventory slot with a getter for our private variable then over in our void awake function I'm going to say item sprite. Sprite is equal to null item sprite. color is equal to color. clear item count. text is equal to blank string we're going to get our button component so button. get component button and then if button isn't null we're going to subscribe to its on click event so we're going to add a listener and we're going to add a method called on UI slot click which we can make here public void on UI slot click so in here we're going to um in a second make a display another class which we're going to access um we're going to access that class so access display class um function so the relevant function on that display class which we'll make and I'm going to make a public void clear slot function which is actually just going to do this but I'm also going to check the assigned in ventory slot is if it's null then we're going to clear the slot there as well so if we're clearing this slot on the um UI we want to make sure that that's reflected in the system as well so we'll just do clear slot here and then we can actually just get rid of this we can call clear slot in the awake function as well then I'm going to make a public void init function for like initialized and I'm just going to pass in a slot when we initialize this slot so inventory slot slot I'm going to say assigned inventory slot equals inventory slot uh slot I've just called it not in slot so assigned inventory slot is equal to the slot that we've passed in and then I'm going to update the UI slot so this is going to be the graphics so it's going to pass in it's going to pass the slot on so public void update UI slot which takes in an inventory slot called slot in here we can say um if inventory slot. data if slot. data item data is uh not equal to null then we will set our item Sprite do Sprite equal to the uh slot. item data do icon and we'll make the Sprite visible by setting the color back to color. White if the data is null then we just want to clear the slot so if for some reason we've passed in a slot that has no data in it we just want to clear that slot anyway um just to make sure that that's reflected properly so that's the the icon and then we also want to check the stack size so if slot. stack size is greater than one we'll say item count. text is equal to slot. stack size. two string so if we've only got one of the item we won't display the number that that's down to you um maybe you want it to display it when there is only one but I prefer it so if there's only one item we just don't have a number next to it so then we can say else item count. text is equal to a null string so so we can actually put this inside here and I want a version of this method that we can call without passing in a slot so we can just refresh it um directly so I'm just going to say update UI slot which won't take in any kind of argument so I can just say that if our assigned inventory slot isn't null then we'll update the UI slot by passing in our assigned inventory slot so the reason for this is we may want to refr we may just want to refresh the slot without passing in an inventory slot so this is a good way to do that we'll just refresh it based on the assigned inventory slot that we've given it anyway when we uh set up the slots okay so let's just pop back over to the editor and set this up so if we go over to our prefab let's add our um inventory slot UI script to our prefab then we can say um item Sprite is that I am count is that our assigned inventory slot um it starts as null that's fine so let's go back and then we can see that our slot uis here they've all been updated to have a reference to their own um images and item counts so that's Grand so now we need our inventory display class so again let's go back to our scripts folder UI scripts and let's go over to so let's right click create create C script and we're going to call this inventory dis display and we'll double click and open that so this is going to be an abstract class we're not going to use this class directly and we're going to want to get rid of start and update and we don't need system do collections we will be using uh generic though and we want uning Unity engine. events and also using Unity engine. input system okay so this is going to need a few different um variables so we're going to need a protected inventory system so this is going to be the inventory system that we want to display so inventory system inventory system and again we'll make a geta for this so public inventory system inventory system we get inventory system I want a protected I'm going to keep all my ghs down at the bottom um so we want a protected dictionary and this is going to take in um an inventory slot UI and inventory slots and we'll just call this the slot dictionary you see now that we we basically marry up a UI slot against its like actual slot in the inventory system so we go back to our little graphic here you can see that we've got the system and we've got the UI these UI slots the physical kind of in-game representations of these system slots so you can see that this is how it's going to look it's going to when it's got an item it's going to display the items graphic when it's got an item and there's a stack size greater than one it'll display a number of that to represent the stack size so this is the representation of the actual slots in the the data sort of system in the back end of it so by using a dictionary if we pass in a UI slot we can get out the slot that it's sort of married to which is great that's exactly what we need to be doing and I'm going to make this publicly accessible as well so so public dictionary inventory slot UI is the key inventory slot as the value and I'll say slot dictionary and we'll get the slot dictionary and I'm going to also serialize field mouse item data I'll call this mouse inventory item and we can set this in the inspector uh another option would be to use um to make a singl ton out of this we can get it that way um that's the way I did it in my test project but to not have to go through what a Singleton is and all that uh we're just going to call this we're just going to set this in the inspector and make sure that we do so we're going to need a public abstract void function that our derived classes are going to um use so that's going to be um public abstract void assigned slots and this is going to take in um the inventory system which is the inv to display so when we assign the slots um we're going to create this dictionary so we need to know which slots to marry up with the actual inventory slot UI kind of representations um I'm going to make a protected void uh protected virtual void sorry called update slots it update slot and then this is going to take in an inventory slot called updated slot and this is an abstract because it's going to be the same it's going to be the same no matter which um kind of variation of this class we make so we can just Define it here so we could say for each slot so variable slot in the slot dictionary if oh if slot. value is equal to the updated slot that we've passed in then let's update the UI slot of the like corresponding inventory slot so now this is getting quite confusing because I've you know stuff kind of called the same thing so on our inventory display class we've got this function update slot and we're going to pass in a system slot this is this this script where it's got all of the actual like system elements to it we're going to pass that slot in and then we're going to check for every slot in our slot diction room we're going to Loop through them and if that slot that we're looking at if the value of that entry is the slot that we've passed in then we're going to update the UI slot that corresponds to the inventory system slot and here that's the key because you'll see that you know the inventory slot UI is our key the inventory slot system isn't the key is the value so we can update the UI slot there so this is the slot value the under the hood inventory slot this is the slot key the UI representation of the value and this will have um another function called um slot clicked which we're not going to do in this episode because it's quite a long script so that's probably going to be an episode all on its own but this is going to take in a clicked slot for now we'll just say uh debug Dot log slot clicked so this function is what we're going to use on our actual inventory slot so if I go back to inventory slot I'm going to make a public property of inventory display and we don't need to set this in the inspector so I don't need a private ver version of this I can just say get private set I need to call it something so parent display and here in the awake function we can just set parent display equal to transform. parent. getet component inventory display so in our onui slot click function this is where we can say parent display dot uh on slot so that's where we say parent display slot clicked this which will go through to the inventory display function and it'll debug.log slot clicked so the last thing I want to do is I just want to make the first kind of derived script from this the first kind of uh instance of this script so um in our UI scripts folder I'm going to create C script I'm going to call this static inventory display we'll open this up so the first thing this is going to do is going to implement um it's going to inherit from inventory display and you see that we've got a squiggle here if we press alt and enter we can implement the abstract class which is this assigned slots function we can get rid of um start an update from here uh what we actually need to do is in inventory display I want to make a public virtual void start just in case we need to do stuff in there later um and then in our static inventory display I can do um public override void start and this doesn't need to be public actually sorry that needs to be protected so protected override void start we can call our base start so at the top of our static inventory display I'm going to need two Fields so I want a serialized field private inventory holder called inventory holder and serialize field private inventory slot UI array called slots now now in our start function I can say if inventory holder is not equal to null so if we've actually assigned it in the inspector then we can say the inventory system is equal to the inventory holder do uh inventory system we can subscribe to the inventory systems on inventory change function and we're going to subscribe our update slots function to that event the update slot function to the event so that's the method that we've can we've got on our inventory display here that event is this this onslot changed so when we do something and add something to the inventory we call on inventory slot changed um and we invoke that here I'm just going to else and I'll do debug. log warning no inventory assigned to this. game object just so we know if something's gone wrong and then after all of that we can say assign slots inventory system so we can assign our slots and pass in our inventory holders inventory system again inventory system is over on our inventory display class it's this protected inventory system um variable here and what we're going to do here is we're going to um get rid of this throw new exception and we're going to say slot dictionary is equal to a new dictionary of inventory slot uis and inventory slots and then we're going to say 4 in I whilst I is less than the inventory system do inventory size which because this is a static display we've set this up in the inspector to have 10 slots so we need to make sure that the inventory system that we're pairing it with also has 10 slots uh we could check for that and debug it and but I know you know I'm looking for the hot bar which is I've said in for my game has 10 slots so I've represented that over on the UI once that set up that should not change you could obviously you would Implement a check if you wanted to so you could check your array size vers the inventory size and if it's not the same then do an error I mean I suppose for good practice let's just do that quickly so if slots. length is not equal to um inventory system do inventory size then again debug. log inventory slots out of sync on this do game object so for in I equals z whilst it's less than the inventory size we're going to add to our slot um our slot dictionary do add and we're going to pass in the key which is the slots I so it'll be 0 1 2 three so it's the corresponding slot in our array so slots I and then the value is going to be the inventory system do inventory I and I can't seem to get inventory so I've obviously not made a getter for it so let's just go to inventory holder inventory system oh I called it inventory slots here that's why so um inventory slots I so that's our value this is our key so this is the UI slot and this is the value of the actual like system slot so we've added that to our dictionary and then we just want to initialize the UI slot so we inventory slot so we can say inventory system do inventory slots I because remember the uh init function takes in um an inventory slot an assigned inventory slot and then it updates the slot as well so let's just go back into Unity I'm going to click on player hot bar I'm going to add our static inventory script or static inventory display for the inventory holder I'm just going to drag in our player and for slots I'm going to open up our hot bar I'm going to click the lock up here to lock the inspector and I'm going to get all of our inventory slots and I'm going to drag them into our slots array now I want them to be they need to be in the correct order so you know slot zero which is this one is element zero slot n or slot 10 sorry is this one so and this is the size 10 and while we're here I'm just going to drag um the mouse object into the mouse inventory item I just had an error I've put button. getet component button I need to say button equals get component button so now we need to get some assets so I'm going to go create B and I'm going to call this uh Graphics okay so that's um s on our inventory slot prefab I'm going to change um we have this image here I'm just going to make this like a brown kind of color to kind of indicate the the slot being empty and then we have an image here which if I disable that we can see the slots now brown this image was currently white should go clear when we hit play because that's the actual item Sprite um so let's even you know reduce the width and height of this so 85 85 so this is the actual slot which is brown and then there's the um item image which is white in this case and let's go back to our inventory slot go go to overide hit apply all so now here's our slots with an item Sprite in it and when we hit play we're going to clear them out and we've got our slots now so when we hit play they go clear cuz they've been assigned a blank inventory slot we can walk around when we pick up an item so we've got our test item here uh there's currently no Sprite icon attached to it but it will go white so when we go over an item it'll go White and we'll see that we've got an item in that slot go over another item that slot now has an item in it if we've got um multiples of this item so test item two can be stacked so let's just make a couple of these hit play when we go over you can see we've now got three of these test items uh in the slot but there's no icon so in the next episode uh we're going to build upon on this system We'll add in some icons for these and then we're going to work on the actual click functionality so at the minute when I click the um slots nothing happens like you can see that I haven't picked it up I've not done anything so that's what we're going to work on next as always if you're watching these kind of as they're coming out um the full series is already out and over on my patreon which is patreon.com pass when you support on patreon you'll also get access to the project file packages for um each episode as well so even if you're watching and they're all out it's worth heading over there anyway if you want to compare your code to mine you can do that by downloading the project files if this episode didn't make sense if there was something that was unclear please do let me know in the comments below or join the Discord server which is linked in the description uh me or someone else may be able to help you if you're having trouble there for now thanks for watching and I'll see you in the next one [Music] bye okay so welcome to episode four of our inventory system tutorial Series where we left it off is if we go um down here and if we hit play you can see that we've got our empty inventory slots here and as we go over the slots we pick up uh these two sort of different items some of them can stack uh the green one can't there was only one of them anyway you can see that they've just got these ugly white Sprites in them at the minute so let's get some Sprites downloaded so we can actually start to see stuff uh appear in our inventory this um there's this cozy Farm asset pack which is a really nice pack includes a lot if you pay for it um but you can get it for free there is a free version so if you click no thanks just take me to the downloads you get this uh free version. ZIP and just hit download on that what you'll get is you'll get this uh PNG with just some basic tiles so if we just drag this into our project so I'm going to go over to our assets folder going to right click create folder um let's type Graphics so I'm just going to drag this uh PNG in and we're going to need to do a couple of things first so the first thing is we want to mark this as a Sprite we want to set the Sprite mode to multiple uh filter mode we want to change to no filter Point compression we can choose none and then we need to hit apply this is one image with lots of Sprites on it so we need to slice the image um up into its multiple parts and to do that we need to access the Sprite editor if you've just started a normal 3D project in unity you won't have the 2D Sprite package installed and you'll get this uh error so we just need to go up to window package manager go over to uh Unity registry and then choose 2D Sprite and just install the 2D Sprite package so with that installed we can just close out the package manager select our image again choose the Sprite editor then we just um for what we need we just want these two Sprites here the potato and the uh tomato so if we hit slice and then just choose automatic it's going to slice up all of the um it's going to try and detect things to slice so where you've got a PNG it'll do a cut around them it's not worked perfectly for this whole image um but we just wanted these two Sprites so we've got those Sprites there so we can uh We've hit slice so we can just click apply and now if we expand this out you can see that what it's done is it's you know sliced them up uh kind of wrongly but here's our potato and our tomato so now if we go back over to our scriptable objects and go to test item and I'm just going to rename this to Tomato I'm going to select tomato and let's type tomato there this is a tomato I'm going to have a maximum stack size of five still and I'm just going to choose the Tomato from um for the icon and then I'm just going to do this and I will say potato and I say potato and tomato cuz I won't say Tom tomato so with potato when you will choose the icon and we'll pick pick the potato icon and we'll say the display name is potato and this is a potato so now we've got our two test items so now with our test item one this is the Tomato which is quite it worked out well cuz it's red so I'm just going to rename uh this to Tomato I'm just going to delete the other ones so I don't have to rename all of them for the test item three let's call it potato and I might actually just change the color of it to be more potato color because why not so rename this to potato let's pick more of a potato color which kind of that color I suppose so now we've got a potato and a tomato the potato won't stack it's got a maximum stack size of one so it's not going to carry on stacking so now we've got our tomato and our potato we can just um I'm just going to select them both and drag them down to the bottom I'm just going to duplicate them a couple of times so I'm going to get the move tool contrl D let's duplicate them contrl D duplicate them again duplicate them some more then I'm going to get all of the tomatoes because these stack we want a few of these so we can actually pick them up and actually why don't I do that with the potatoes as well just so we've got multiple things to work with so if we now hit uh actually let's select all of these and just bring them down to the bottom and then I'm going to group all of these together uh under a object just called items just to keep the uh hierarchy organized so let's drag that in we can just collapse that so we've got our items here now and you'll see that as we go over them now the icons that we've set should appear in our inventory when we pick them up so there's our tomato you can see that we've got five tomatoes are stack in and then the potatoes don't stack and they fill up our inventory now our inventory is full we can't pick up anymore and I don't like the font here being black so let's just go over to the canvas uh play Hot bar get one of our slots and just open it up and I'm going to change the item count to White and we could maybe give it uh an outline so just check the outline just so we can definitely see it over the images so there you go we've got five five tomatoes so we just need to um choose our prefab and then hit apply all and that'll apply it to the rest of them so as we hit play see that when we've got more than one item uh it comes up and shows us the item in our inventory so now the next thing we want to do is we want to start be able to click on the items and actually do stuff because at the moment nothing happens when we click on the items we want to be able to pick it up and manipulate this mouse item to show the item that we've got selected and we want to remove it from the slot and do lots of interesting stuff of it just to show how that's going to work we're going to run over these items and then we can pick them up move them around and place them down so this is what we're going to be working towards in this episode uh moving them between the slots so let's go back over to our scripts folder and we've got our UI scripts and I believe we need to open up the inventory display script so here's our inventory display click uh here's our inventory display script in the last episode um you know we we set this up and we set up the static inventory display as a uh that inherits from this class but all displays are going to have slots that can be clicked and at the minute it just prints out slot clicked when we click it what we want to do is we want to start picking up items and moving them around so let's just get to work on that straight away so first thing we want to do um we're going to need a few different checks because there's a lot of different things that need to happen based on a few different context so um if the clicked slot has an item and the mouse doesn't have an item then we will need to pick up the item because there's nothing currently on the mouse we also need to account for if we if the clicked uh slot doesn't have an item but the mouse does have an item then we need to place the mouse item uh Place Mouse item into the M uh the empty slot we also want to check to see whether uh both slots have an item and if they do uh we need to decide what we want to do there for example are both items the same if so uh we want to combine the stacks if we can so if we've got you know three tomatoes on our inventory bar we're holding four from a different slot can we combine them and if they're um if different items then we want to swap them then swap the items and actually this one has an bit of an extra step we want to see that um is the slot plus is the spot is the slot stack size plus the mouse stack size greater than um the slots maximum stack size that it can take if so we need to account for that um so we need to if so uh take from Mouse so we need to take so if the maximum stack size for tomatoes is five and we're currently we've currently got three in the stack but we've got four in our Mouse then when we click on the item we're going to take two from the mouse to fill the stack and then we're going to leave three two on the mouse bad math I'll just I'll just show what I mean here so if we've got um you know so these Hearts they stack to a maximum of five we've got three in this stack if I split this and let's just get four so this three it can only go up to five so when I've got four on my mouse if I click here it's going to fill this stack with two cuz 3 + 2 is five so it's going to take two from the four that I'm currently holding so as I click I've now got two left on the mouse that Stacks full and when it is if we're also accounting for if this Stacks full and we're trying to place this on top of it it's just going to swap them it'll just swap them over so that's what we're kind of building up towards as well and I'm not sure if we will get there in this episode um but we also need to check uh if the player is holding shift key and if they are we want to split the stack so we want to separate the stack into two different um Stacks we want to leave some in the slot and put some onto the mouse so there's quite a lot to get through here a lot of functionality to build uh we'll try and do it in one episode we'll see how we get on the first thing we'll tackle is this if the click slot has an item and the mouse doesn't let's pick it up let's put it onto the mouse so if we make some room here so this slot clicks when we click on the button that's attached to the slot it's going to call it's going to reach up to the parent um display we look at the inventory slot UI we've got onslot clicked which we've uh added as a listener to the buttons on click event and and it's going to reach up to the parent display and it's going to say uh call slot clicked and it's going to pass in itself so we know which slot exactly was clicked so here we can say if this clicked slot uh and just so we know exactly what's going on I'm going to rename this to clicked UI slot so if clicked UI slot do inventory assigned inventory slot. data item data is not equal to null so if the click UI slot has an item in it so it's not null and the mouse inventory item dot uh inventory slot so why is that not working why can't I get that oh so I've actually added an inventory slot to the mouse so let's go back to the mouse we just need to add an inventory slot to the mouse so we can do a public uh inventory slot called inventory slot so we're going to be coming back to this in a second so I'm just going to move them and I'm just going to close all these other ones that we don't need so let's go back to our inventory display class so um we've got click slots uh item data and then Mouse inventory item do inventory slot. item data is not equal to null is equal to null so if the um slot has an item in it and the mouse doesn't then we can pick up the item and assign it to the mouse so it'll be in here that we split the stack if they're holding uh the shift key so that's if that but and then we'll do an else but for now let's just do mouse inventory item data Dot and then we're going to need to make a function on our Mouse inventory item called update Mouse slot and then we're just going to pass in the clicked UI slots assigned inventory slot and then we're going to call click toi slot clear slot because there won't be an item in that slot anymore cuz we have picked it up so let's go and make this function so it's update Mouse slot I'm just going to copy it so we know it's uh called exactly what we want it to be called and I'm going to make a public void and then paste our update Mouse slot and this is going to take in an inventory slot and it's going to be called just inv slot so here we're going to um take our inventory slot and just to match this up with the clicked UI slot I'm going to right click and I'm just let's rename this to assigned inventory slot so it matches just so it matches this so we know kind of what we're working with um so assigned inventory slot Dot assign item in slot which is another function we need to make on our inventory slot and and I'm just going to call this in slot and we'll do that in a second um so the next thing we want to do is we want to set our item sprite. Sprite equal to the inventory slot do item data. ion so the item that's in the slot that we're putting on to our Mouse we need to set our Mouse's Sprite to the icon we want to set the um item count. text equal to the inventory slot. stack size. two string and we need to set the item spray. color equal to color. White so it becomes visible again so obviously we we set it to clear initially so now we need to make um this assign item on our inventory slot class let's go over there here we can say uh public void assign item and we can pass in uh inventory slot in slot and we can just say here [Music] um if the item data that we currently that's currently on the this slot is equal to the item data that we've we're picking up so the inventory slots item data so if this inventory slot has some item data in it and we're trying to add more of that item to it then we can just call add to stack and pass in the inventory slot do stack size so this is going to combine the items and we can say else item data is equal to the inventory slot data that we're passing in so in slot. item data we're going to set our stack stack size back to zero and then we're going to add the inventory slot. stack size to that so this is going to completely override the item that was in the slot if they're different so we're basically swapping them well we're not swapping them we're completely overriding it if the mouse is um um assigned inventory slot had a potato on it and we passed in a tomato an inventory slot with a tomato on it we're going to assign the Tomato to the assigned inventory slot of the mouse so hopefully that all makes sense so let's go back over to our inventory display class if we've done this then we can just return cuz we don't we won't need to check any of the other stuff because we've already accounted for what we're doing here so let's just hit save go back over to Unity so if we hit play and we walk over our tomatoes and we click the slot it's I'm going to set it on our Mouse inventory slot item which doesn't follow our Mouse which will fix that and I'm also going to do what I've what I did with the text down here as well I'm just going to set the mouse slot text to white with a slight outline so now when we hit play pick up an item so we got five tomatoes on our Mouse slot so let's let it actually follow the mouse around now so to do that we go over to our Mouse item data and because this is a mono Behavior it can get a update function so we can do void update and what we want to do here we want to say if our uh assigned inventory slot. item data is not equal to null so remember this is the way we check whether the mouse has an it item actually on it so if that's not equal to null then we want to say transform. position is equal to Mouse uh we need to be using Unity engine. input system for this so using Unity engine. input system we want to say mouse. current do position. read uh value so if we have an item set the items object position to the mouse's current position so it'll follow the mouse around and we can go further here to actually delete the item so if we click outside of the inventory we can delete an item so to do that uh we can get this function here which I found on I think it was stack Overflow which to use this we need to be using Unity engine. Event Systems and we say Point our event data event data current position equals new pointer event data event system. current we're going to get the event data's position and set that equal to the mouse's position and we're do an array cast and this will uh return a list of items that it hits and it'll hit UI elements it won't hit stuff in the game world so if that list is greater than zero then we've obviously hit UI so it' return uh true if it doesn't hit any UI it'd be false so we can say under here if the mouse. current. left button. was pressed this Frame and we're not uh is pointer over UI object so we're not currently hovering over an object then we can say clear slot which is a function we just need to make down here we can say private void uh no public void because we'll need this later on so public void clear slot and this is going to get our assigned inventory slot and call clear slot on that so we're going to empty out the inventory slot and then we need to reset our item count. text to uh display nothing we want to set the item sprite. color equal to color. clear and we can actually just null out the item Sprite so item sprite. Sprite is equal to null as well so now we go back to our Mouse object and we hit play you see that if we pick up an item it will now follow the uh Mouse and you might not want it directly under the mouse you might want it slightly offset so we can do that so we can do that easily so if we hit 2D and look at our Mouse so the mouse object is uh sort of anchored here and it'll this position in the center will be what follows the mouse so we just want to offset the image uh by 50 and then we can do negative 50 so the left corner is now at the pivot and then we can just drag this the text into place so if we go to item count and drag this down and one thing you'll notice is that it it was behind the UI when we click it it goes behind the UI what we want is we want to get our Mouse object and just drag that to it it needs to be at the bottom of the canvas which will draw it on top of everything else we can hit play and you'll see that it appears on top of the UI now one thing you'll notice is if we pick it up it doesn't actually fully work when we click to delete the item unless we get away from the mouse quite quickly the reason for that is that we need to make the Mouse image uh not be a rast Target otherwise when we click will always be over a UI element because it's following the mouse around obviously and under the item count text as well we can come to rast Target and let's just uncheck that so now when we go back and hit play and we pick up an item you see that we pick it up and we can click off our UI and it'll delete the item and that slot is now empty it's not just the kind of representation of the slot that the actual inventory slot has been uh emptied as well so we can pick up our tomato it's out of the slot cuz it's now on the mouse and we click and it's gone there's nothing on the mouse and there's nothing uh in the hot bar and we can pick it up we've now got the potato on the mouse we delete that so that's gone out of the game and we can carry on picking stuff up so now we could pick up items and we could delete them but now we need to be able to pick them up and place them back in slots so we can move them between our inventory slots and keep stuff organized so let's go and work on that done that that's all working so let's go back over to our inventory display so we've we've achieved this let's just go up okay so let's have a look so the next thing is the click slot doesn't have an item but the mouse does so let's place the mouse item into the empty slots let's move them around so here we're basically doing this but in Reverse we're doing the kind of flip of that so let's make a new uh if statement so we can say if and let's just bring this up so we know what we're working on so if the uh clicked UI slot start assign inventory slot. item data is uh equal to null so the click slot doesn't have an item in it and the uh Mouse inventory item do assigned inventory slot. item data is not equal to null so the mouse does have an item let's place the mouse item into the empty slot in the same way that we do um here so so here we just need to say uh click slot UI do assigned inventory slot and then here we need to assign the item directly so we can say uh Mouse inventory item do assigned inventory slot. item data so after that we need to call click UI slot. update UI slot cuz we've put a new item in it so let's just refresh it now we could put it um you know in this one and pass in the slot but this is also called when we pick up an item from the ground and if we reassign the item when we pick it up it causes some weird issues and it adds multiple to it for some reason um I'm not 100% sure why that bug was occurring but so this is the way around it though you just assign the item directly and then you just refresh the slot and then we need to do what we're doing here but for the mouse item so we just need to say mouse inventory item do uh clear slot so if we go back over to uh Unity let's just hit play so as we go over we can have pick up items we can pick them up on our Mouse and we can delete them and carry on picking up items it'll fill up the stack when we pick them up then it started uh a new stack once that stack was full and we can pick up the items move them and drop them into the different slots now and if we look at our player on our inventory we're actually moving them um we're actually moving the slots to their corresponding slot here so we can move it and put it into the second slot we can put it into the last slot see this is kind of working as we intended now so we can pick up these potatoes and we can place them in this slot and you see that if we pick up the potato and try and place it somewhere else nothing happens it has to go kind of into a blank slot so the next thing we need to work on is swapping slots and splitting stacks and we will do that in the next video and I think that will be enough for this video so we'll do that next time um so in the next video we'll finish up our uh thing here so we'll we'll swap the items and we'll uh set up stack splitting as well and we can and we'll also set up some we way to combine the stacks once we've split them as well cuz it's kind of using the similar sort of functionality so that's it for this video uh if you're watching this as they go live as always the full series is over on the full series is up on my patreon already um that's patreon.com slos if you've struggled with anything in the video or need some help or something's not quite working either leave a comment below or better yet come join the Discord server an invite for that is in the description of this video uh and either me or maybe someone else would be able to help you it's probably a quicker way of getting a response than here on YouTube time thanks for watching and I'll see see you in the next one [Music] bye hello and welcome to episode five of our inventory tutorial Series in this series uh we're working on building an inventory system but just to show you where we're at at the minute we can currently walk over items and we can pick up items uh they they can stack and once the Stack's full so the Tomato's got a maximum stack size of five it then goes over to the next free slot and we can pick up slots and we can move them as we walk over an item it'll add itself to the first stack that it's that has some free space in it and if the Stack's full it'll just get the first free slot on the inventory so it'll go here when we pick up a tomato and we can move them around and we can pick up these potatoes which don't stack and we can you know change the position and they're actually changing in our inventory here so I'll place that down pick it up and we can also pick them up and drop them out of our inventory to delete the items but what we can't do at the minute is combine the stacks swap items or split the stacks which is what we're going to work to uh which is what we're going to work towards in this video so let's just get started with that straight away so if we go back over to our inventory system um inventory display class script see that here's the two methods that we you see that here's the two kind of cases that we had for what happens when a slot is clicked on and now we need to see what happens when we take into account some different kind of options so for example what happens when both slots have an item we need to decide what to do because are both items the same if so we want to be able to combine them if they're not we'll swap them can we combine and can we actually combine the stacks is that possible is the stack full and how full is the stack so uh we need to start working on this so the first thing I'm going to do is we'll account for swapping items cuz that's the easiest to do first so um this is all kind of one sort of this all kind of flows into each other so we'll actually work on this first um to do this I'm going to just come out of this function and I'm going to make a private void swap slots and this is going to take in um the clicked slot so inventory slot you my clicked slot I'm doing this here cuz we're going to use this function twice up here so we may as well put it into its own function so we're not repeating stuff now to swap a slot we need to clone the mouse slot um first because we need to make a copy of the mouse slot so then when we move what's on our hot bar hot bar to the mouse would obviously lose what's on the mouse then we couldn't put the mouse in the empty slot so we need to make a cloned kind of of inventory slot of the mouse's data so let's just do variable V cloned slot or duplicate slot and this is just going to make a new inventory slot and it's going to take the mouse inventory item do inventory slot. dat and it's going to hold the inventory slot do stack size so we're just making a temporary inventory slot that's not part of any system it's just a sort of temporary slot in this one function then it'll be disposed of once we've used it so now we can say mouse inventory item. clear slot because we've got a copy of it so we can clear it and now we can pass in the clicked slots item so we can update the mouse slot and we can do clicked UI slot do assigned inventory slot so this is what we're doing um up here when we pick up an item so we've copied what was on the mouse and then we're picking up the item that was currently in the slot and then we want to clear the clicked slot because it's now on the mouse so we've emptied the slot and then we're doing what we did um here so we can actually just copy this paste it here but instead of the mouse inventory slot we're going to pass in the cloned slot and let's just rename this to clicked UI slot click UI slot so that's swapping item so we have an item on the mouse we make a copy of it then we clear the mouse off put the click slot on the mouse and then put the cloned what was then we put the copy of what was on the mouse into the UI slot and then you know this is disposed of once it goes out of scope we won't it's just a it's not used anymore so we don't need it so let's just go back up here so the first thing we want to do is we need to account for both um items both the click slot and the mouse having an item on it so we can just copy this paste it here and we'll say not equal to null and not equal to null so if the click slot has an item and the mouse slot have an item we now need to decide what to do so both slots have an item decide what to do so we need to see whether uh both slots uh both items are the same like is it are we trying to place a tomato on a tomato or potato on a potato Etc or I'll be placing a potato on a tomato for now let's just say if clicked UI slot. assigned inventory slot. item data is not equal to the mouse's inventory item data so if they're not the same item then we can just say swap slots and we can pass in the clict toi slot so call that there so now we should be able to swap our potatoes and our tomatoes so let's hit play so we can go over pick up some items and we can pick up a potato and we'll swap it for the tomato and we can put it back down now currently nothing happens with uh the potatoes we're not adding it So eventually you know there's one potato here we have one potato on the mouse we'll click and it'll become two potatoes in that slot but for now we can now swap items so we know our swap item method is working so let's go back over to our script so we're back over in our uh inventory display script so let's start accounting for what happens if the items are the same so let's just copy this so we want to say if the clicked slots item is equal to the mouse's inventory item and we want to check whether the clicked UI slot do inventory slot whether there's room left in the stack and to check that we're going to pass in the uh Mouse inventory item do assigned inventry slot. stack size so so if we've got three potatoes on the mouse and we're trying to place them on top of a potato that's in the clicked UI slot the slot that we click on is there room in that stack for the amount of potatoes that we have on our Mouse and remember this is this uh bull here so all it's doing is it's checking whether the stack size plus the amount to add is less than or equal to the maximum that that item can hold so if we've got a stack size of three in our inventory slot on our hot bar and we're trying to add two that are held on the mouse 3 + 2 is equal to 5 Which is less than or equal to the maximum stack size which in this case is five if we tried to add three to a stack size of three this would return false because obviously um 3 + 3 is six which is greater than the maximum stack size so it would return false we can update our um stack sizes so we can say uh click UI slot. assigned inventory slot and we can sign item uh oh assign item and let's assign the mouse inventory items uh inventory slot and let's just remind ourselves what this functions doing if we assign an item and the slot already has the item it's going to add the stack to the stack size if it's not the same item it'll just overwrite the item so it'll it'll swap the items around so in this case we've already checked whether they're the same item and that the stack size won't go over the maximum stack size so we can just basically add to the stack that's already there with this item so we're assigning like a tomato to the Tomato so they're the same so we're just going to add them to the stack so then now that they've been assigned we can uh call update UI slot on our clicked UI slot and then we need to clear our Mouse inventory item because we've we've combined the items now so now we need to check whether there isn't room left in the stack and if there isn't we need to know how much is actually left in the stack so we can take it from our Mouse so we'll do else if we'll get this again what I'm actually going to do is I'm going to get this and cut it and then up here I'm going to say bull same item or is is same item and we'll just put that there and then we can just say here is same item and then we can maybe bring this back up to this line CU it is quite a long function and the reason I've done that is because we need this again here so else if if it's it's the same item and there isn't room left in the stack so this one is going to have to come down cuz it's a long one so if the click slot if there's no room left in the stack we need to get out how much is left in the stack so left in stack so again let's just remind ourselves so we've got two versions of this we've got one where it doesn't pass it out cuz we don't we don't need to know but when it returns false we probably do want to know how much is remaining so we can say here item Max data stack size item data uh maximum stack size minus the current stack size so if the max stack size is five and we have three currently this is going to return two so here let's uh open up our uh our curly braces so if it is the same item and there's not room left in the stack let's get out how much is actually left in the stack and we can actually just say if left in stack is less than one we can just swap the slots passing in the click to youri slot so you know if if we have um so here we've got a full stack so as we try and combine them there's nothing left in the stack so that'll be less than one cuz it'll be zero and they they swap and that's just to account for so here we've got our two and we can place five on there so instead of adding three to this and leaving two on the mouse it just swaps them because there's no point you know messing around and adding it to that stack just to leave them when we're going to get the same result from swapping them so we can just swap them directly so if left in stack is zero which is essentially saying is the stack full so let's just leave some notes here so we fully aware of what's going on so um the stack is full so swap the items and we'll do else so else the uh slot is not at Max so slot is not at Max so take what's needed from the mouse inventory so let's do int uh remaining on Mouse and we're going to say equals the mouse inventory item do inventory slot assigned inventry slot do stack size minus left in stack so if we've got five on the mouse and there's left in the stack is on the click slot is two this remaining on Mouse int would be three because we've taken two from the mouse to fill up the stack so then we can say clicked UI slot dot inventory slot do add to stack and we're just going to pass in the amount we want to add this time not just cuz we already know that this the same item we don't need to call assign item we can just add to the stack directly we can just pass in left in stack and then clicked UI slot. update UI slot and then let's update the mouse with how much is left remaining so we can say uh variable new item is equal to a new inventory slot with the assigned inventory slots dat dat and our new uh amount or remaining on Mouse then we'll clear the mouse slot and then we'll update the mouse slot with our new item then we can turn this if into an else and attach it to this whole statement so if the items the same and there's room left in the stack let's combine them if the items the same and there's not room left in the stack to take the full amount how much can it take we're just checking whether it can take less than one so the Stack's full and we'll swap them think about it I don't know if that would ever get called but you know it works so I'll check that in a well let's check that in a second um but we're saying else let's calculate how much would be remaining on the mouse when we fill up the clicked UI slot stack let's fill up the UI slot stack and then let's make the mouse inventory item have the new amount and else if they're not the same so uh else if not is same let's just swap the Dos okay so back in unity uh we can't currently split the stack so it's kind of hard to show this off but what I can do is if I click our um player and I go over you can see that we've got five five and one these are these Tomatoes I can uh change the inventory amount directly so I can say it's three in this one two in this one and then if I that won't update the UI cuz I've manipulated them directly so I'm going to have to just pick them up and put them back down to get the correct amounts in there so now we'll be to see uh the combining of the items so we've got three tomato stack backs here with all different sizes I'm going to add the two to the one so now there's three slots we've combined them 3 + 3 would be six and the maximum stack size is five so I'm going to pick up the three place two into this stack so now there's five in that stack which is the maximum amount and then we can put our one back down and if we click it'll just swap them around because the stacks are full like one of the stacks is full so they won't combine so the last kind of implementation of this is splitting the stacks and then we'll be able to work on the chests and Etc in the next episode so let's get the stack splitting working let's go back over to um our inventory system in Visual Studio okay so let's just come up here and type in uh bu is shift pressed and we'll say this is equal to keyboard. current. leftshift key do is pressed so if the left shift key is pressed when we um click on a slot this would be true and if it's not it'll be false this is using the new input system and it's using it directly if you wanted to use your input action asset and have it so players can um change which key is the split stack key you'll you'd have to do that through the input action asset uh and like maybe use like an input manager we're just going to read it directly here because this isn't an input system tutorial it's a inventory system tutorial if you want me to go over and cover that in some more detail and actually do some input system stuff let me know in the comments below but for now we'll just check it directly and hard code it so it'll always be the left shift key and it's here that we're going to check this and split the stack if um if possible POS so for now I'm just going to say if um is shift [Applause] pressed and then we're going to um and if it is then we'll split the stack so we'll and split stack and we'll say else so if the shift key isn't pressed then we'll just pick up the item as we have been doing so to actually split the stack uh we're going to make a method on our inventory slot so we'll say if shift is pressed and clicked UI slot do inventory slot dot um split stack which is a method that we're going to make in a second so let's go and make that so let's go over to our uh inventory slot class and let's just uh let's come down here and we'll do a public and this is going to be a bull because it's going to return false if we can't actually split the stack for example if there's just one item we won't be able to split it so we're going to say public bll split stack and this is going to pass out uh a new inventory slot cuz it's going to have a new inventory slot with the split amount already in it so we can say uh out inventory slot split stack so let's just start defining this so if stack size is uh less than or equal to one then we're just going to return null we're just going to return false false and split stack will be equal to null but if it is greater than one so if there's multiple items in stack and we can we can successfully uh split them let's just calculate how much half the stack actually is so we'll do Half Stack equals and I'm going to do MAF f. round to int and we'll do um stack size divided by two then we'll take half the stack size off this amount so um let's just use our remove from stack function and we'll pass in the Half Stack size so we're going to take half the stack off the current stack we're then going to split uh set the split stack equal to a new inventory slot with the item data and the Half Stack amount in so if we have four and we've held down shift and clicked we're going to split the stack it's going to split the stack from four divid by two so the Half Stack would be two we'll remove two from the four that we currently have in the stack and then we'll make a new inventory slot with two of the same item in it and we'll pass that back out to our inventory display so we can say out inventory slot and this is the Half Stack slot so we can put uh the so here we know there's nothing on the mouse so we can just update the mouse slot with our Half Stack and we because we've changed the slot directly on the clicked slot we can just update the UI and this will check for its new amount and it'll refresh it and then we can just return because we're done we don't need to carry on and just to be kind of consistent we can put our returns in elsewhere it won't matter too much but let's just return once we get to those kind of key points because there's no point trying to process the rest of the code because we have separate if statement so it'd return and then it' try and do this and it' be confusing so we just need to return out them that should be our split stack oh we're not uh we need to return true here return true there because we successfully split the stack so let's go back over to Unity make sure we've clear the log make sure there's no errors let's hit play so we can now pick up loads of tomatoes and we've got two here we can hold down shift and click and we can pick up one and play place the one down we can combine them back together we can hold down shift split the stack so we'll take uh two from it cuz we've rounded up we can click again we can add two to two four to one they'll swap there two there let's split them again so let's pick up the potatoes if we hold down shift it'll just pick up the slot because it'll just pick up the potato CU we can't split one so it'll just pick it up place it back down we can't combine these items cuz the maximum stack size is one and once the inventory is full it won't put pick up any more items unless it can add them to an existing stack and we can clear our inventory of all of the potatoes and start picking more up so I think that's a good place to leave this video all of the um core functionality of manipulating the inventory is now done uh what we're going to work on in the next video is uh the ability to access the chests so you see in my test project as I walk up to a chest I can press uh a button on the keyboard and the inventory window pops up I can place uh items in it and close the inventory come over to this chest it's a smaller chest there's less uh inventory slots assigned to it we can put in five parts there we can go back to this chest and this chest has its inventory system all set up and ready to go we can take them back out and we've got the same sort of functionality as well so we can put them in and we can split them here and then we can take one out leave one in come pick up the this item you know try and put them in it'll swap and it'll put we can put them back over here so yeah that's what we'll work towards in the next video as always if you're watching these videos as they go out the full series is already up over on patreon which is patreon.com dampas as well is all of the videos I'm exporting packages at each at the end of each episode with the script so if you need to follow along and you want the um and you want the code to check against yours you can get that by subscribing over on patreon if you do have kind of any issues and you want them you want some help let me know in the comments below um the best place to help is probably the Discord though there is a an invite to the Discord in the description box because you can post uh code Snippets there and it's a bit easier to share links to stuff um then a YouTube comments and it's a bit more real time so if you do need any help I recommend uh going over to the Discord but in the meantime thanks for watching and I'll see you in the next one [Music] bye hello and welcome to episode 5.5 I'm calling this one um CU I said in the last episode that the next episode would be uh looking at the chests in the chest system but before I do that I just want to go back through the code and do a bit of a code review um and start commenting so um hopefully going forward if anyone has any issues they can you know the code will make a bit more sense and and I'm going to release this kind of midweek so it's um this isn't going to replace the chest video that will come out when it was supposed to come out and that will be episode 6 so if we go over to our inventory item data script um I'm just going to leave I'm just going to type three slashes and do a summary at the top of this script so uh this is um a scriptable object that defines what an item is in our game it could be uh inherited from to have branched versions of items for example potions and Equipment because they would all have different stats so you know we've defined that an inventory item data at the very top level it'll have an ID a display name a description an icon uh and a maximum stack size you could have like a monetary value as well so you could do uh public int like gold value so how much it's worth and then you could derive a new script from this and have a potion object or have a sword object or some armor so you could have multiple classes that inherit from inventory item data and they would still all plug in to our inventory system because it' have the kind of Base stuff that we need for example the icon and the max stack size so I mean this is all self-explanatory these are all named kind of self-explanatory so I think that's fine so let's kind of move up to uh inventory slot so this is uh a reference to the data of what makes up an item this is the current stack size of the slot so how many of the data so how many of the data do we have these are the public um ghos for these so so this is a Constructor to make a slot of stuff in it so Constructor to make a um occupied inventory slot this is the Constructor that makes a blank slot so Constructor to make a make an empty inventory slot I me self-explanatory but clear is the slot so this one assigns an item to an inventory slot that's already been made CU all inventory slots are created at the start and they're empty so we can actually assign an item directly to the slot so assigns an item to the slot so here we're seeing does the slot already contain the item we're trying to assign to it so does the slot contain the same item and we can add to the stack if so so add to stack if so and else if it's not the same item we're trying to assign a different item to the slot then let's overwrite the data reset the stack size and add how many of the item that we're trying to assign to the new slot so else overwrite slot with the inventory slot that we're passing in we've also got update inventory slot which assigns the data and the amount directly it doesn't reset them and I can't remember exactly where we're using this but I'm pretty sure we are um but just updates slot directly now this code you know some of this may end up being redundant and we can always go through at the end and try and like do a bit of refactor and and tidy everything up because I I I do think I've doubled up on some kind of code systems here but it works at the minute so that's fine um we've got our room left in stack function so um this is checking would there be enough room in the stack for the amount we're trying to add so if we're trying to add two to the stack if the current stack size plus the two that we're trying to add is less than or equal to the maximum stack size then there is enough room left in stack and if there's not we'll can return false so actually maybe we could rename this to enough room left in stack CU that's what we're actually checking we're not room left in stack makes it seem like we are trying to get the amount remaining but we're not always trying to do that we're just checking is there enough room left in the stack to take this amount let's just call that enough room left in stack I mean this is self-explanatory you add to the stack and remove to the stack here we're not taking into account the item data's maximum stack size which could be a bad thing but in the inventory system we are we're taking taking that into account before we actually add it to the stack so that's why we don't ever go over the maximum stack size cuz we are checking that here um before we add it to the inventory and the inventory system so you know we could check and return a bull if it can't but we're kind that's kind of what's Happening Here we're doing enough room left in stack and then we're there is enough room we're adding it to the stack and we're checking that here so this is fine stack size plus amount like it won't ever go above the maximum stack size so here with um split stack again it's kind of self-explanatory but we're saying here um is there enough to split um is there enough to actually split because we can't have 0 five of something we can only have one of something as the maximum so we need to make sure that uh the stack size is more than one so if not we'll return false and nothing will happen but if that is we'll just half the stack get half the stack we'll remove from stack that's this we'll minus the Half Stack from this current inventory slot then we'll just return a new inventory slot with the Half Stack so we can assign that where we need to assign it so create um a copy of this slot with half the stack size so hopefully that kind of makes sense so the next kind of thing up in our kind of hierarchy is the inventory system which it contains all of the slots so let's go over to our inventory system so this is the list of inventory slots that kind of you know makes sense itself which will have a size that we pass in here so this is the Constructor that sets the amount of slots and then depending what size we pass in we just do a loop and add to this list empty slots like so we pass in 10 we're going to make 10 empty slots and add it to our list then we've got our add to inventory which is going to check which again is kind of self-explanatory um it checks whether the item exists in the inventory so does it contain the item and it will pass back out a list of all of the slots that contain the item and then for each of the slots in that list we're going to check is there enough room left in the stack for the amount that we want to add and then if there is enough room left in the stack then we add it to the SL stack and we just return true and invoke our event on inventory slot change so the UI can update there isn't enough room left in the stack nothing happens so if there isn't enough room left in the stack then we come out of this if Loop and we check do we have a free slot so an empty slot if we do have a free slot and we pass back out the the slot that is empty then we update that UI the free slots inventory slot with the amount that we want to add and then we call our on inventory slot changed event so actually here we probably will need to check um for the maximum stack size cuz realistically we shouldn't ever pick up more than you know the stack sizes amount but we do need to check for that so what we can do is we can just check this so if free slot enough room left in stack with the amount to add then if there is we'll update the inventory slot of the free slot and then call our um Onslaught changed event and we'll just return false if neither of these are true so the inventory is full okay so we actually need to rename this to enough room left in stack there's a bit of an issue there let's just see will that get rid of that yeah that should get rid of that error so let's just make sure this uh free slot system works now we've changed it which it didn't so let's just double check what's going on there so we just need to check the item data is actually valid so if item data is not equal to null actually we can just get rid of that and say if item D data is not equal to null and stack size plus amount to add is less than or equal to the item data's Max stack size return true actually if it's null uh we want to say it has enough room in the stack as well so if it's even null or it's not null and the stack size is um you know this this meets the requirement then return true else return false so let's just try that so there you go that's still working so this gets the first available slot checks whether that slot has enough room in it and if it does it'll add it to the inventory this just a bit of a fail save to make sure it never goes over the um stack size and we could also you know here in the future um add implementation ation to only take what can fill the stack and check for another free slot to put the remainder in for example in Minecraft you can put multiple items on the ground you can have like a stack of you have multiple apples and you'll pick them up it'll fill up the stack then it'll put whatever's left into a new stack so we can that's where we can add the implementation there if we want to currently we'll just check the free slot and if the free slot doesn't have enough room left in it stack nothing will happen it'll just stay on the ground and we won't pick up the item so here we're checking um does uh do any of our slots have the item to add in them if they do get a list of all of them and if they do return true if not return false creating a list of all of the slots that equal the item data that we're trying to add to our inventory we're going to put them in a list if that list isn't null so if it has found them then return true and if it is null we'll just return false and this is just get the first free slot so the first slot that has uh no data in it or the data is null so just get the first free slot okay so that's the inventory slot looked at let's go up to inventory holder and this is very simple all it does is it creates a new inventory system based on the size that we've given it and in the next few videos we're going to spin this out into a player inventory and a chest inventory and they'll inherit from inventory holder and they'll have their own kind of uh systems in place but for now I think this is kind of you know self-explanatory so let's look at our Mouse item data script which is the one but when we click on a slot we update this mouse slot so the item Sprite count is all kind of self exponentory the assigned inventory slot that's fine as well um to be safe we can do get and private sets on these because we don't need to set them externally we'll always set them by updating slot on we'll actually use this method to update the slot so this is going to assign the item to our inventory slot it's going to set the Sprite text and color to whatever we've assigned if it has an item follow the mouse so if has an item follow the mouse position as a bit of um a to-do here we're going to add the ability to uh use a controller and it'll follow the controller around the screen instead of the mouse and it'll go from slot to slot so to do uh add controller support we'll do that towards the end though um so if we do have some item data we're going to set the current position to the mouse's current position and if we uh press the left button and we're not over any UI we'll clear the slot here we can have um a to do and this is going to uh drop the item on the ground instead of deleting it if you want to do that we can go ahead and do that um but for now we'll just delete the item we'll click outside and it'll it'll disappear and be deleted all this clear slot is doing is it's just clearing our assigned inventory slot and then resetting the values to kind of their defaults and hide in hide in it so that the mouse item data won't be seen and here's thate code that I got off stack Overflow to just show whether the mouse position is currently um over UI so when we click we're doing a ray cast from the mouse position and we create a list of everything that we hit that's on the UI layer because we're using the uh event system which responds to the uh UI and if this list is um greater than zero then we've obviously hit some UI elements so we won't delete the uh item that's on the mouse but if it is zero then we haven't hit any UI so we're clicking into the world so let's delete the item on the mouse we've already looked at our inventory item data let's go and look at the pickup so this has got a pickup radius and some item data that's all self exponentory collider self exponentory we're getting the collider we're setting the trigger to true and setting the radius to pickup radius and on our trigger enter we're just looking whether the thing that hit us has um an inventory script if it doesn't we're just going to return nothing will happen if it does we'll try and add ourselves to the system's inventory that's successful we we add it to the inventory and that that that happens then we'll destroy the object and if not nothing will happen and we'll just stay on the ground waiting for it on trigger and it to be called again to check again once we implement the player inventory and chest inventory scripts we'll have to change this up slightly but for now now this this is fine so over on our inventory display script so this is just a reference to our Mouse item data this is the object in the game World this inventory system is the inventory system that we are trying to display we set this in our static inventory display by getting it from the inventory holder um we make a dictionary of uh inventory slot UI elements and they kind of system counterparts in our slot dictionary so uh pair up the UI slots with the system slots in a dictionary then we've got a gter for the inventory system and the slot dictionary in case we need them we've got a protected virtual void start in case we need to do anything later on in the start method um and we can override that in our uh static inventory display which inherits from this class we've got an abstract void assign slots which um we don't do here because it's going to be different based on the kind of child classes so the this is implemented in child classes update slot is a method that's called on our inventory system when something changes on the inventory we pass in the slot that's updated and then we search the slot dictionary for that inventory slot and if it is that slot we update the key which is the UI slot we'll update that slot's UI we've said here so slot. value is the under the hood system slot the key is the Y representation so if the system says in slot three system slot three we've updated and we've picked something up it will update the UI slot that's paired with the system slot in our dictionary okay slot clicked um I think I covered this quite well in the last few in the last video we did when we we built this out this is already pre all commented but I'll just go through it again so if the player is holding the shift key which we've hardcoded here um if you wanted to allow the player to change this you'd have to use uh the input system to do that and create like an input action asset for example and here we're saying um does the click UI slot have some data on it we're checking to see whether the item doesn't so um does the clicked slot have item data and does the mouse have no item data if the player is holding the shift key then we'll split the stack else we will uh pick up the item in the clicked slot if we're not trying to uh split the stack and if we can't split the stack because there's only one item in the stack then we will um we'll just pick up the item instead now here we're checking does the click slot not have an item in it and does the mouse have an item in it so if it does then we can just place the item into the click slot and then we're going to check so both slots have an item so we need to decide what to do so here we're checking is it the same item and is there enough room in the stack to take everything from the mouse if there is um both items are the same so we're going to combine combine the stacks we're going to place the mouse item onto the click slot here we're seeing is it the same item and if it is and there's not enough room left in the stack so if it's if there was enough it' do this if it's not enough room left in the stack then we need to find out how much room there is left and kind of account for that so if it's left than one we'll swap the items cuz the Stack's full and if the slot isn't at Max then we'll take what we need from the mouse inventory and add that to the click slot and just leave however much we haven't taken still on the mouse and if it's not the same item so if we're trying to put a potato on a tomato it's not the same item we can't combine the stacks so let's just swap them so we'll assign the Tomato to the mouse and put the potato where the Tomato was and then swap slots we are cloning our inventory slot from the mouse because we're going to overwrite it and we need a copy of it so we can put it back in so here we need to make a copy of the mouse's inventory item because we're then going to clear it and update it with what's on the click slot and then we need because it's cleared that's why we've cloned it so then we can put that information back into the click UI slot so we'll clear we'll make sure the UI slot's being cleared we'll assign the new clone slot and then we'll update the oi slots elements to kind of show the system slot now on the front end uh we'll come back to inventory slot UI let's just stick with the inventory display so this inherits from our inventory display class which we've just been through we're going to call Base start on an overrided start just in case like I said we want to call anything in the inventory display start and now here we're saying if our inventory holder isn't equal to null and let's get the inventory system of our inventory holder and subscribe the on inventory slot changed um subscribe to the on inventory slot changed event and assign our update slot function to that which is on our inventory display so that's uh this here which is called when we add an in an item to our inventory from the ground so we're going to subscribe to that method I'm going to debug.log a warning here if this isn't the case just so we know what the problem is that there was no inventory assigned to the object and then we can just assign our inventory slot systems which is this abstract method which I've said is implemented in the child classes so that's implemented here so it's public override void assign slot it takes in an inventory to display which is our inventory system it creates a new dictionary in memory from that slot diction that we we've decided we need because this is a static display it needs the right amount of slots for the um inventory size so here we're saying if the slots. length which is an array of our prefab UI slots if that's not the same as the inventory size then we'll just debug.log um to say that the slots at sync but if that's not the case then we will um go into a loop and well add to our dictionary that we've just made we'll add the slot and its corresponding system slot and we'll initialize this um and we'll initialize the UI slot with its counterpart um inventory slot from the system so in our init function you can see that that just assigns the inventory slot and then updates the UI slot um just in case you know if we if we're loading the game and something's already in inventory system then it'll update it'll it'll show that straight away it won't just be a blank UI slot so finally over on our inventory slot UI we've got that in it function like I just mentioned um but this is kind of like the mouse item data so there's the Sprite the count and an inventory slot which is been assigned it's also got a button element on it and then here we're just getting that button we're subscribing our onui slot click event to that and we've also got a variable called parent display which gets the inventory display component on our transform. parent so the inventory slot UI are childid to the parent display which is inventory display that could be static or it could be the dynamic inventory display but we're just getting the top level inventory display cuz that's all we kind of care about and the reason that we only care about that is because when the slots clicked we're going to all we're going to do is access our parent display block clicked method and pass ourselves into it and that's on inventory display. CS that's not on the static inventory display so other than um in it we've just got update UI slot and then we're going to update the UI slot and pass in a inventory slot to display so we're going to say if slot. item data isn't equal to null then we're going to set our Sprite and the color to Y and then we're going to set the sack size and if it's over one we'll set that and if it's zero we won't display any any number in the stack size and if the data is null if if the inventory slot is um empty then we'll set the item count. text to blank the Sprite invisible and we'll null out the Sprite then we've also just got a version of that method that doesn't take an inventory slot and we call this when our assigned inventory slot isn't equal to null so we call this method and pass in our assigned inventory slot and then we've got clear slot which just um clears out our assigned inventory slot so it empties it clear slot it just sets it to null stack size minus to one and it sets our item Sprite to null our color to null and our text to just blank I mean that's all pretty self-explanatory so I've not bothered to leave comments on that okay the problem I just notice the problem we can't do get private set here because if we do that we can't set them in the inspector so let's just get rid of that we didn't need to do that anyways it's fine that these are public if we wanted to have a getter uh we could make them private and serialize so we can set them ins Spector and then do what we're doing here and just make public property but let's just reset that to not be getting private set and then actually in our Mouse object we'll have to reassign our image and our item count that was a silly mistake on my part but yeah so this is where we are at that's all of the code in review we can pick up everything it'll add itself to a stack if we move this to the end and pick up more Tomatoes it'll add it to that one cuz it'll find it that's full so it'll find the first free slot so that's that's where we are that's the end of episode 5.5 which was the code review which was an extra kind of lesson to go through um just to kind of recap on all the code I hope that all makes sense and I hope if you were confused about anything previously that that's kind of cleared it up and you kind of get it now as always leave a comment below or join the Discord server if you want to um if you want help with anything if you're watching these videos as they're going up live the full um series all the way through to the end is currently available over on patreon.com dmos and so are packages from the end of every um lesson I save out a package with the scripts in that current state so you can compare your code with the code from that lesson if you want to again they're over on patreon which is linked in the description but for now thanks for watching and I'll catch you in the next one [Music] bye hello welcome to episode 6 of the inventory tutorial Series in this episode we are going to be covering the dynamic display so in the minute we've got our static display so there's always 10 slots and these slots fill up with with our tomatoes and our potatoes or um so these fill up you know and these are static these are always the same um but we have a small chest here and a big chest and we want to be able to access the small chest and the big chest and we're going to have a window that pops up and displays their own um individual inventories but you know we don't want to have to make a different screen based on every sort of inventory size that we want cuz we may want some to only have one inventory slot something to have 30 we want a bit of bit more of a flexible system we can do that by making a script that derives from our inventory display class so just like our static inventory display inherits from inventory display we're going to make a dynamic uh inventory display script so let's just right click create C script and we'll call this the dynamic inventory display and let's just have a look at how this is going to work so this is the test project here so if we hit play you so I've got my heart bar here I can press tab I can press B on the keyboard and my backpack inventory comes up and I can go over here and I can access the small chest which you know here has uh I think that's 10 10 slots or we can go across to our big chest then this has got 20 slots and our backpack has 50 slots I believe yeah so there we go we got 50 slots in our backpack so you can see how that's scaled up um might need to play with the anchoring cuz it's it's gone up to the top of the screen but we can we can do that we can sort that so let's go back to the project that we're currently actually working through and let's just open up our Dynamic inventory script so again our Dynamic inventory display is going to um inherit from uh inventory display which is the kind of Base Class so let's replace monob Behavior with with inventory display and let's just get rid of the uh let's get rid of the update function and get rid of uh this comment and we can just say uh protected override void start and we want to say uh base do start but before we do the base start what we can do is we can subscribe to our inventory hold holders on Dynamic inventory display requested event so we can say inventory holder do on Dynamic inventory display requested and I'm going to um subscribe uh a method that we've not created yet called refresh Dynamic inventory display uh no just let's call it refresh Dynamic inventory and we can even make this just public void refresh Dynamic inventory and this next to needs to take in an inventory system and I'm just going to call this the inv to display and here we can say our inventory system is equal to the inv to display so inventory system is the inventory system here this is the inventory system um on our inventory dis display and we're just setting that to the inventory to display that we're we're bringing in we're bringing that in from our inventory holder script on our inventory holder script we've got this Unity action which is static so we can access it from anywhere like we've just done and it's called on inventory uh on Dynamic inventory display requested and it passes in an inventory system and we're not currently invoking this anywhere yet uh we will do in a second we'll work on the getting the players backpack working first and then if we have time in this video we'll work on the chests if not we'll do the chests uh in the next video let's just see how far along we get so let's go back over to our Dynamic inventory display class and let's just finish implementing this so we have a red squiggle that's because we aren't implementing the abstract uh class uh the abstract method that we made in our abstract inventory display play class and that's our assigned slots function so let's just get rid of our um system not implemented error the first thing that we want to do on assign slots for our Dynamic inventory displays we want to clear all of the slots that were there from the last time that we looked at an inventory so you can see that when we were accessing the chests in the project my test project that I've already got set up I you know the actual slots delete when we close the the um we'll close the panel and then when we go to open up the panel of a different chest it'll clear all the slots it'll just delete all of the prefabs and then it'll spawn them back in uh it'll spawn the correct amount back in so instead of 20 slots there'll be 10 or five or however many the inventory display has or needs to like actually request so the first thing we'll do here is we'll do private void and let's make a method called clear slot and we need to be using um system. link here so what we're going to do here is we're going to say for each uh variable item in transform do cast transform so this is going to get all of the um children on our transform so this is going to sit on the top level object and it's going to have have UI slots underneath it so it's going to get all of those and we just need to say destroy item. game object now a more efficient way of doing this would be to use object pooling so instead of destroying and instantiating new slots we could just disable them and clear them and uh add them back to a pool this isn't an object pooling tutorial so we're not going to um do that here we're just going to act directly destroy them but just know that that is an option um if you want to go and look into object pooling you can you can do so and this is that would be a better way to do this but for now for what we need this this works fine so as well as this and destroying the actual objects we want to clear out the um slot dictionary so we can say if slot dictionary is not equal to null then slot dictionary. clear and again just to remind ourselves the slot dictionary is the dictionary that pairs a UI slot with an inventory system slot so we clear that out when we clear the slots so in our assigned slot function we can just say clear slots and then we're going to do a similar thing to what we do here in our static inventory display when we assign our slots we're going to pair we're going to pair a slot with our inventory systems inventory slots um array so first thing we're going to do is because we've cleared the slots and we've cleared this we can all we can just make a new dictionary over the top to make sure that it is definitely clear so new dictionary inventory slot UI inventory slot is the key and value and we can say that if INF to display equals null then let's just return out of this cuz we don't want to start um accessing it if it's null so it's just a good way of checking to make sure that we're not going to get any um null uh reference exceptions and then we can say for INT equals I whilst I is less than the in to display do inventory size we're going to make a new um reference to a UI slot which we are going to instantiate so instantiate and I'm just going to say slot prefab which is a variable we'll set up in just a second and then I'm going to put the parent as this transform and let's come up to the top and let's just make a serialized field protected inventory slot UI slot pre uh slot preab and I'm just making this protected just in case stand line we want to um inherit from this class for example we may want um Dynamic inventory displays to we may want some of the functionality that this provides but expand on it a bit more for example um NPCs with a shop they would have uh multi probably Dynamic inventory displays or they'd have some custom functionality that chests for example wouldn't need um so we're just making that protected just in case down the line we want to access it we don't need to come back here something I've um I forgot to do because we're subscribing to this event here we just want to unsubscribe from it if we um need to so I'm just going to say UND destroy I'm just going to say minus equals refresh Dynamic inventory that's something that uh we need to do um but let's come back to to our assigned slot so we're going to get a variable called UI slot and it's going to instantiate this slot prefab and then just start a reference to the the specific slot prefab that has been created and then we're going to add it to our slot dictionary and this UI slot is going to be the key and the um value is going to be the inventory to display do inventory slots I because you know we're we're in this Loop and it'll go for this is going to create the exact amount of slots that it needs and it'll pair the slot with the current uh index that we that we're on in the for Loop and then we can say UI slot do init for initialize we can pass in the inventory to display uh inventory slot I and then we can just call UI slot um update UI slot here so this is just like our static inventory display so we're doing a loop we are adding the slots but we just because the slots haven't been defined here and up under our um base. start I'm just going to assign slot inventory system and pass in our inventory system I'm just going to do that once so it clears it out and it sets up anything that it needs to set up found that not doing that here when we um access it the first time in game it wouldn't actually show anything that was already in the inventory so we just need to um run this method uh just once here and that sorts that out so if we um press contrl s to save that now let's just go back over into um unity and let's go to our canvas and underneath our canvas let's just open this up so here I'm just going to make an empty object I'm going to create empty and I'm going to call this the inventory UI controller and I'm just going to make our hot bar and our Mouse object uh a parent of the inventory UI and then for our inventory um and then underneath our inventory UI controller I'm going to right click create UI and I'm going to choose panel I'm just going to call this um Dynamic inventory and I'll bring this just up uh above the mouse object just so the mouse object renders on top of the uh UI element that we're going to make and I'm just going to add add component and we're going to add our Dynamic inventory display and I'm just going to drag in our Mouse object uh item to our Dynamic inventory display and I'm going to go over to our prefabs and I'm going to drag in our slot prefab over to it so now let's get um a Content size fitter added to this and we can set this to Preferred size and then we want a grid layout group we've got our grid layout group and under padding I'm just going to put some padd in in so 10 10 10 for cell size I'll have that at 100 and I'm going just put some spacing in as well for child alignment I'm going to choose um upper Center and constraint I'm going to have a fixed column count and I'm just going to have 10 columns as our fixed column count so if we just drag our prefab directly under our Dynamic inventory we can see kind of what that's going to look like like so let's just add them in so you can see that how that's going to look when we add sort of more and more so that's with 51 slots which is probably too many anyway so let's just delete all of those out press contrl s to save so we've got our Dynamic inventory here let's go up to to our inventory UI controller and let's try and get this set up and working so we need to make a script on our inventory controller so let's go back to our UI scripts folder and let's right click create C script and we'll call this the inventory UI controller and let's open this up in visual studio so here for the inventory UI controller I'm going to keep the update method and I'm just going to get a public uh Dynamic inventory display and I'll call this the uh inventory panel which is what we've just made and here I'm going to um oh make a on enable function and on enable I'm going to say inventory holder do on Dynamic inventory display requested and I will put a display inventory method which we're we're going to create and then on disable we'll just want to unsubscribe that method from it as well just to be safe so we can minus equals inv uh display inventory and then in our display inventory uh function which we'll make here void display inventory which will take in the inventory system INF to display so this is going to say inventory panel. gameobject do setactive to true and inventory panel. refresh Dynamic inventory and pass in the inv to display which actually thinking about it that makes this redundant um we don't need to do this so let's just uh comment that out and we can actually uh get rid of this as well we don't want we don't actually need to um call it on start so let's get rid of those the reason that we don't need to call it on start is because in our inventory UI controller when we said it's active we're refreshing It Anyway passing in the inventory display so now we're only subscribing to this event in one kind of place which is fine that's that's not which is a bit cleaner than subscribing here and calling it twice and we can actually say here in our refresh Dynamic inventory we can call clear slots here take it out of aign slot and we can call aign slot here so a little bit of refactoring so now on our UI on our inventory UI controller this is going to receive this request to display an inventory it's going to set the panel to active and then it's going to refresh the dynamic inventory which is going to clear out any old slots it's going to update the inventory to display and then it's going to assign um slots which will do do all this so let's save that go back over to our inventry UI controller so let's just test this is all working now so let's say using Community engine. input system in our update function on the UI controller we can say if key uh keyboard. current do I'm going to say uh b key for like bags so if the b key dot is uh was pressed this Frame then we're going to um we're going to bypass this method and we're just going to display inventory and we'll make a new inventory system with a size of let's say 30 so we'll just uh you know we're just making a new inventory system here when we press the b key and we're displaying that and and actually let's just see this working so we can actually say random. range and we'll say between 20 and 30 so if the b key was pressed display the inventory and create a new inventory system to display with a random size of between 20 and 30 and then we can say if um the inventory panel. gameobject do is uh do active in hierarchy so if it's set as active and keyboard do current. Escape key was pressed this Frame then let's set the panel back to false let's close our bags so let's just check this is working so we can go over to um hit play and we need to add the uh inventory UI script to our controller we need to dis uh assign our Dynamic inventory display and what we can do is we can set it to false in the awake method so it's we just we know that it's going to be um closed already when we first start so let's just set it to false if it's not already so you can see that the dynamic inventory is enabled at the minute when we hit play it'll um disappear so we've got our inventory here we can press B to open our bags and you can see that it's created our inventory slots if I press Escape it'll close the panel and they are still there um but when I press B again it'll delete them and it'll make another one of a different size we can press Escape B so you can see that here we're now getting a panel that responds dynamically to different inventory sizes now obviously if I put a something in this when I press Escape it's getting deleted the inventory system we're making so those items will just um you know disappear so let's work on doing this so it's actually permanent so let's make a chest now so let's go back over to our inventory system uh project and we'll get rid of this we don't need um that let's keep this one though so we can press the Escape panel to close any sort of chests that we're looking at bring that down so we can actually see that so it's a bit more uh neat so we've got um so yeah let's make our chest script now so here let's go over to our project again let's go into our inventory scripts and let's make a new C script called chest inventory let's open that up and this is going to um inherit from inventory holder and we're going to get rid of the start and update function and we're actually going to use um using Unity engine. events because we're going to need to implement um a Unity action which will pass in the type of I interactable which is an interface we're going to make in just a second and this is going to be called on interaction complete which we can put get and set we won't actually use this in this tutorial but it's going to be enforced by this I interactable which we're going to make now so let's go back over to our project and I'm going to make um a new folder in our scripts folder called interfaces and we need to make an interface for all of our interactable items in the game so cop script and let's call this I interactable so let's open up that script and this again is going to be using Unity engine. events it's going to be an interface so let's get rid of mono behavior and public interface I interactable so it's going to need a public Unity action which passes in a type of I interactable called on interaction complete with a get and set we're going to have a method called public uh void interact which will take in um an interactor which is another script we're going to have to make I'm just going to call that interactor and it'll pass out a bll of whether the interaction was um successful and we also want a public void end interaction so let's just uh copy this let's go over to um unity and in our scripts folder let's right click create C script and let's call it intera so now that's um that's fine that's filled in let's just line that back up I'll work on the interactor script in just a second let's go back over to our chest inventory and make sure this is inheriting that interface so I interactable and we should get a squiggle in a second yep so we press alt and enter it'll add those um the interfaces methods let's get rid of them and I'm actually going to move interact up above uh the end interaction just because it's a bit neater like that way so interact is going to be a method that was that's called when we try and interact with the chest so when we open the chest so obviously here we need to um say on Dynamic inventry display. requested is anyone listening out for this event and if it is let's invoke it and pass in our inventory system so again this is deriving from inventory holder this event is on our inventory holder and so is our inventory system so we're going to call that event when we are interacted with and we're going to um pass out we're going to invoke that and pass in our inventory system and then we can say interact successful is equal to true so we're not actually going to use end interaction here uh this is just enforced by the I interactable uh interface stand line maybe you want a event um on interaction complete to fire when something happens then you'll call that in the in end interaction function and for example so for example if your player moves away from the chest that you could call on interaction complete and be listening out for that on the UI controller and then so instead of pressing escape then so instead of pressing escape you'd be listening out for that event and that would set the panel to false instead but I'm just going to keep it like I'm just going to try and keep it simple so we're just going to interact with the chest and we'll call the on Dynamic inventory display requested and we'll just pass in our inventory system so now we need to be able to actually interact with the chest and that's what this interactor uh component is going to be this is going to sit on our player so let's go build that quickly there's lots of different ways to do this um the way I'm going to do it is I'm going to make a public transer form and call this interaction point I'm going to have a public layer mask called interaction layer I'll have a public float which which is the interaction um Point radius and I'll set this equal to 1f and I want a public bull called is Interactive with a get and private set and in our private void update function we're going to make a variable called colliders and we're going to equal this to physics do overlap sphere and we're going to pass in the interact point do position as well as the interaction Point radius as our radi radius so as we're walking around if we interact with anything um you know on the and then we need to pass in our interaction layer as well as the third parameter so as we're walking around if we overlap anything that um is on that interaction layer at that position and within this sphere that we're making it'll store it in a collider array which you can see there so collider array physics. overlap sphere that's what it returns so this will be a collider array called colliders and now we can say that if and we'll say keyboard dot uh we need to be using sorry using Unity engine. input system so here we can say if keyboard. current Dot and then whatever key you want I'm going to use the uh e key dot was pressed this Frame then we're going to Loop over all of the ciders that we are currently um overlapping so colliders do length i++ I'm going to say VAR interactable is equal to colliders I do get component I interactable so we're going to check every collider that we're interacting with to see whether it's got the interactable interface on it if that's successful interactable won't be null so we can say if interactable is not equal to null then we've successfully found an interactable item which is what this interface uh indicates so we can just say um start interaction and we can pass in the interactable and all I'm going to do there is this is going to be a um void start interaction which takes in an i interactable called interactable and it's just going to say interactable do interact and it's going to pass uh itself in and get back out the interact successful uh bull the reason I've spaned this out as its own method is because in your movement script for example you may want to be checking the interactor component to see whether there is interact in ball is set to true and if it is true you may want to disable movement so here you could say um is interacting is set to true and then at some point you could have an end interaction um you know an end interaction method that sets is interacting back to fault and you'll call this somewhere in your script depending on your code so for example we can say here if we if colliders do length is zero then we're not interacting or if we become if we move a certain distance away from the thing that we collided with we could choose this uh this is just a way of keeping track of what your the interactor is doing it's not going to have any effect on you know what we're doing but hopefully this is just something extra that you can expand upon again this is a tutorial on an inventory system not an interaction system or something like that if you want me to cover this more in detail let me know in the comments below but just know that all we need is uh this interactable do interact so we're overlapping anything here and the E key was pressed this Frame then we're going to search for the through the overlaps we're going to try and find the interactable component on all of these colliders and if we find one we'll start our interaction which will call interact on our I interactable which in this case would hopefully be our chest inventory which will just say on Dynamic inventory display requested passing in its inventory system and then our Dynamic inventory display would would show that so let's get this all set up so we can get that working and I think that would make a good point to end the video so we've got our player movement script on our player let's just add our interactor script and we need an interaction point so under our player let's make an empty and that's 0 0 Let's just call that interaction Point let's move it forward and I'm actually just going to um give it a little Gizmo so we can see it in the scene and we can assign the interaction point on our player script on our interaction layer we can make a new layer and we'll call it um interactable and then we'll go back to our player and we'll choose the interactable layer as our interaction layer and our radius um let's set it to let's just leave it at one for now and let's go over to our small chest let's add a chest inventory component to it and we'll say the small chest can have have an inventory size of 10 and we'll make sure that it's got a box collider on on the actual um inventory on the chest so let's bring this up uh one five maybe there we go and let's remove the colliders from the cubes underneath it so we'll just remove components set our a small chest onto the interactable layer and we can change the children as well it doesn't really matter for our big chest let's again add a box collider let's bring it up 0.5 increase the scale on the uh X to just match the shape of our um chest get our cubes remove the Box collider go back to big chest set it layer to the interactable layer yes change children let's give this a chest inventory script and let's say the chest inventory has a size of 20 so our small one's got a size of 10 so let's see if this works and if it doesn't let's debug it so we'll hit play we'll pick up some items on the way so you can see here that our little yellow Point that's fly over here all your yellow point is over is inside our chest you can see that I've pressed the button and the the panel has come up we can press escape to get rid of it we can press e Al so I opened up the big chest so we press e the big chest with 20 slots opens press escape to close it and come over here press e the small chest opens press escape to close it we can open it back up with e we we can put our tomatoes in it we can press escape to close it we can pick up some potatoes open up our big chest we can store our potatoes press Escape go back over to our Tomatoes press e to open it our tomatoes are there press shift split them we can do all of the same stuff we can you know leave our Stacks there like this press a uh press Escape walk over press e on our big chest get a potato back out maybe leave three in put a tomato in press Escape walk back over here access this chest all of our tomatoes are there and this because obviously over in our chest inventory system when we close the panel all of our inventory slots stay there so if we press Escape obviously the chest inventory script has its inventory system on it and that's now full of those items so they exist in memory even when we're not actively viewing them so that kind of works exactly as you would expect it and we can move them again get them here you'll see that we've got one tomato in slot one let's combine these so now we've got four tomatoes these are all null now because they're empty we can pick them up put them back in our inventory hit Escape pick up some more stuff so everything is working as we would expect so hopefully I explained the interaction system okay I did very much gloss over it um if you have any problems or would like to see another series on the interaction sort of script and how we can get that working in a bit more detail do let me know in the comments below but I think that will do us for now I think that's a good place to leave it we've got the chests set up and working it all came together quite quickly at the end as always if you're watching this as the videos go up weekly uh the full series is complete and already up over on patreon which is patreon.com dpos and you can find a link for that in the description as well as the full series you'll also find the project files so at the end of each episode I'm exporting the scripts kind of as is like this project where we are now I'm saving that out as a package so you be a to compare your um so you be to compare your scripts with my scripts to see if anything's going wrong if you do want any help with anything if You' got any questions uh either leave a comment below or better yet join the Discord server cuz over on Discord it's a bit easier to get real time feedback and you can share your scripts easily you can share code exerts a link for the Discord is in the description below as well in the next episode we'll work on the players backpack system so they've got the hot bar and um if we Press B it'll open up a dynamic backpack display and when we walk over the items if the hot Bar's full they'll go into the player backpack instead so that'll be in episode seven which is the next episode which will a in a week if you're watching these as they go out but in the meantime thanks for watching and I'll see you in the next one [Music] bye okay so welcome to episode s of the inventory tutorial Series where we left off in the last episode we got chest inventories working so you see that as we play the game we can walk around and pick up these objects then we can come over here and access our chests and put objects in the chests we've got all the same functionality where we can split up all of our items we can back out of the chests pick up some more stuff go over here access this chest put our items in the chest back out walk away and you know just as you'd expect it to work so the one thing that's missing really is that the player doesn't have a backpack and we've only got the hot bar and then that's it we can't once the hot Bar's full we can't pick up any more items so the next thing I'm going to work on is giving the player a backpack pack so when we Press B uh a similar panel to this will pop up so we can put things from our hot bar into our backpack and then walk away and close it and carry on going about our business uh and one thing that we I want to add is the ability so now once we pick up inventory items um it'll check the hot bar first and if this is full it'll move on and it'll check for a player inventory and then it'll add themselves to that and this will help solve another issue as well so if if I give this item a rigid body and then hit play all that's happening with this pickup script is it's just looking for an inventory holder component it's not looking for specifically a player it's just looking for um the chest it's just looking for an inventory holder script which a chest is it does have the inventory holder script on it so so if there was a character walking around and they accidentally like you know walked through the item they'd pick up the item you may only want it so it picks up the player in the room a couple of ways we can solve for that um one of those is the fact that only the player has a rigid body so if they were the only character in your game to use a rigid body then you know it wouldn't go over it wouldn't go into the chest if something with a rigid body collided with it whereas if it collided with the player it would we could also check to make sure the thing that hits us is tagged with the player um player tag that's one way of doing it but because we're going to be doing a player inventory holder anyway we can just make our item pickup look for the player script not any other kind of inventory holder script so let's just get started on that so the first thing we want to do is we want to come over to our inventory scripts and then we can right click create C script and we'll just call this uh player inventory holder so let's just open up this script in visual studio so just like our chest inventory script this is going to inherit from inventory holder so inventory holder I'm going to keep the update so I can uh listen out for a keyboard press um and for that I'm going to want to use Unity engine. input system and we'll look for when we press the b key I'll do that in just a second the first thing we want we want to uh we can get rid of the start function and we just need to serialize uh field and make a protected int backpack size so on our inventory holder script we've got our inventory system which has an inventory size and I might actually want to rename this I'm going to Right double click right click rename and I'm going to call this the private uh primary inventory system and I'll do the same for this rename primary inventory system so in our player inventory holder script I can actually rename this to secondary um inventory size oh and we can have a serialized field protected inventory system we can call this the uh secondary inventory system and then we can have a public inventory system called secondary inventory system which just returns that and we need to override our awake function so we've got private void awake let's just change this to a protected virtual void awake so our protected virtual void awake we're going to make our primary inventory system but on our player system we can do protected override awake which calls the base awake so that'll set up the primary inventory system and then we can say secondary inventory system is equal to a new inventory system with our secondary inventory size so we're going to use this event this on Dynamic inventory display requested just like our chest does um and I'm going to listen out for the b key so if keyboard. current do b key was pressed this Frame then we'll just call the on Dynamic inventory display requested and we'll we'll invoke that and pass through the backpack uh the secondary inventory system so let's just hit save there and close this down so we can go over to our player script and instead of our inventory holder script let's remove this and let's add in our new player inventory holder and we give our uh primary inventory system which is our hot bar in this case uh 10 and our secondary inventory system let's give it a size of 30 let's just hit play we've got a error here and it's because we need to reset our our player hot Bar Needs a reference to our inventory holder so now if we hit play so that's all working we've got our hot bar that works we can press B and it'll open up our backpack we pick up some more items so you see at the moment as we go over it the items aren't adding themselves to our inventory backpack they're staying on the ground so that'll be the next thing we work on so let's go back over to our inventory system script and back over to our inventory holder script so in here on our player inventory holder similar to our inventory system script we're going to want a public bull add to inventory and this is going to take in the same parameters as our uh inventory systems up to inventory uh method so this is going to take in an inventory item data called Data and an amount so the first thing we'll do is when we pick up an item We'll add it to our um primary inventory system which is our hot bar in this case so add to inventory and pass in the data and the amount and remember this returns true or false depending on whether it was successful in adding it to it so if it was successful then let's just return true because it was successfully added to our hot bar if it returns false then let's try and add it to our um secondary inventory system passing in the data and the amount and we can just return true if it manages to go into our backpack and then we can just return false if that wasn't successful so let's go back over to our script here and what we're going to need to do now is we need to refactor very slightly the item script so let's choose an item and we'll open up our item pickup script so here instead of saying um get component inventory holder we can just get component uh player inventory holder because this is a VAR it doesn't matter we don't need to uh make a new type this this still works and then instead of saying primary inventory system. add to inventory we can just call add to inventory directly on our inventory holder and that should just work as is so let's go back into unity and we'll hit play so now as we go over we'll see our backpack fills up with potato uh our hot bar fills up with a potato and then they start to go into our inventory you'll notice though that they don't um refresh while we go over it we have to open up our backpack again so let's solve that next to do that let's just go back over to our Dynamic inventory display and because this works in the same way as our static inventory display though where we make a new dictionary and pair up a UI slot with one of our system slots we can subscribe to our inventory system method uh uh event on inventory slot changed and where we want to do that is we can subscribe to it in our assign slot function so underneath inventory to display actually we can do that in the refresh Dynamic inventory where we assign our inventory system here what we can then say is inventory system dot on inventory slot changed and then just subscribe our update slot method to it and just to remind ourselves when that's called it'll look through the slot dictionary and if the system slot exists then we'll update the UI slot for that UI element so we can come back over to our Dynamic inventory display and we just want to make sure that this is valid first otherwise we may get an error so we can just say if inventory system is not equal to null then let's subscribe to its un inventory slot changed event let's just copy this and then when we close the panel with the Escape key we can call undisable and we can just unsubscribe from the event so let's hit save go back over to Unity so we can pick up all these potatoes and you'll see that as they start to go into the inventory they get as if it's open while we walk over them it fills up the inventory and press escape and close that come over to our chest put in the potatoes and pick up some Tomatoes put them in there and close that you see they're all still there we haven't got any errors in our console log and that's not filling up this panel cuz this is a different inventory system so we can close that open up our bag and there's the Tomato that just got picked up so that was all working that's a very simple little change but that allows you to kind of carry and walk around with your bags open so instead of having the backpack be a dynamic inventory system you could set it up um as a static inventory system if you know that your backpack's never going to change throughout the game in terms of size you could set it up obviously as a static um system just like the player hot bar and then that would allow for you know positioning so your backpack up here then you could redesign the inventory the chest system to come over here and you may want to move stuff from your backpack over to your inventory system so what you could do there is if we go over to our Dynamic inventory display and then let's set the constraint count to five columns instead of 10 so it's not as long it's like half the width and let's anchor it to the right side of the screen and we can drag over the X column so it's positioned kind of over here on the right hand side let's do 450 why not so we know this is going to be the width of it so let's just see what that looks like when we actually open it up so we've got our uh d Dynamic inventory displayed there so that was when I pressed B on the keyboard it opened up that we could probably move it up a bit as well so now let's just control D and copy this Dynamic inventory and let's rename this to player backpack and again make sure Mouse object is at the bottom of the hierarchy so it appears above all of the elements and let's go over to our inventory UI controller and open up this and we need to copy this and rename it to um like player backpack panel we can just call this the chest panel instead and actually I'll right click rename so it changes throughout the code so chest panel and then what I'm going to do is I'm going to go over to our player inventory holder script and then go through to our inventory holder script and I'm just going to copy this action and go back to our player inventory holder script and then down here let's just say using Unity engine. events so we can get a Unity action that passes in an inventory system and I'm going to say on um player backpack display requested so on player backpack display requested so it's a public static Unity action passes in inventory system and it's called on player backpack display requested and I'll copy this and I'll just swap out that event the on Dynamic display to the on player backpack display requested we'll go back over to our inventory UI controller and here we can say player inventory holder do on player backpack requested and we can plus equal and I'll say display play ler backpack copy that unsubscribe for it on the UND disable function let's [Music] um copy this method and we'll say display player backpack and what I've done here is I've said display a player backpack which isn't what we want so let's just copy this back up so it's spelled exactly the same and instead of chest panel this is going to set the player backpack panel player backpack panel and then again we can copy this and say player backpack panel so we'll close it if we press the Escape key so let's uh now minimize this and go back into Unity we've got our player backpack which is in the exact same place as our Dynamic backpack so let's now snap this over to the left hand side put the anchor over the left hand side and we'll drag this across to the left of the screen and I'll mirror The Wire axis so we'll just completely mirror this so minus 450 and then our Dynamic inventory is it um I'll say 115 Play Backpack 115 so they're at the same sort of size and height now so we press play now nothing happens and I think that's because we need to go to our inventory UI controller and drag in our backpacks so player backpack panel go goes into the bler packpack panel Dynamic inventory can go into the chest panel is that what the issue was object reference not set yeah and actually let's duplicate um this and we'll do the same we'll close the player backpack panel as well and we hit play see now we can open our bags that's going to come up on the left hand side we can pick up all of our items the we go into the player backpack then we can come over here and we can open up a chest panel so these are the two different chest panels and our backpacks are still open and we can move stuff from our backpack into the chests and we can close out of them go back into the game we can pick up the uh Tomatoes off the ground they've of course gone into our backpack and then we can come over we can open our chest we can combine these items we can split the stack actually and take two back out come over here open up this next panel bring in our Tomatoes here take a couple of tomatoes uh potatoes from our hot bar put them in the small chest exit out you know take more out so that's all working kind of as intended so that's going to be it for this uh for the initial kind of batch of videos of this series if the series does well and it's has a lot of interest and people actually watch it and want to see more I do have some ideas of where I'd like to take it uh I'd like to introduce um an NPC that you can sell items to from your backpack because obviously the NPC will need their own inventory system with a cell button that um you know it'll com it'll check all the value of everything that you're trying to sell them and then it'll give you that amount of gold back so that's something I'd like to kind of do in the future if this if this series works and it's well responded to I'm currently looking into kind of the best method to save the backpack system obviously this video doesn't tell you how to save and load so if we go back and hit play obviously everything everything resets so I'm currently prototyping how I personally go about saving this inventory using Json so that'll be kind of an update to the series as well down the line if if I can figure out that and get it in a concise way to pass that over one very simple and easy way to do that is instead ofad of our inventory system just being a normal class this could be a scriptable object so instead of adding um on the inventory holder creating a new inventory system here what we could do is if the inventory system was a scriptable object like our items you could have it so you could rightclick create inventory system and instead of inventory item you could have an inventory like underneath it you could create an put it size in and then assign that in our um player holder script because um the data in a scriptable object if you change it that's just how it is it doesn't reset so if I H if I hit play and if I come over to the potato and I said it's gold size to 10 so for example if this was a scriptable object and it was an inventory system and I had loads of inventory items and I changed how many I had when you stop playing this data stays the same and that that works even when you build the project as well so um a kind of easyish way of saving your inventory systems is to use the go the scriptable object route but because I know I do want to build a save load system anyway I've gone for the kind of normal class route so that'll be kind of a an expansion if you will to this series if if that's what people want there's anything else specific that you want to see in an expansion to this course let me know in the comments as always the project files for this entire course including all of the scripts from each uh individual episode I've exported each episode script at the end of that episode um if you want to compare your script to what I've done then come over to patreon.com dpos and you can get access to them there if you support me on patreon if you want to discuss the course or get help with any kind of elements of this course or this this episode in particular then again leave a comment below or join the Discord server which is linked in the description but in the meantime thanks for watching and I'll see you in the next one [Music] bye hello welcome to today's video which is episode 8 of the inventory tutorial Series in this video we're going to work on creating a save load system which you can see here so I'm going to say walk over these um tomatoes and we get some of these potatoes in this chest I'm going to place our four tomatoes in this chest I'm going to place our two potato actually I'm going to put one potato there and I'll put a potato here and I'm going to walk away hit save you can see here that we've got our save game file I'm just going to open this and you see we've got some collective items some active items we've got values um so this is our chest and our inventory and how that actually looks in game is if we come out and hit play so those items that I picked up at back the chest will be empty if I hit load the items that we' already picked up are going to disappear and we can go back over we can see that our one potato is here in the chest our four tomatoes and our other Potato so if you want to see how I did this stay tuned and make sure to pay the course fee which is one like or one subscribe and for bonus points why not hit the Bell notification but with that said let's just jump into this and see how it all works now as a prerequisite I guess for this video uh I recommend you watch this save data video I did I explained the concepts kind of behind what we're going to be doing here so I'm not going to cover over them I'm just going to go quickly through kind of the code um so I do recommend using watching through this video first that said obviously if you are a patreon you can download the files and use the code or just follow along as I type the code out I'm not going to be explaining kind of every little thing I'm doing with the save system uh cuz I've went into a lot more detail with that here and of course you can find that Linked In the description below okay so with that said let's just jump straight into doing it with our little project here so the first thing we're going to do is I'm going to right click create and I'm going to create a folder here and I'm just going to call this um save load and this is where our save load scripts are going to live so we'll open up that folder there and then we'll right click uh create C script and we will call this save load cuz this is going to be a static class that we use to save and load just as a side note I've upgraded to ryer I've not been using visual studio so that's why the ID looks different than the rest of the videos but but the code obviously is all exactly the same uh but yeah just so you know I'm using ryer now instead of visual studio so we've got our um save load script here and as I said this is going to be a static class so we can call it from anywhere so we can get rid of the started update get rid of mono behavior and we'll just type in static there so this is a public static class called save load so the first thing I'm going to do is I'm going to add to public static Unity action um events and we're going to call this uh on save game and we'll also do a public static Unity action which is going to take in something that we're going to call save data and we'll have to make that class in a second um and I'm just going to do onload game for that and then we're going to want two public strings here as well so public static uh string and actually these could be private private static string called directory I'm going to set this equal to save data and then we're going to have a private static string called file name and I'm going to set this equal to save game. saav now I'm going to create a public um static bull method so public static Bull and this is just going to be our Save which is going to take in some save data so this is going to be the data that we want to save to file and we're going to have a public static um load function and this is going to return our save data so at this point I think we need to make this save data so go back into our scripts and into our save load folder and I'm just going to um I'll do this within Unity actually so if we go over here I'm going to right click create C script and we'll call this save data so we'll let that compile and open up that in our IDE so we've got our save data here so you see that these have all stopped being uh red now so for our save function um I'm going to call the onsave game uh Unity action just so we know when the game is trying to save and we could do string dur equals uh application. persistent data path uh plus our directory and here we can say if directory do exist so if this directory doesn't exist and this is using the system.io namespace so you need to make sure you include that so if directory doesn't exist then obviously we need to make this um directory which we can do here by saying directory dot create directory du so just very quickly we've got our string here which is called directory this is save data we're making a dur uh another string called dur which is the application persistent data path which if you've watched the other video this is our local low folder on our C drive and plus the directory so and we're going to see if this directory exists so have we saved the game before CU if we have this will exist and if not let's just create this directory here so then we're going to make a new string and we can just call this Json this is equal to our Json utility. tojson uh data and true so this data here is the data that we're passing in and we're going to save we're going to convert that data to a string which will then save to file and this true here is just for prettyprint which I believe puts stuff it organizes the file a bit easier so you can read it a bit better in a text editor instead of putting it all on one line and then we can do file do write all text and set this equal to Du plus our file name and the text that we're writing out is our Json string again if you don't understand any of this uh and this is the last time I'll say this but just watch the other video I did that I showed at the start of the video and you'll fully understand what I'm doing here so here I'm going to debug.log saving game and then we can just return true now the reason this is a bll is because we may want to return false if some of the parameters don't get met so for example if we're already saving um you could check to see whether the file streams open or if this files being accessed but for our basic case we're just going to always return true if we save for your game you may want to do something differently and then therefore it will return false so there may be a path that you take that can return false so the framework's there for you to use if you need to so for our public static save data load what we want to do here is we want to get our string and this is going to be a full path and this is going to be the application do the persistent data path plus our directory and then this time it's plus our file name so we're going to try and load this save game. saav file from our directory and we need to make a new piece of save data just called data and we'll set this equal to a new save data which is going to be a new instance of our save data class and we need to get rid of mono Behavior because it's not um it's not actually going to live anywhere kind of on an object we create a new one and then we need to check now whether our um file name exists like whether the save game actually exists so we can just say if file. exists and we're going to pass in the full path if the file does exist then we're going to get the file and turn it back into a Json string so we can do file. read all text so we used write all text here we're going to do read all text here and we're going to read all the text from the full path and then we can use the Json utility to turn that back into our save data so we can do Json utility. fromjson and we're going to turn that into a type of save data and the string that we're going to turn back into some save data is our Json so there we go and here we can say the onload game Dot and then we can invoke this passing in the data that we've just loaded if the file doesn't exist then we're just going to do else and we can do um debug.log save file does not exist and then regardless of whether we've um because we've already created some data we can just return that data at the end if it's got to this point it'll just be the new save data that we've made so for example if we're starting a new game and the save game hadn't existed we're just going to return some data to get started with but if it did exist then we're going to return our actual instance of the save data so now let's actually start to um build our save data like what what we're going to actually care about saving with our inventory system and before we can do that we actually need to um serialize a dictionary so the dictionary is going to be responsible for saving our chest inventory but you can't save but you can't serialize dictionaries um kind of from the get-go we're going to need to make our own version of a dictionary that's serializable so let's just go back into unity and that needs to recompile so in our save load folder I'm going to right click create C script and this one is just going to be called C realizable dictionary so in our serializable dictionary um class I'm actually just going to copy this in so this is the code for that I've got a link in the description um but basically that's this script here uh you don't need to know really the ins and outs of how it all works um but back in 2013 there was this question posted about saving out uh dictionaries and keys and um even though this was the accepted answer uh this script here works really well it says here that you need to um derive a non-generic class from that one I've not needed to do that here maybe it's because we're using Json but this just works as a serializable dictionary so head to the link in the description you can copy that script into our serializable dictionary. CS file make sure you've spelled the name of the file write compared to the name of it here otherwise it won't work so we can go back over to our save data um CS file and we're going to do a public and this is going to be a serializable dictionary which is the class we've just made and it's going to be of type uh string and a type of chest save data which isn't something we've made yet we'll make that in a second and I'm just going to call this our chest dictionary and I'm going to make a Constructor here and do a public um save data Constructor and we can say our chest dictionary is equal to a new serializable dictionary of type string and chest save data so now we're going to make our chest save um data this is going to be a struct and we're actually going to put this into our chest inventory. CS file so here we can come over to our chest uh inventory script and outside of this class I'm going to uh flag this is system. serializable so we can save um it out we're going to do a public struct chest save data and this is going to keep track of our inventory system so public inventory system in system a public Vector three of our position and a public Quan of our rotation and then we're going to make a Constructor for this so we'll do a public chest save data this is going to take in an inventory system which I'll just uh underscore INF system we'll do a vector three underscore position and a quitan which is rotation and then we can set our INF system equal to the underscore INF system position to our underscore position and rotation equal to underscore rotation so this is our chest save data um put together so now what we need is um so our framework is getting there uh quite nicely now so just to have a quick run through so we've got this action here onload game that's going to be called uh when we load the game and so it's going to get our chest inventory from file and we can hook into that onload function and check the data and find the chests inventory within our save data so let's just go up to the top here so I'm underneath the I interactable I'm just going to do a public sorry a protected override uh void awake and we may need to make um protected virtual void protected override void awake we can call base. awake and here we can hook into the save load do um we can hook into our save load do uh onload game and we can make a new function called load inventory and we'll create that function here so this is oh sorry I need to get rid of the brackets so this is going to take in some save data and this is going to um check the save data for this specific chest inventory and if it exists load it in so how will our chests the in the world so how will this chest here differentiate itself from this chest here they're going to need need some sort of unique identifier that can say like hey I'm chest number one does the save data that I've just got from the load game have a chest number one and if it does like can I get my inventory back please and it'll load it into this this one could be chest number two so we're going to need another script called um unique ID if I click our chest here in our test project you see I've got all of these chests here um so I've got my small chest here you can see that I've got this script unique ID and I've got a unique ID this is our ID here this is persistent between saves and states and scene loads so we'll right click create C script and we're going to make a unique ID and load this up in our IDE Okay so we've got our unique ID script here and this is is going to be a mono Behavior because it's going to live on our object now we're going to need a couple of um attributes above so we're going to do a system do serializable as well as execute in edit mode so we're going to have a serialize field and this is going to be a private string and we're going to call this uh ID and this is going to be equal to a new guid and we can do do two string now we need this to be readon and we need to make our own uh read only attribute so I'm going to go back over to Unity and I'm going to write click create C script and we're going to call this uh read only attribute and then we can open this up and I'm just going to paste this one in it's a very simple on line class just public class readon attribute and it inherits from property attribute so now if we go back over to our unique ID we can add this uh readon tag here and let's just add this to our chest so I'm going to add our unique ID um field to this chest here and you can see that we've got our ID here this is our unique ID so we've got this property attribute which we've called readon it's just this simple script and this has to uh interact with a editor script as well so back in our project you need to make a folder called editor and it has to be called editor so right click create folder editor spelled like that like editor and then here we're going to create a another script called our read only draw and this is the script for that so we've got our public override void on guy which takes in erect position serialized property property and our goey content which is label and we're just setting the um edit for the property to false so if we go back over to our chest and we add our unique ID script onto our chest you can see that this ID has been generated but we can't um we can't click in there or change anything about it and that's perfect we don't want to be able to change that code because it needs to persist kind of throughout our game so I'm just going to save our scene there so that's our um unique ID generated uh but we're also going to want a serialized field it's going to be a private static serializable dictionary and this is going to take in a string as well as a game object and I'm I'm going to call this our ID database and we can set this equal to a new um serializable dictionary of those types and I'm going to do a public string ID and this is going to return our private ID string here so we can get this ID from other places in the uh project and in the on validate function I'm just going to want to check whether our ID database already contains a key if it does already contain our ID let's generate a new one and this is just going to make sure that we don't have any keys that are the same this is going to be a new method called generate that we're going to create and if it does exist then we can do else ID database and then we can add our ID as well as ourselves so this do game object so now the actual chest in the world is linked to its ID so we'll be able to find this we'll be a to use this information in lots of other places I also want to make a UND destroy function so private void on Destroy and so if we delete the chest from the world and it contains the database contains this key then obviously we want to remove our ID from the ID database CU it's not a thing anymore so remove uncore ID all generate is going to do is it's just going to do this again again so we can just copy that bit of code there and once it's generated we're just going to add it to the database so this is just covering our backs to make sure no IDs are the same and that the ID database is um filled with IDs and the relevant game objects so that's our unique ID um script and our readon attribute and the read only draw so back to our chest inventory script so we've hooked into this uh unload game so now we can actually load the inventory so what I'm going to say here is if data so the save data um if the chest dictionary contains our ID so get component unique ID and from that component we're going to get the ID then it's going to pass back out the chest save data and we can just call this the chest data so remember our save data has has this chest dictionary which has got a string this is going to be our chest's unique ID that we've just generated and some save data this save data is this data here so it's the inventory system the chest position and its rotation so from this chest data all we need to do then is just this. inventory uh primary inventory system is equal to the chest data. inventory system CU remember our inventory holder it's got a primary inventory system so that's the first inventory system that all inventory holders will have so Prime inventory system is equal to the inventory system that's stored in our chest save data we can say this do transform.position is equal to the chest data. position and this. transform. rotation is equal to the chest data. rotation the reason we're saving this is because in your game you may be you may want to be able to craft a chest like in Minecraft and place it down in the world and if you do that it's going to know where it was like what its position and rotation should be so we're just covering ourselves if we want to do that um there now we're not going to do that in this um tutorial series it's not going to focus on Crafting necessarily maybe that'll come down the line let me know in the descript let me know in the comments below if you do want a crafting system that builds on top of the inventory system but if we do get that far then that's already there for us we can just read from that we can spawn in the chest at that position rotation and assign its inventory system as well if we need to as a bit of a root if you want to go down that on your own um you could have like a chest manager that loads in the data spawns in a load of chests based on this chest dictionary so for every entry in here it will instantiate a new chest and it'll set it to that position and rotation and set its inventory system so in that way when you load the game first there won't be any chests in the world and they will be spawned in dynamically by like a chest manager based on the save dat data but again explore that on your own or let me know in the comments below if you want me to do a video on that okay so we're getting close to the end of PST actually see this all working um I'm going to make a start function on this so private void start and we're going to make a instance of some chest save data so uh chest save data we'll set this equal to new chest save data which will pass in our uh primary inventory system we will pass in our transform. position as well as our transform. rotation and then we're going to get in touch with our save game manager which is another script we need to make and we're going to hook into the data on the save game manager and we're going to go to the CH chest dictionary and we're going to add our unique ID as well as our save data now this is a reference so we've assigned ourselves to this dictionary as the chest gets updated this chest dictionary will will stay updated we don't need to do it every time we request to save the game now our chest save data is a reference type so we only need to assign this once and it's the same kind of you know it's pointing to the same place in memory so we've assigned it to the chest dictionary which is going to be on our save game manager so it will always update no matter what we put in the chest so let's have our save game manager uh let's create that so right click create C script save game manager now you may want this to just be part of your like normal game manager uh but basically we need like an active piece of save data that everything is passing in its references to so then when we we hit a button to save the game it can just save this one piece of save data it's like your save file essentially it can save that to disk and we could in the save game manager we could have a tick that saves it periodically so like an autosave function um but for now we're just going to have a public static save data because we only want one piece of data to be working with we don't want to have lots of different save files everywhere uh we just want our one bit of save data so that can be static which means we can access it like this we don't need a reference to the save game manager because we can just get this static variable now I'm going to do a private void awake and also this save game manager class could be static I want it to live on an object just so I can interact with it a bit more easily in the scene so I'm going to keep it as a mono behavior and it'll live kind of like a game manager just on an object check in our scene so the first thing I'm going to do is in our awake function I'm going to hook into the save load on load game unity action just like we did in the chest and I'm going to um make a function called load data and this will be called data and in our awake function I'm also going to set our data equal to a new bit of save data so all that we need to do is when we load the game we're just going to replace our data with the save data that we've just loaded so we can do um data is equal to underscore data and I'll make sure I put the underscore there so this static instance of data is going to be um updated to this bit of data here and we're can make this a public static void load data this is where we're going to be able to save our data as well as well so we can make a public static void save data and here we're going to make a copy of our data and then I'm going to call our save load class um I'm going to do save and we'll pass in our save data and F write it I'm going to make a public void delete data and we can call Save load do uh delete save data and let's make that method over on our um save load file so we've got a public static void delete save data and all that's going to do is it's going to get the full path as it's up is up here and if that exists then we're going to delete that save file so that's just an easy way of deleting our save just for testing purposes or you know you might want to give the player the option to surface that option to the player okay so let's actually implement this so we can test to make sure it's all working okay so let's actually Implement some buttons so we can actually like save and load our inventory system and the way I'm going to do that is I'm going to get our canvas here I'm just going to right click create an empty and call this a save load buttons and I'm just going to add our save game manager to this object you may want it somewhere different in your scene but just to make it easier I'm going to put it here and I'm just going to put in um let's use text mesh Pro but and we'll do save we'll duplicate that and call this one load and duplicate that and call it delete so let's go to our UI and actually like sort these buttons out so we're going to get our going to parent them all to the top left of the screen so we've got our save button which can go in the top left we'll bring our load button down and then below that we'll bring our delete button and I'm just going to make these bigger just so we can see them a bit better I'll do the same with the the text I'll just check Auto size just to bring them up and then we can name this button save load delete so our save button uh we can do onclick and I'm going to drag in our save game manager and this is going to be uh save data got our load button here oh again onclick save game manager uh we need to be able to load the game why can't we load the data oh yeah we need a function to actually um try to load the data so let's do public static void um try load data and this is going to call load on our save load system which if is successful it'll fire off this event and then this will actually do this uh method here so let's go back to the game so under our save game manager we can now choose uh try load data and then for delete we can do onclick save button save game manager delete data so for ease of trying to navigate to our save game like file on disk I'm going to go over to our save load function and in our save game when I hit save game I'm going to copy the directory to the clipboard so I'm going to do uh GUI utility do system copy buffer and I'm going to set this equal to our directory so that means that when I hit save it's just going to copy the persistent directory path to our clipboard so we can quickly get that in uh Explorer so let's save our scene hit play so uh oh got a null null reference so what's that Ah that's because this chest um the big chest doesn't have a um unique ID component on it so what we'd actually want to do for our chest inventory is put in a requir component of type unique ID uh type of unique ID so when we call get component that's not going to um throw that error we may also want to Cache our um unique ID instead of calling get component but I'll just leave it like that for now let's just make sure it's working first so let's hit play so let's go over some objects come over here press e pick up our Tomatoes put them in that chest we'll go get some potatoes pick them up put them in this chest let's um close out that hit save so we can stop playing let's come over to Explorer I'm just going to paste in the directory so tutorial we've got our save game. saav we can open this up in um any text edor I'm just going to use notepad and we can see here that our chest dictionary it had two chests it had BF 041a and OC ec6 8A or 8 e and you can see that that corresponds with our chest here so BFA 041a OC ec6 8 e so that's our save game working it's got our chest dictionary it's saved our keys um it's got the value so it's got uh item data instance ID 243 two so that's referring to our tomatoes and a stack size of four so that's that's all working if we go back over to our chest and press e you'll see that there's nothing in them so we'll close that we'll hit load go back to our chest and there's our four tomatoes now obviously there's a bit of a problem here that um we loaded the game after we' already picked up these uh Tomatoes off the ground so to solve that issue uh what we can do is in our save data we can make a list of items and this is all of the items that we've picked up in the game so we can do a public list of string type and we'll call this uh collected items and we can do here uh collected items is equal to a new list of type string uh we're going to need the unique ID um on our items as well so we can do require component get uh type of unique ID uh sorry not that's not on our save data that needs to go on our um our item pickup script so require component type of sphere collider require component type of unique ID and just like the chest inventory we're going to want to make a um some item pickup uh save data so system. serializable and this is going to be a public struct of type item pick up save data so again this is there for the if we want to implement um you know we've dropped an item on the ground uh and we want to save that position and rotation uh we can do that by spawning in New items we won't use that again in this script but I'm doing it for you so it's there if you do want to use it um so let's do public inventory uh item data and this is going to be our item data we'll do public Vector 3 and this is going to be our position um public querian our rotation and we'll do a public item pick up save data Constructor which is going to take in some inventory item data called Data Vector 3 position Quan rotation and we'll do item data is equal to to data position uh position is equal to position rotation equal to rotation Okay so we've got our save data there um and again just like on the chest on the save data for the chest we need to hook into our save load onload game so in our on awake function just above the colliders I'm going to do um save load dot on load game and we're going do load game so here I'm going to do a private string ID and we will cache our ID here because it is good practice and I'm also going to do a serialized field private item pickup save data just called item save data so we can say our ID is equal to get component unique ID do ID and we can do item save dat is equal to some new save data which is going to take in our inventory item data so item data our position just like the chest and our rotation just like the chest and just like we had start function here for our chest inventory that adds itself to the save game manager data we can do the same thing here so we'll do void start and we can do save data uh sorry save game manager. data Dot and then we're going to make a list of our active items which takes in our ID and our item save data go back to the save game manager so we'll go back to our save data and I'm going to make a public serializable dictionary of type string and item pickup save data called active items and we'll do active items is equal to this so when we make some save data that uh dictionary is valid and active in our load game function we just want to see if this item has already been picked up and we'll know that if it's contained within our collected items uh list when we pick up an object it's going to add itself to this collected items list and then when we save our game we'll keep track of the items that we've collected so here we just want to say if data from our load game do collected items do [Music] contains our ID then we just want to destroy this. game object and in our on Destroy method so if we do get destroyed by getting picked up we just want to remove ourselves from our active uh list so save game manager. data. active items do contains key ID save game manager. data do active items do remove r i ad so when we're picked up we're going to be destroyed and we're going to take ourselves out of the active list and then we want to unsubscribe from the um save load. onload game action we don't need to care about that anymore so we can just unsubscribe from that there and in our ont trigger enter before we are destroyed we can do save game manager. dat. collected items do add uh ID so we can when we get picked up this is where we will add ourselves to the save game manager so let's just see that in action so let's go back hit play creating missing unique ID let's just check that that so that's on there now so all of our items have a unique ID so let's hit play so we're going to go over we're going to pick up these items and place them these four tomatoes in the chest and we're going to walk away hit save come out of that go back in now here we're going to manually load in your game when you start the game when like when a player starts the game you probably want to load then so like when the application first starts you'd call the load function or you'd be in a main menu and you'd choose a load game um you wouldn't just spawn into the world and then load um but here we're going to have to manually press the load button and you can see that those items have been deleted because they've got picked up and we'd previously put them in the chest so that they're here in the chest and we can take them back out put them back in so that's the basics of the save loading uh done players hot bar doesn't currently save so if I hit save come back out hit play hit load it's not working on our players inventory bar that'll come in the next video if you want to see that make sure you hit the Subscribe button hit the like button if you liked this video as always the project files for this video plus Early Access to these videos are on my patreon which is patreon.com dpos if you'd like anything kind of explaining a bit more detail I I felt like I went quite quick CU it was a lot to cover and I wanted to get this video out and two people cuz it's been a while since the last video if you need anything explaining uh let me know in the comments or head over to the Discord server which is linked in the description I'll be more than happy to help you and kind of debug your code with you thanks for watching and I'll see you in the next one [Music] bye hello and welcome to part nine of the inventory tutorial Series in this video we're going to be working on saving the player inventory so you can see here if I hit load the player hot bar now fills back up with the inventory the backpack has the inventory in it as well and if we go over to the chests we can see that the chests have their inventory stored as well which is what we did in the last video so let's just get straight into doing this okay so where we left it off last time is that we could walk around and pick up some tomatoes and potatoes and then we could go over to our chest and we could access the inventory and we could put our tomatoes in it well they were potatoes but you know what I mean and our Tomatoes we can hit save come out go back in and play and then if we load the items that we' picked up get deleted and then the potatoes and tomatoes are still there but what we had left in our player inventory uh wasn't getting saved and that's what we're going to work on in this video okay so let's open up our chest inventory you can see in our chest inventory we have this public struct the serializable struct that we were using to save out in our save data and and we'd save the inventory system as well as a position and a rotation and you can see that this derives from inventory holder but so does our player inventory this is uh this inherits from inventory holder as well and we need to save the same thing we need to save this inventory system system so what I'm actually going to do is I'm going to take this uh script instead of calling it a chest save data I'm going to just rename it to inventory save data and I'm going to put it onto the inventory holder parent script so I'm just going to rename our struct here inventory save data and I'm going to cut this from our chest inventory and I'm going to place it onto our inventory holder script so underneath the public class here let's just pop that there so the good thing about this now the inventory save data is for example you may have other types of inventory holder um you may have a mailbox that just takes in mail you may have you may have like a cauldron which is technically an inventory holder but it could only hold like potions or something and if each of these things are placeable and craftable in the world then we can just use this public struct inventory save data and we can even use this for our uh players inventory as well but with the players inventory we don't need to care about the position and rotation necessarily because that will be because that piece of save data would be included in a different saving and loading for like the player stat you'll have a separate player save system which will have its which will have the player's position and rotation like their location in the world uh saved into that and realistically you'd have their inventory system probably saved into that struct so you'd have a public struct player save data and it to have their inventory system position rotation any stats that they've got on them other stuff about like who they've spoken to where they've been Etc um but just for the sake of this tutorial I'm just going to keep it all simple and we're going to have this one struct which is what we save inventories with so what I'm going to do is I'm going to create another Constructor that doesn't care about a positional rotation so we can go uh and start a public inventory save data so this is a new Constructor and it's going to take in the inventory system which we will call INF system and here we can say that INF system is equal to underscore in system position can just be set to Vector 3.0 and rotation can equal Quan do identity so then over on our player inventory um file we need to do what we did on the chest inventory so we need to subscribe to the load onload game function in our awake method and we should probably unsubscribe from it uh in on Destroy as well then on over on our inventory holder uh I'm going to implement a method called load inventory which can take in a save data but I'm actually going to make this abstract so private abstract void load inventory and we've got an error here meaning that the class isn't flagged as uh abstract so we need to do a uh public abstract class which we've called inventory holder and we can make this protected so it's a protected abstract void load inventory taking in some save data on our chest inventory we just need to do protected override void and the reason that we're doing this instead of having it just be a virtual void is that on our chest we care about the position and rotation on our inventory holder uh we don't so what I can do now is I can copy this function from our chest inventory and we can go over to our player inventory holder so here we're going to paste in our our load inventory what we're going to do here is instead of looking into a chest dictionary we're going to say data dot our player inventory dot inv system is not equal to null then we're just going to set our primary inventory system to the data. player inventory doin system so this player inventory is going to sit on our save data script so if we go over to Sav dat. CS you can see this is where we've got our string and our serializable dictionary for our chest dictionary what we can actually do here is do a public inventory save data and we'll call this player inventory and then in our Constructor we'll have to say player inventory is equal to a new inventory save data okay so let's go back over to our player inventory and actually it's not called inv system is it it's a inv system with a lowercase i that's my mistake so we've called it inv system really because they're public they should be Capital eyes we're sticking to proper uh naming conventions okay so another thing that we're going to do is we are going to change how the player inventory holder actually works so you can see here we've got a um secondary inventory system and this is essentially our hot bar so it's the 10 slots that sit on the bottom of the screen but that's just a bit clunky because we'd have to keep track of the players uh hot bar and their backpack separately so that's just creating too lots of data when there's not really a need to do that so what we're actually going to do is we're going to get rid of the secondary inventory system um just all together so we can get rid of all of this I know it's daunting deleting uh lots of code so with that done we can get rid of our awake function and instead of this Unity action here we're going to say uh get rid of the uh parameter and we're just going to call on layer invent ventory changed so when we load our save game we're going to call this action so all we need to do there is on play inventory changed we can call this after we load in our inventory and instead of this here so if keyboard. curent B key was press this Frame we're going to just Swap this over to the on Dynamic inventory display requested action which sits on the inventory holder script and this is going to take in a um inventory system which is just going to be our primary inventory system and we're going to pass in an offset so the offset for the player inventory is going to be 10 so basically when we call the on Dynamic inventory display requested panel we're not going to show the first 10 items if the in the inventory because they're going to be the ones that are on our hot bar and you can see that we're getting an error here which means we uh need to change some things so back on our inventory holder script where we've got this on Dynamic inventory display requested we can also take in an INT which is the offset so INF system to display amount to offset display by and because we don't have this uh secondary inventory system anymore we can get rid of this else if and we can just have this add to inventory and over on our inventory system when we're calling the on Dynamic inventry display requested we don't want an offset so we can just uh pass in zero so now let's jump over to our um UI script you can see that the UI controller is having a bit of a an issue because this backpack uh action isn't a thing anymore and display inventory uh we can get rid of this method and inventory to display needs to take in an INT offset and we need to pass this offset through to the chest panel refresh dynamic make inventory uh I'm actually going to just rename this to inventory panel now because it can be a panel for anything it doesn't have to be just a panel for the chests so inventory panel and I'm going to add formly serialized as so it doesn't lose its reference so you can see here it says formly serialized as once we've recompiled the editor we'll be able to remove that um if you want to know more about that click the link up in the top right corner I did a video on what this does so passing through through our offset here we just need to go to this uh refresh Dynamic inventory function uh method and actually implement the offset mechanic so here we're taking in um an INT offset and again we need to pass this along to its final destination which is uh this assigned slot method here so in to display offset uh and that needs to take an in our inventory because this is an override we need to do the same on the assigned slot abstract method here so we need to pass that inventory slot in we need to pass that uh it offset into that and now instead of starting at zero we can start at the offset so um I equals offset and then whilst the inventory display is less than the inventory size we'll do all of the other stuff so basically we're missing when we start to assign the slots if we pass in an inventory size of 50 because our player inventory is a size of 50 10 of which are for the hot bar and we'll passing in a offset of 10 it's going to skip the first 10 Slots of the inventory which I should be able to show you here so that should all be working it doesn't look like it is there's something wrong with our static inventory and that's because we need to pass in the offset here even though we don't use it okay so that should all be happy now so let's go back over to Unity that was a lot of changes without testing any of them so hopefully that will all work let's recompile no errors in the log always a good sign so I'm going to walk over to this uh tomato we've got our two potatoes and they're coming into our hot bar as we go over you'll see that nothing happens and that's because we probably forgot to do something ah so our player inventory size was set to 10 because we only had the hot bar and we got rid of the secondary inventory system which is our backpack so let's put this up to 50 okay so that didn't work we got an error um that's because silly old me forgot to do something on our static inventory display class you can see that we were looking for the amount of slots and we' put in 10 inventory slot uis uh so this is an array of the actual like UI inventory slots and we were checking its length and making sure that it was the same as our actual inventory size and log in an error if it wasn't just as a fail safe um but we need to get rid of that now and instead of doing in I equals z what we need to actually do is check I say in equals Zer and whilst I is less than slots do length so there is a potential issue here and if you decide to have um say five inventory slots you need to make sure you change that in the code on the player inventory holder where we're passing in this offset what you may want to do is to have a public is to have a serialized field private in offset and we'll default that to 10 and let instead of hard coding that there we'll just put in offset and we can change this in the inspector if you changed the hot bar so if we look at the player hot bar you can see that we have 10 inventory slots in the script so slots 10 that's these here if you decide to only have five you just need to make sure that you change that on your player um the player offset here and actually if you wanted what you could probably do is if we go over to our player uh inventory holder script I'm actually going to put this offset onto the inventory holder main class so we'll do offset equals 10 let's make this protected so we can access it from our player inventory holder script and and I'm going to do a public int offset a capital O and this can be a property that Returns the offset field so now over on our static inventory display what we can say is instead of slots. length we can actually check the inventory holder dot offset okay so with those changes done we just want to go back over to our player inventory holder CS script and the last thing we need to do is in a St start function so private void start we just want to add to the save game manager we want to get the data the player inventory and we want to set a new inventory save data just passing in our inventory system which is the primary inventory system okay so back in the project what you want to do is because we've changed the way the save file is actually set up and we've renamed some stuff we just want to hit delete you need to delete delete your old save file which is important to get all of this stuff right now in the prototype in Phase because obviously you'd hate for players to have to delete their saves some games do have that in Early Access you need to have save wipes and they get rid of your saves so that's just something to keep in mind um that once you start changing the structure of what's actually saved out you can't then load that back in or you can but you'd have to you know code for for that and convert stuff um but let's just start walking over these Tomatoes here and these potatoes here so you can see that our hot bar got full and as we go over the items on the ground they start to fill up in the backpack we can go over to the chest and let's put five tomatoes in here and some potatoes let's split that stack and put two in there one in there and then let's hit save let's come out go back in let's load our game so we'll hit load so all of the items were collected so they're now not on there over on this chest here we've got the tomatoes and the potatoes that we put away in our backpack we've got them but you can see our hot Bar is missing if we go over to our player you can see on our actual inventory they are there we we have those items but they've not shown back up and that's because the hot bar unlike the dynamic inventory it wasn't set to refresh when something changed so when we load our save game we just need to ask our hot bar to refresh because obviously the data that's contained within our player inventory has changed and that's quite simple if we go back to the static inventory display class and in uh on enable we can subscribe to player inventory holder do uh on player inventory changed and let's make a method called refresh static display and let's just copy and paste that and we'll change this to disable and we'll change that to on disable and we'll unsubscribe from that method so in our refresh static display method all we're going to do is take this out of the start function and we can get rid of that we don't need to call base. start so we're going to take that out of our start function we'll place it into the refresh static display script and then we can call refresh static display from our start function so back in unity if we hit play we should just be able to load the game and everything should now be working so let's load you see that all the items were picked up our player inventory is all intact this is everything that we had we have our chests which have the tomatoes and the potatoes in them just as you would expect so so I know uh code refactoring can sometimes make for a little bit of a hectic video I hope you all followed along and it was okay in the next video we're going to be doing a bit more refactoring unfortunately and we're going to be looking at the way references to items within an inventory are stored so what I mean by that is this is our save data and you can see that the reference to the actual item data is we we store how many of the item we have but the actual reference to the data is this instance ID now you can see that if we build the game so here we are in the built version of the game and if I hit load you see that the items get deleted and that's because they have a unique ID it's not an instance ID uh that's an ID that we've created and is unique um but you can see none of our inventories have any items in them and that's because in a built version of the game those instance IDs change between the built version and the editor version and in patches down the line they may change again if you upgrade your engine or you know sometimes just your project will re serialize and those in IDs can change and that means that the loading whether that's in editor or in an inbuilt version of the game would actually stop working and you'd break player saves it's a bit of an oversight on my end um but after this comment from 322 SS on the previous chest inventory save in uh they've kind of flagged this as an issue uh I did a bit of researching and I've found a way to fix that by creating an item database using scriptable objects so in the next video we'll take a look at how to implement that fix it's very simple but again it's just a little bit of refactoring so that will be what happens in the next video but in the meantime I hope you're enjoying the inventory tutorial series it's been very good fun working on this if you'd like the project files for this video or any of the other videos in the series you can head over to the patreon which is linked in the description below that's patreon.com dpos if you've struggled with anything in this video or any of the video so far you can join the Discord server which again is linked in the description below i' be more than happy to help you there but for now thanks for watching and I'll see you in the next one [Music] bye hello and welcome to episode 9.5 of the inventry tutorial series I'm actually recording this from way in the future I've already filmed quite a lot of extra stuff uh I think episode 11's currently out but I'm just going to slot this in between cuz I've had a question from Watcher on the Discord which if you want to join the Discord there's a link in the description below and they were asking how when you go over to a chest and you pressed e it' bring up the chest but then if you press B it' bring up the same panel so you couldn't for your player inventory so you couldn't put things from your actual inventory into the chest but by the end of this video we'll have fixed that so we can have our inventory panel up here so this is our player inventory so you can see we can walk away from the chest this is our backpack with our hot bar down here and if we go over here and press e we can then bring up our backpack put some potions in there split them put them back in our inventry split them put them in our backpack walk away come back over press e and we've got our chest and our backpack and it's all the separate so let's just jump straight into this quick little fix video okay so there's a bit of a glaring issue with uh the inventory project which I haven't got around to fixing yet um but it should be quite a simple fix so you see here we've got our backpack if we press B you uses the dynamic inventory um panel so we can put stuff in our backpack instead of on our hot bar but if we go over to um this chest and we open up the chest and then we open up our backpack with the B button you see it uses the same panel so we can't put stuff from our backpack into a chest we'd have to put it on our hot bar then use the chest and then put it into the chest which obviously is rubbish we don't we don't want it to do that so let's just quickly fix that and it's quite a simple fix what we're going to do is we're going to drag our canvas um we're going to expand our canvas go to our inventory UI controller and we've got our Dynamic inventory pack here I'm just going to shut the shop UI controller so you can see you've got the dynamic inventory um display we've also got this player backpack I don't know when I made this so let's just assume you don't have that and let's start fresh so I'm just going to open up this prefab and delete the player backpack and we'll go back to our canvas here so we've got our Dynamic inventory panel I'm going to contrl D and duplicate this and then just move this over to this side and let's rename this to player inventory um panel so we've got our Dynamic inventory display here um I'm going to go over to our um inventory UI controller so it seems I decided to set up this player backpack panel and at some point I know maybe I didn't cover it but that's no biggie um if I do cover it in a later video just skip past that bit okay so you can see I've already tried to do this here so um we've got a public Dynamic inventory display player backpack panel and that's on our inventory UI controller so let's just drag our player inventory panel over to the player backpack panel and we can also see that in update we've got a keyboard current key. Escape key was pressed this Frame and if the player backpack panel is open we'll just close it and then here we've got our inventory holder um on Dynamic inventory display requested this is what's opening up the chest panel and it's also opening up the um player panel as well so instead of doing that let's um I'm just going to duplicate this method so we'll just contrl c contrl v and let's name this to display player inventory and then on our player inventory holder script so we've got player inventory holder we've got here if keyboard docent b key was pressed flame frame on Dynamic inventory display requested and then we're just going to invoke our primary inventory system and pass in the offset what I'm going to do um see the the version I'm working with here is from episode 11 of The Backpack series if you're jumping ahead to this one from episode 9 I'm not sure I can't remember exactly when I implemented this offset it may have been in a later video but I'm responding to a question on Discord asking how we can do this um I'm going to slot this kind of in between episode 9 and 11 so this will be like a episode 9.5 as it were so yeah we should so you should be able to follow along but there may just be some code that's not you may see some code that's not kind of there yet but it will be by episode 11 um so we've got if keyboard. current b key was pressed this Frame and we've got this uh event here what I'm actually going to do is I'm going to create a new um public static Unity action and just like like on our inventory holder this on Dynamic inventory display requested just to make it easy I'm just going to copy that I'm going to go back to our play inventory holder and let's just paste that in and then we'll say on player inventory display requested so now when the b key is pressed instead of doing on Dynamic inventory display requested we can say on player inventory display requested and if it is let's invoke it and pass in our inventory system along with the offset again depending on when you're watching this video you may have your backpack inventory system as a separate inventory system I do rework it to just have one kind of system but hopefully you can follow along we go back to our inventory controller we just need to listen here so um we can do player inventory holder do on player inventory display requested and then we can plus equals the display player inventory and we'll copy this and place it in our undisabled function so we've got our display player inventory system we're going to call this so now we just need to set our player backpack panel to true and then we want to refresh the dynamic inventory of the player backpack panel not the inventory panel so now if we press play and we can press B that'll bring up our bag we press escape and close that and let's just pick up some stuff we can press B and we can place this in our bag and you can notice an issue here that the icons are going behind the bag I'll solve that in just a second and but now when we go over to a chest and press e and we can press B and we can bring up our bag and place them into the chest and press escape and it will close both panels so now you've got your bag and the chest inventory are all separate panels and then to fix the um inventory UI controller with the player inventory being behind it so to do that let's um come to our canvas and let's just apply all of our changes that we've just done and then let's try and drag the mouse object below player inventory it has to open up the prefab and then we just need to make sure this is at the bottom of the UI inventory controller window cuz anything that's at the bottom renders on top of the stuff above it which I've never really liked I wish stuff at the top would render above it's a bit more kind of like Photoshop them with different layers you can see that if we go over our backpack if we go over pick up some items pick up an item and now it's rendering on top of our backpack our swords in and then we can come over here to these chests and then we can pop some stuff into the chests and also as a sneak peek I've just finished recording all of the shop tutorial stuff so that is coming up in the future just as a little little sneak peek I'm actually working from like episode 15 of the inventry tutorial series which includes the shops that's just a a little sneak peek um but yeah I hope that solves your issue if you've been having that issue um I can't remember if I addressed this in a future video if I do just skip past that bit thanks for watching [Music] bye hello and welcome to episode 10 of the inventory tutorial Series in this video we're going to rework how the items are stored in memory and how we save them out so the end of the video uh not much will have changed in the editor uh I'll be able to you know go over here and put stuff into the chest just as we always have been able to and we can hit save but now as kind of pointed out at the end of the last video if I built and run this version of the game I wouldn't be able to load that save in the built version of the game originally but by the end of this video we will be able to do that so you can see here we're in the built version of the game and we can now hit load and the save files are in sync between between the actual built version of the game and the editor version as well we'll be able to go over here you know make some changes go into this chest put a this thing here put some tomatoes in the players's backpack we can hit save we can go back into the editor hit play and our save files will be in sync so you can see there's our tomatoes and each of the chests has what we put in it we'll be creating a database that controls all of our items and assigns the items and ID as well so let's just get started with the video okay so let's get started let's go over to our item scripts folder right click create C script and we'll call this database and let's open up that in our IDE so this is going to derive from scriptable object so we'll get rid of start and update and we'll Place monab Behavior with scriptable object now we're going to need to be able to right click and create a database in the project so let's do create asset menu and we can say menu name is equal to inventory system SL uh item database let's just zoom in a bit so we've got our database object here um so the first thing I'm going to do is serialize field a private list of inventory item d data so these are the other scriptable objects that we have and I'm just going to call this the item database also since starting this project many many months ago uh I've upgraded kind of my name in conventions to fit more in with how C should be coded so you'll notice that here I've got privates without an underscore and you see Ryder is complaining saying it should have an underscore so it doesn't really matter but that's why my nameing conventions have changed so I'm putting underscores on under private variables just so you're aware so this is going to be a list this is our database this is the list of all of the items in our game and this is kind of like the one sort of point of Truth so when we load in a game we can look for an ID instead of the instance ID which as I said last time can change between builds and the editor and patches and updates like it's not very safe this way we can assign an ID to a item say like one two three and then our save file can say that we've saved item three and item 3 will always be item three it won't change in between it won't change in between sessions and it will go between the and the editor and the build will share the same item database so we'll be able to load our save games that we've made in the editor in a built version of the game and we' be able to load the save file that's in a built version of game back up in the editor which would be great for debugging and stuff like that so with that said so with that little bit more of an explanation out of the way um we're going to make a function to actually set these IDs so I'm going to do a public void set item IDs and I'm going to above that give it at the context menu attribute with the set ID's name so we can call this in the inspector uh if we need to so the first thing I'm going to do when we set some item IDs is I'm going to create a new list of inventory item data this will just ensure that the database is never null when we start to try and do stuff with it and the first thing I want to do is I'm going to make a variable called found items and I'm going to search the resources folder by calling resources load all and I'm going to get it to load all of the inventory item data that we have in our project and this is going to be at the path of item data and then I'm going to use system. Link so let's come up here we'll do using system dot link and we're going to order all of our items by their ID so if say apples is an idea of so if tomatoes is an ID of one and potatoes are an ID of two it will put them into the order so it'll put Tomatoes first and then potatoes so we can do order by the way the order by function works is quite easy so we need a letter or a variable name CU this is almost like doing a for reach Loop so we're saying for each I or this can be anything this could be for each um for each item but convention is to just have one letter so ordered by I so for item for each item let's order it by the item. and then finally let's put this into a list called found items so again we're loading all of our item data scriptable objects that we've created that are going to be in a folder called item data and then we're going to saw all of those in ventory items we're going to order them by their ID and then we're going to put them into a list called found items and now we need to filter these found items into three separate categories we need to say um has ID in range that's going to be one of the categories we're going to uh has no uh has an ID not in range I'll explain these all in a second um and we want no ID as well so here we're seeing whether say we found 10 items but for some reason uh Tomatoes had an ID of five but then potatoes had an ID of 15 the one that has an ID of five would be in range because it's in the range of the amount of items that we found the ones that had an ID of 15 or anything above how many found items we had uh they would have a valid ID but it wouldn't be in range and then no ID are going to be all new items that we've never set an ID for before and we're going to default them and when we make a new inventory item data we're going to make it so it always defaults to minus one which is what we can then check for so let's focus on has ID and range first so I'm going to set this variable equal to found items so we're going to check this list and we're going to get all the ones where our Item ID is not equal to minus one and the items ID is less than the found items. count and then we're going to order that list by their ID so just the same as above and then we're going to put them all into a list and this seems quite complex in terms of you know memory usage it might not be the most efficient but this is only going to get called where we build the game this is never going to happen uh like in game where there's a player doing this so for our purposes as long as it's functional I'm more than happy with that going into a built version of the game so for the not in range we're going to do the exact same thing but we're going to change the um check on the account so we can say equals found items where their ID is not equal to minus one and the ID is greater than or equal to the found items. account and then we'll put that into an ordered list and then finally we're going to copy our found items where I'm going to say where the item ID is less than or equal to minus one and we'll put that into a list as well so now we're going to Loop over all of our lists and organize them into the item database in the correct order the ones that don't have an ID we're going to give an ID and because they're script objects this ID would then be persistent that data will stay we don't need to save it out to a list like to a Json list or anything like that so I'm going to make a temporary index um variable just called index and we'll set that to zero and I'm going to go into a four Loop I'm going to say 4 in I and while I is less than the found items. count so all of the items in our game i++ and I'm going to make a new um inventory item data called item to add because dependent on some different checks this is going to decide what item that is that we're checking and then we'll put this item into the list so here we're just checking the ID at I we're going to check the found items. range and we're going to see if the item that we're looking at has the same ID as the position that it's come through into the ordered list so we're going to say item to add is equal to has ID in range do find and I'm going to say uh where the data and I'm using D here instead of I because we've already got I here I'm going to say where the data is equal to the data's ID equaling I sorry that's not equal needs to be that so so when we've got to this index that we're on we're going to assign it we're going to assign it an item from this list this has ID and range list so we're going to get the ID that matches the current iteration of the loop that we're in if the item to add is not null at this point then then we are good we can add that item to the database CU that's it's the correct item in the correct position ition so item to add can go into the database if the item to add is null so we've not found an item that's within the range that we're looking for doesn't have a correct ID then we'll going to check does the index which is this variable here that we've made is the index less than the ID is less than the no ID do count so this is a separate index that we're keeping track of over here because we're only going to iterate this when we run this bit of code to make sure that we don't go out of range of this no ID list so if there's no ID what we're going to do is we're going to um get the item that is at the index that we're looking at and we're going to set its ID equal to I and again I is the current like Loop index so essentially we're going to get the first time around if we get to here we're going to go into this list of no IDs and we're going to get item zero and we're going to set it to the relevant ID of this Loop and then we can say item to add is equal to no ID do index we will increase the index so this is the sort of internal index to this no ID list so we're going to increase the index and then we can add the item to add to our item database so item item to add goes into the database and then once this has ran and we've gone completely through this Loop all we're going to do then is we're going to go through all of the items that have an ID but they aren't in range so we'll say for each item in has ID not in range we're just going to add them to the end of the list so item. database do add item so this will be a case of say you had 15 swords in your game and you decided that's too many uh I'm going to take out five but you're only going to take out kind of like the middle five and then the last sword which was originally the 15th sword and had an idea 15 players have that testers have that you don't want to remove that ID from the database because it might be referenced in a save file somewhere doing this ensures that those IDs don't have to change they can still be valid and if we add more items into the future it's going to fit it into kind of the next available slot in our list so that's the set ID method complete so now all we need is a method that returns some inventory item data and we can call this get item and we can just pass in an ID and all this is going to do is return the item database. find and it's going to find the item that has the ID that we've just passed in so find the item where the item. ID is equal to idid which is this ID here because once we run this set item IDs because it's a scriptable object the item database will just stay around until we call set item IDs again so we don't need to run this at runtime we can just run this the once when we build the game or while we're testing the game in the editor and then that's all we need that's that's all we need to do so let's save our database and let's just go back to our project so now you need to make a folder called resources so I'm going to create folder and let's call this uh resources and I'm actually going to put this into our item scripts because you can have multiple resources folders so remember we were looking in a folder called item data and I'm going to put all of our scriptable object so the potato and the Tomato I'm going to put this into our item data folder and in the root of our resources folder I'm going to create inventory system item database and I'll just call this database so whatever you name this is what you're going to refer to it as in some code later so um make sure you name it appropriately called item database database um I'm just going to leave it as database so you can see here that our list of items is empty we've got our item data here and their ID is currently set to zero let's just set these to minus one and let's actually open up our inventory item data and I'm going to set this equal 2 minus one so when we create a new inventory item it will be automatically set to uh one so let's do inventory uh inventory item and I'll call this uh Apple so you can see ID is set to minus one and we'll just type in apple here um so if we go back to our database um so I'm going to set the potato so these are all minus one so if we go to our uh database and we come up to the three dots here you can see that it's got set IDs and this is what we did with that context menu we hit that you can see that it found all of the items in the item data folder it found three items it found Apple first so this is id0 ID 1 is the potato ID 2 is the tomato and that matches element zero element one element two from the database list if for example this was set to uh this one was Zero we'll put this one back to minus one and I'll put this at 50 so it's going to find all of the items but it's going to be put them into their ID order so this is ID Z so it'll go into element zero in the list and then find this one has minus one and element one doesn't have a matching ID so it's a basically a free so it's basically an ID that is free to be assigned to another item so it'll set Apple to one and it'll leave ID as for the Tomato was 50 and it'll just put it at the end of the list so let's go back to our database and let's just set the database back to zero so if I click set IDs so you can see element zero is the potato which had an ID of zero it set the Apple to ID of one and tomato has been left an ID of 50 so if I create a another inventory item and I'll call this uh pair we'll do display name pair and I'll leave the ID for now at minus one so what we need to do now is we need to load our items back into the game based on their ID not their instance ID so let's go back over into our IDE and we're actually going to go over to the inventory slot. CS file and here we're going to implement the um I serialization call back receiver which is an interface that allows us to to get a call back when the game when the game is being serialized so we can get a call back so just before it serialized and then after it's serialized and we'll Implement um the missing members which are these two scripts here which are these two methods here is public void on before serialize public void on after uh deserialize and we don't care about on before ser realized we don't need to use that but so we have to keep it around though so I'm going to get rid of the throw exception the method that we're going to use is on after d serialize but first we need to go back up and we need to assign an inventory ID to our slot so serialized field private int and we'll call this uh Item ID and and we'll default this to1 so when we save out our inventory system and all of the inventory slots we're not actually going to be saving out the items contained within the slot anymore we're just going to be saving out this int which was the which will correspond to an item in the item database so this can be private but it has to be serialized with serialized field one so we can see in insector and two so it saves out into our Json save data so let's go back to on after deserialize so here I'm going to check uh whether the item ID is equal to minus one if it is the slots empty so we don't need to get the item data and instead what we can do is I'm going to make a temporary variable called uh database and I'm going to set this equal to resources. load I'm going to load the database from our resources folder and it's going to be called database because it's in the it's called database and it's in the root of our resources folder what you may want to do is get this what you may want to do is load this um database into memory on your game manager or on some sort of Singleton somewhere just so you can always access it you're not having to load it each time the game deserializes but for the purposes of this this is fine and then all we're going to do is say item data is equal to the database. get item and we'll pass in our Item ID so now let's go up to the assign item method here so this is when we pick up an item and we're assigning an item to the slot what we want to say is um so the data is equal to the data and our item ID is equal to the item data's ID which is the ID that was set for to it by the database in um clear slot we just want to set the item id back to -1 because the slot will be empty and when we create a a slot in the Constructor we just want to set the item ID to the ID there as well and we just want to put um Item ID into the update inventory slot as well so that should be that let's go back over to Unity and just check that that's all working so let's hit play let's pick up some tomatoes and potatoes go over to the pl player and you can see here that we've got the tomato and it's got an item id of 50 got the potato item id of zero and then the slots that are empty have an item id of minus one so I'm going to delete my old save file because again we've done some structural changes to the way stuff is saved and I'm actually going to hit save here and let's load up that save data so here you can see that item data instance ID is still being saved out we don't need it to in fact it's confusing that it is so let's just Mark that as nons serialized so in our inventory slot instead of serialized field we can do um non serialized but you can see that the rest of it we've got the item ID and the stack size so it's loading it in by Item ID and not by the item data's instance ID so this will never change this could change so let's just check that again let's delete our save let's pick up some stuff let's put it in a chest over here and we'll hit save let's check that save so here we've got our chest inventory and you can see that it's just saving out the item ID and the stack size it's not got any of the instance ID stuff now so we've saved that let's come back out of the game go back in let's hit load game so there's our potatoes everything deleted off the floor we've got our chest which is where we put the tomatoes originally just going to split that stack put it over here put them in there so I'm going to save the game and let's just check that it all works in the build version of the game as well so I'm going to come over to our database and make sure we set the IDS if you want to see how you can automate this and get the database to set when you hit build click the little icon in the top of the video now I covered that a couple of days ago I covered that in a previous video just follow through with that and you should be able to see how I got the database to save when I hit build it will search for and add all the items to the database that I may have forgot to put in myself and you can see that if we've hit build and run we're in the game we hit load and now our save files uh kind of in sync between the actual player and the editor and you can see that there's our Tomatoes got these Tomatoes here let's put a potato in come out of that let's save our game again all for to quit we can press play here hit load and the save files are now in sync which is great for debugging so later on as your game progresses and you start to get beta testers if they say I've got this weird bug with my game they can now send you the save files you'll be able to load it up in the editor and start to debug what exactly is going on so I hope that was useful for you I'm glad caught that bug and thanks again to the commenter for letting me know about it for the future of this inventory tutorial series I'm currently prototyping a shopkeeper system so you'll be able to sell items at a shop to make some gold that's currently in the prototyp in Phase it depends when this video comes out and how far I've got with that and what else has G in life when that will be but subscribe if that is something that you'd like to see if you want the project files for this tutorial or any of the other tutorials on my channel you can get them over on patreon.com there's a link for that in the description below if you need any help with this tutorial or any of my other tutorials you can come over to the Discord again which is linked in the description below but in the meantime thanks for watching and I'll see you in the next one [Music] bye hello and welcome to today's video in today's video I'm going to be showing you how we can give our scene a bit of a refresh just to take away those boring gold spheres and put in these nice uh 3D objects which is a free asset pack from itch see we've got them rotating to make them just look a bit more visually appealing uh we've got a C Machine camera that's following our little bean around and we can come over here and we can pick up the items and the requested feature and kind of the main sort of point of this video is that we can now drop them onto the ground and we can pick them back up and all the same stuff so we can still save our game and load our game the stuff that we've already picked up will be deleted and it'll go back into our inventory and very importantly we are going to fix a bug that I found while recording the video uh with our unique ID script uh there was a bit of a kind of glaring issue with that which I've since uh fixed I hope fingers crossed but let's just get straight into the video okay let's just get started so we're here with our um seen you know we've got our kind of ball RM blobs on the ground um if you go to the links in the description there's a free low poly 3D and pixel 2D um pack which we can use here um just click download now um and then you can you know you can tip them or you can just say no thanks take me to the downloads and you can get a load of models for free and you can see some of the the models here so we're going to use a couple of these to kind of jazz up our scene once we've got that all set up we will add um droping items out of the the inventory um putting them back on the ground so once you've downloaded the um Unity asset uh package this Unity package we can just drag and drop that into our assets folder and it's quite a big package so it'll take a little bit of time so you see that it's uh importing now and then once it's imported it will bring up this Unity import package if I just make this a bit bigger uh there's quite a lot of stuff in here you can import the whole package if you want um it's a bit unnecessary cuz some of the stuff we're not going to be using but I'll leave that up to you um so I'm just going to collapse everything uh when a list is open like that and it's expanded if you hold alt and click the top level it will collapse everything uh inside it as well so I don't need the read me and I don't need the reference under here uh I'm just going to get the AO images and then under 3D um we'll bring all of the 3D in um cuz there is a series of prefabs and we don't want to have to go through and uncheck the ones that we don't want uh we can just delete the ones we don't want back out of our project if that's the case and you can see that in the um images here for the offo view there's just little renders of the images um of the items inside and this is what we'll use to display in our inventory so just go ahead and hit import and again depending on how many objects you've picked in that menu it'll take a while to bring all of these in okay so they're all in now um you can see that we've got this new folder assets devil workshop and we've got our three 3D um folder and then in prefabs we can see our prefabs here and we can drag in the chests for example and we can see them here uh there's different eggs and stuff um but let's just undo that so what I'm actually going to do first I'm going to come down here and I'm going to delete all of our items and I'll leave just one of them and I think I've already set this as a prefab prefabs yes so we've got our tomato here so I'm just going to open up the prefab in the prefab viewer and I'm going to delete our sort of boring test sphere and then let's go to the devil's workshop prefab scene and I'm actually going to drag in uh one of the potions I'm going to drag in this health potion here so let's just drag that under our um tomato and you see here in the game view that the prefab has updated so I'm going to go back out into our scene go back to our prefab here and I'm going to rename it from tomato to health potion and I'm going to click on our tomato inventory item data here and I'm going to rename this to health potion uh let's call it health potion data just so we know exactly what it is so now I'm going to change the display name to health potion description this is a health potion stack size and gold value we'll just leave them as it is for now and then let's go back to our 2D assets come into the images folder and then you're going to need to select uh everything in this folder so click on the top item hold down shift and click on the bottom item and under texture type uh swap that from default to Sprite 2D and UI and then we can just hit apply and again depending on how many images you've got in this folder this will take a while so just let that complete okay so they're all now Sprite images so if we go back over to our item data and select our health potion we can now open this up and we can find our potion so we'll just type in potion and you can see here that we've got a nice icon for our potion and then I'm just going to rename the actual prefab in the scene to health potion as well and you'll see that if I hit play now and we walk over the potion we have our potion and it's gone in with the new icon now you can see it's a little bit stretched it doesn't look uh perfectly good so let's fix that um to do that we need to go into our um into a few different scripts so we can go over to Canvas inventory UI controller and let's start with the player hot bar so let's open up our static inventory display script so we've got our script here I'm just going to let this um open properly in Ryder okay so we actually need to go to the inventory slot UI script that was my mistake so let's go through to there so you can see here that we've got our private image item Sprite what we need to do in uh on awake is we need to go to item sprite. preserve um aspect and just set that to True um in code the reason for that and it's quite annoying is if we go back into unity and select one of our um inventory slot uis you can see when there's not a Sprite in there you can't see The Preserve aspect ratio uh box so if we go to our image so there's no um preserve aspect ratio box it's hidden if we put a Sprite in you can see now it says preserve aspect but obviously we don't want to have the graphics in because that's all set through code um so we just need to set that to True through code as well and we need to do that uh in a couple of other places as well so we need to do this on the uh Mouse item data as well so we'll come over to awake and we can say item Sprite do preserve aspect and just set that to true so now if we go back in and we pick up the item you can see that the uh icon's not stretched and then we can pick it up and put it onto our Mouse and it's not stretched there let's go over to our chest and we can put it in our chest and it's not stretched there okay so that's all working and looking good I'm just going to come over to our chest and I'm going to delete these two cubes now we need to open the prefab cuz I've made a prefab of them so let's delete those two cubes let's go over to our 3D prefab scene and we've got these um cool chests so for the small chest I'm going to have these golden this nice gold chest um and then for the big chest we've not actually made a prefab of this but let's delete our cubes from under that and then I'm going to drag in the silver chest uh under our big chest item so you see these are rotated slightly um so I'm just going to rotate this around just so the front latch is at the front um and same again with this let's just rotate that round um and then we'll have to override apply our changes to this prefab and then I'm actually going to make a prefab out of this this chest as well so let's just drag our big chest in here so now we've got that as a prefab so to make some other items it's quite a simple process so I'll do another one and then I'll go through and do a time lapse of making the others you can do sort of yours in your own time so let's just contrl D and duplicate our health potion and then I'm going to right click prefab unpack completely and I'm just going to call this one uh Mana potion underneath that we'll delete the um bottle from it and let's actually just drag this over so let's go back to these assets and this time I'm going to get the uh Mana potion you can see that's there it's a purple liquid instead of a red liquid actually just for differentiation I'll drag in the poison bottle um and let's just rename this to poison potion just so they look a bit visually different on the item data let let's select one of the other datas that uh one of these temporary datas I'll select the Apple um and then I'll rename our Apple to poison potion data we'll select the poison Sprite so we' got this Sprite here uh rename this to poison potion this is a poison potion Max stack size can be one um and we've got a gold value let's just put 10 doesn't really matter we haven't got any sort of currency sort of set up yet so we've got our health potion and a poison potion so I'm going to do two more different item types using some of the prefabs in here so like I said I'll time lapse that um and you can do as many or as few as you want okay so I've got our items here and I'm just going to make some prefabs of them them so let's go back over to our prefabs folder and we'll select all of the ones that we haven't made prefabs of and we'll just drag them so we have to drag them over here one by one so let's drag in our poison potion our cogs and our sword and our health potion um I moved the sort of visual representation down so I'll just apply those changes so now you can see that we can add these back into the scene and we'll have to move them up slightly so we can drag them out and position them kind of around the scene how we want can drag in another sword so if we hit play now you can see that they're they're a little bit boring um they're just sort of stationary so let's just add a bit of uh spin kind of movement to them so we can go over to our item script uh item pickup this mono Behavior lives on the items um and what we can do is in the update function we can do private void update and in here we're just going to rotate the items kind of over time and we can put a speed in so we can do serialized field private float and then we'll do underscore um rotation speed and what we'll say is um we'll do transform dot uh rotate and we'll rotate around uh Vector 3 dot up and then we'll times that by our rotation speed and then Times by time dot Delta time and then let's set our rotation speed to uh let's see 20 let's see whether that's too fast or not so you see that all of our health potions now have this rotation speed um let's set it to 20 in the inspector as well and just hit play Let's see what that looks like so you see that our items are just slowly rotating um on the ground I've missed these items up here let's drag them under our items and we'll put a rotation speed of 20 in there okay so that's just a little bit more visually interesting like while they're on the ground we can run over and pick them up they're in our inventory we've got our potions let's split them come over here let's make sure everything's going to save so let's put some potions in this chest got this bigger chest here let's put our stacked potions in there and one of our swords let's save our game come back out hit play load our game and you can see that all of our items are back in the respective spots we've got our sword and potions and our Potions there so that's still good that's still working so now let's make it so we can actually drop the items uh on the ground from our inventory so if I go over to uh our Mouse item data script you can see here that we've got this um we've got this thing in the update function that just says uh if the mouse. current. left button was pressed this Frame and we're not over a UI object currently we just delete the item by clearing the slot but we have we've had this to-do here for quite a while now minutes to drop the item on the ground so let's get rid of the uh to-do and let's actually do it so let's just make some space up here um and I'm actually going to uh up here let's make a private uh transform variable and we'll just call this uh the player transform and in awake I'm just going to Cache our player so I'm going to do player transform is equal to game object. find oh that's game object with a capital G uh find object uh game object with tag and we'll just put in the tag of player and then we'll do dot get component and we will get their transform component and we'll cach that now you may have a reference to your player somewhere else like on your game manager you'd get him from that way um this is just like a quick and dirty way to get the player transform um and I'm just going to if player transform is equal to null then let's debug. log um player not found and that's just in case you know something happens we'll see um that that's an issue so let's go back to our project and let's select our player and let's make sure that they have the player tag we need to make sure they've got that okay so we're back in our Mouse item data script and we need to instantiate our item here when we click it but we need to know what exactly we need to instantiate so for that we're going to need to add another variable on our inventory item data so let's go over here and let's make a public game object and we'll just call this um item prefab and then we can go back over to our m item data here and we can say um instantiate our assigned inventory slots. item data. item prefab and where we want to instantiate it is we want to do the player. transform but we need to position it somewhere kind of in front of the player or to the side of the player if we do it exactly where the player is we'll just pick the item straight back up which is a bit of a pain so we can do player. transform forward and then we can just put in a bit of a like a drop offset um I'm just going to put one F we can change that if we need to and we could make this a variable if we wanted to um so we can control it in the inspector but 1 F should be fine uh as long as the distance is is greater than kind of where the radius of the item pickup is so we've got um we'll put that just forward and then we'll do curnon do identity and then we can clear the slot and what you may want to do is just check um this so if uh item prefab is not equal to null then instantiate it and then we can clear the slot ah okay this is my mistake sorry we need to drop it um at the player transform do do position plus the player transform form do forward Times by the drop drop offet cuz we need to kind of attach it to where the player is and then just add a little bit of distance in front of the player so that was my mistake let's try that again pick this up and then we can drop it out of our imetry okay we've picked that straight back up so now let's put this back to one hopefully that won't that'll be a bit better let's pick it up drop it no still picking up up so let's put this to three pick it up drop it okay there you go it's uh in front of the player now so we see a couple of issues here so it's in the floor um and it's not rotating um that's because I changed the rotation speeds here but I didn't apply them um to the prefab so we just need to hit apply all so let's just hit okay to that message okay so that that should sort that if we look now all of our items have a rotation speed of 20 20 and we can see that the problem was that the item was spawning kind of on the ground and the actual pivot is here so there are a couple of ways to solve this and the easiest would probably be to open up all of our um items and let's select the actual uh game objects within them let's just move them back up if we look kind of where the radius of the pivot is so now the so this pivot is actually going to be where the potion spawns on the ground so let's just move them up slightly a little bit more Okay so we've moved them up now let's get our poison uh get the top level prefab objects and we've got our sphere collider here which we're setting its radius we can just move this up off the ground as well by raising the Y AIS so now the actual collider is around the game object but the pivot is slightly below so if we go back to these top level items of our prefabs we've got the potion the cogs and the um sword I don't think the cogs moved up annoyingly so let's just move them up properly let's move them up a bit more to kind of like there so let's apply those changes to our prefabs and we'll see that the other items should sort themselves out as well so we'll hit apply and there you go all of our prefabs have updated and now we can select all of the items in the world and we can actually reset their uh axis on the Y okay so they're all on the ground now but they're floating um so let's go back in and we'll pick them up and then we can pick them up and drop them out of our inventory and I may made the changes to the mouse object in play mode so just make sure you set that uh not in play mode come back over pick them all up and then hopefully finally we'll be able to pick it up and drop it kind of in front of us and it spins and we can pick it back up so currently if we pick up our three potions and drop them on the ground just one potion will be dropped uh not all three so let's sort that out so instead of clearing the slot uh what we can actually do is we can say um if assigned oh wait is the game still running no okay let's get rid of that so if assigned inventory slot do item data do um stack oh no not data assigned inventory slot do stack size is greater than one then we want to do something else we can clear the slot because they'll be the last item so instead of clearing the slot if there's more than one item on the item prefab what we actually want to do is we want to take our assigned inventory slot and we can um add to stack and we're actually going to add minus one so that'll take one away and then we can call our update um we can call our update Mouse slot function uh and I'm actually going to make a version of this method that doesn't take anything in so let's get rid of this and then get rid of that and here I'm going to call update Mouse slot and here we don't need to assign inventory slot CU we're going to do it here so let's get rid of that and then instead of taking from our items this inventory slot that we passed in we because we've already assigned it we can just pop it in here um and we can make that private cuz we're not I know we may we may call that from somewhere else in the future who knows so we'll just leave that public and then we've got our update function here so it's going to take one away from the stack and then it'll update the actual UI to show that and we'll spawn it on the ground so let's pick this up so we've got three health potions we can pick it up and we can drop one so we've got two left on our Mouse we can do it again okay you'll notice a bit of an issue here with our unique ID script which I didn't actually catch earlier so that's good we can we can debug this so we've got our unique ID script and what it seems to be doing is it's um spawning it with the ID from the prefab because that's what we've we have assigned it to in the prefab so we need to update our um unique ID script Okay so so that was a bit of a pain um I've had to do some jiggery pokery of the unique ID script I think it's working I've tested you know starting the editor closing the editor starting it up again changing scenes um building and running the game making a save in the built version of game load it back up in the editor making a save in the editor loading the built version of the game and it seems to be working it's quite robust um if you do have any problems or you know any better way of doing this do let me know in the comments uh I'd love to make sure this is kind of like production ready and we could actually use this properly um but for now uh I'll just go over some of the changes that I've made so you can see that I've got rid of the on validate function uh and I've actually generated and I've changed it to the awake function um the private string I've got rid of the generating uh guid there uh the reason for that is that it doesn't need to be called because we're checking and generating a key here anyway um if it needs to be and the reason we don't need unv validate and we can actually use awake is because of the execute in edit mode um tag on the script this attribute here so this is going to work in the same sort of way as um on validate wood when we generate a new item like duplicate an item or drag it out of the inspector it will do the right checks and it will generate it something else that's worth noting is um I'm initializing it here but there was some instances where it wouldn't actually be initialized the database would would be void for some reason um so I'm just checking if uh in a way just doing a null check to see whether the database has actually been uh initialized if it hasn't we'll just create a new database so that's just this bit of code here but we're putting it here instead and then this is the same as what was on in the unvalidated function uh so if the database contains the ID already then let's generate uh a new ID and if it doesn't contain it let's add it to it and then in on Destroy uh we're just saying that if the database contains the key let's just remove our ID and then generate I've not changed that that's the same um and the only other thing I've changed for this script then is over on item pickup I've moved the ID get component unique ID into star instead of on awake uh the reason for this is that we are generating ing the ID in the unique ID awake so if this script gets called after this awake function then the ID wouldn't be ready it wouldn't have been generated so then if we tried to add it um it wouldn't work it wouldn't have generated and it wouldn't have um there was no guarantee that it would have been unique because it may have been the same sort of ID before we actually generated a new one so we can go back over to un we can see this kind of working so if I hit play uh everything's going to be working the same so if I pick up all of these so I've got three cogs two potions two swords I can drop my potions and you can see over in the console uh there's no sort of Errors uh this was just a test over in the unique ID script um just debug. loging the actual count of the database when we generate I was just making sure that was working in um but you see we've got two potions here and we can pick them back up and we got our two potions and we can drop them again and there's no sort of uh errors there and we could do the same with the cogs we can pick up the cogs and we can drop some cogs and we can um every time it generates a new ID you can see that we're getting the count of the database when we pick it up so there eight and nine if we pick up the items and then drop them again you see that you know it's obviously reducing them as we're picking it's obviously reducing the database count as we pick up items and then generating new ones when we spawn them back in if it needs to the first one that we drop will have the same unique ID as the prefab but that's fine um you know as long as it's Unique that's okay so we can pick up all of our items hit save come out of the game go back into the game and then when we hit load because we've already picked up these items they will delete themselves and then we can come over here and we can put some stuff in the chests let's split this Cog stack hit save come back out and then if we run the game so we'll build and run and we can hit load they'll delet CU we've had them we've got our hot bar we have our cogs let's add them we have our potions let's take one of them split the stack keep that there and there you have it so that should all be working like I said if you've got any issues with this unique ID script do let me know I'll carry on doing some experiments with it as well and see if I can break it and if I do I'll fix it okay so the last little change I want to make is I want to come up here and I want to add uh a cinem machine camera so let's go to window uh package manager and let's go to the unity registry and look for cin machine and let's just install this package so with cin machine installed let's just come up to cin machine we'll create a virtual camera and that'll put it at the kind of spot uh that our camera was at so I'm just going to reset everything to zero and then in our camera I'm going to drag our player into the follow and I'll drag our player into the look at as well and then we can move our camera up slightly and kind of position it into sort of the perspective that we want for our player then under binding mode I'm just going to do a simple uh I'm going to swap that to World space and then I'm going to select do nothing on the AIM so you see that if we hit play now as we walk along the camera will follow our player um around the scene so we can uh make it a little bit more dynamic as we're walking around and we're accessing this stuff but yeah there we have it ended up being a bit more long-winded than I was hoping because of that bug but you know it's good that we caught it and we can kind of correct that so I said the project files for this video are over on my patreon which is patreon.com dmos I'd just like to take a minute to thank my supporters in the 10,000 XP tier we have omega mic and on screen now are all the amazing 4,000 XP tier patrons if you've been enjoying the series so far it'd be great if you could hit the like button it really helps the channel out and if you've got this far through without subscribing it'd be great if you could hit the Subscribe Button as well in the meantime thanks for watching and I'll see you in the next one [Music] bye hello hello and welcome to episode 12 of the inventory tutorial series and episode one of the shop system in our shop system uh there's not much really visibly to show kind of in game you can see we've got these three uh capsules here these are going to be our shop MPCs so we can see here we've got shop MPC and it's got a shop system and it's got three items and it's holding different amounts of those items got our shop MPC here this is the weapon shop it's got 10 swords available got the shopkeeper here this is the potion shop and it's got 50 of the health and poison potions which you can see in the world so there's a poison and the health potions and this is all defined by these scriptable objects here so we go to our potion shop we can see that I've said that we've got 50 poison potions and 50 health potions as well as the shop having uh kind of available gold that can be used to buy items from the player um each one of these has different values and that's driving these shops with the shop MPCs that's we're going to get to by the end of this video uh so let's just jump straight into it okay so let's just get started um so to start with I'm going to right click create a folder we can call this um shop system and let's enter this folder and I'm going to rightclick create um just a few scripts so I'm going to create a um shop item list and this is going to be a script object um script this will allow us to Define which items a shop is selling and how many of them they've got as well as how much gold that that um shop has access to for buying items from the player and a way of influencing the price of items to either make them a little bit more expensive or uh buy them for less money than the worth you'll see that as we kind of go along that that's how we can do that so let's just open this script up um Okay so we've got our script here so instead of monob behavior let's derive this from scriptable object and then let's um make a create asset menu and we can do menu name is equal to um we'll do shop system SL uh shop item list so as I said this is going to be everything that the um shop has in stock okay so the first thing we're going to do is we're going to have a serialized field uh private list of um shop inventory item which is a new class that we're going to make um and I'm just going to call this uh score items we'll have a serialize field uh private int Max allowed gold so again have that like that going to do a serialized field private float and this is our cell markup and we'll have a serialized field private float uh buy so let's create this um shop inventory item now and what this is going to be is it's just going to be a struct so we can come out of our class here and we'll just do a public struct um shop inventory item and this is just going to have a public uh inventory item data called item data as well as a public int um amount I need to make sure my item convention names are all we've got our shop inventory item here um and we need to mark this as serializable so we're going to do system. serializable okay so now we need to make a shop um keeper which is going to be the NPC in the world that holds holds our um shop inventory and it's going to be kind of like the inventory holder script we've got so let's go back over to our project and we can right click create and we'll create another C script and we'll call this um shop keeper and again we can go and open this up so uh shop system shopkeeper so our shopkeeper is going to be kind of like um chest or uh other items in the world that we want to save um because we're going to be influencing ing their inventory we want to be able to save them out and cuz there's going to be multiple of them uh we need to use our unique ID component so we'll just say require component type of uh unique ID and then it's going to be a mono behavior and it's going to inherit from I interactable as well because we're going to need to interact with the MPC so we can implement the missing members from our uh interactable interface so we'll Implement these um soon we're not going to use them straight away um let's just get rid of these for now as well and what I'm going to do is I'm going to create a um serialized field and this will be a private um shop item list and we'll call this a shop items held so this is going to control um again which kind of items the shop is selling and this will be here and then we need to create a shop system which lives on our shopkeeper uh to kind of hold and manage the shop interface and now this is kind of like we've got the inventory holder which has has an inventory system now we've got a shopkeeper which is going to have a shop system so again go back to Unity right click create CSH C Crypt C script and we'll have a shop system script then on our shopkeeper we can have a private buiild we can have a private um shop system for this shop system now let's jump into our shop system script so it's going to have some similar functionality to our um inventory system script but it's not going to derive from that we're going to kind of copy some of the code over where we need to but it does so much different that it's not sort of I don't really see the point of making kind of like a parent class to inherit from so the first thing I want to do in our shop system is Let's Make A Constructor so I'm going to say public shop system and this can take in an INT for the size of the system an INT for the amount of gold that the system will have a float for our um buy Mark book and a float for the cell Mark B and then up here we need to just make a private int we say available gold and we can set available gold to gold from our um Constructor we'll need a private float um buy markup as well as a private float sell markup and again let's do buy markup is equal to buy markup and sell markup is equal to cell markup and then I'm going to make a public um and then I'm going to make a private void uh set shop size uh method and this will take in uh the int size and what this will do is we'll set all this up and then we'll set the shop size and we'll pass in our size the kind of main thing that this is going to do is it's going to um create a list of shop slots which is another class we'll have to make so let's do a private um list of shop slot and we'll call this our shop inventory and before we make this method let's make this class so going to go back to um our project and now we're going to right click create cop script and we'll call this one shop slot now we're going to have to um do a bit of refactoring uh to get this to work so let's get rid of start an update and I'm going to open up our um inventory slot script here which is uh one that we we made way back when and I'm just going to open these up side by side so I'm actually going to put a lot of this functionality into something called uh an item slot and then the inventory slot will inherit from item slot so again we'll go back over here we'll right click create and I'm actually going to put this um I'm actually going to put this in our item scripts folder so I'm going to right click create C script and we'll call this one item slot so we've got item slot here and actually need to let's have these open side by side if you can split them uh I would do it makes this a lot easier so um for item slot that's going to implement I serialization call back receiver so we can um Implement those missing members and then inventory slot is going to inherit from item slot and item slot is going to be an abstract class we got public abstract class item slot and that's where our inventory slot is going to inherit from and then we can actually copy all of this to our item slot um class so let's get rid of let's get this we're going totr X to copy it and we're going to paste it cut it and we're going to paste it over here you see that we need to import um missing members there and instead of being private these now need to be protected so the um this class can access them but no other class can so protected I'm going to start moving some of these methods over so public void clear slot I'm going to take clear slot and I'm going to put that on to the item slot um class assign item I'm going to take that and we'll cut it and we'll pop it over on the item slot uh function the item slot class you see the add to stack is now um red so we need to take add to stack and remove from stack let's cut them and then we'll pop them onto our uh item slot class and now in inventory slot uh we don't need this um on after deserialize so we can take this um we'll cut this into uh this method here and we'll get rid of uh this exception and we can get rid of these so now in our inventory slot um we've still got access to all of these methods because again we're inheriting from item slot now and we've just left um so on inventory slot we've now got um our enough room left in stack methods our split stack method a Constructor to make an inventry slot that just sets it up as a clear slot and this other Constructor here um the reason that we've got we haven't copied these over to item slot is that we don't need to check on a shop slot if there's enough room in the stack so I've basically what I've done here is I've taken uh the stacking ability uh functionality out of um the shop slot because shops don't need to stack it's going to just show a list of an item and how many it's got it doesn't care about Stacks cuz that' look really weird in the UI to have multiple entries for the same item just showing different Stacks so an inventory slot can stack a shop slot can't so but a shop slot um needs to be able to kind of add items to it remove items from it um you know access its save data be able to assign an item to it so that is shared functionality so that's why we've put this into our abstract item slot class so now if we go back to shop slot this can inherit from um item slot and then all this is going to do is when we make a new shop slot is it's just going to create a clear slot now in our shop system we've got our list of shop slots and I can close our inventory slot um functionality and first let's just make sure that we've not broken anything crazy um with our normal inventory system so we can go over to play and we can pick up our items and they're all still stacking uh nicely we can go over to our inventory and we can put the items in the inventory so that's working uh fine so we've not broken anything there which is always a plus so now on our shop system uh back in our private void set shop size um function we're just going to set our shop inventory equal to a new list shop slots with the size that we Define and then we're going to say um 4 in 4 in I equals z and whilst I is less than the size we're going to get our shop inventory and we're going to add a new um shop slot to our shop size so we've created a new shop inventory and we've filled it with our slots so now if we go back over to our shopkeeper in the um awake function we can say shop system is equal to a new shop system and this is going to take in um so the size is going to be the amount of items that it held so shop system shop items held do um items. count and we need to go to our shop item list and be able to get access to our items we're going to need to make um of public ghettos for all of these so we say public list of shop inventory item called items this just returns returns items public in uh Max allowed gold this can return Max allowed gold okay so I've done that there we've put Getters in for our um builds here so we go back to shopkeeper so we're going to pass in the items count the um items held uh Max allowed gold the um items held buy mark up and the shop items held sell markup I'm just going to drop this down to a new line so all fit one screen so so got our shop system here uh shop system we need to get rid of mono Behavior as well and we're going to add the items from our list to our shop system so we can say for each uh variable item in the shop uh items held do items let's add it to our uh shop system so shop system. add to shop which is a method that we're going to need to make and we're going to pass in the item uh item data as well as the item do item um uh amount pop over to our shop system and let's make that method so public void add to which is going to take in an inventory item data called data and an INT amount so this is going to be quite similar to our inventory system so let's get our inventory system script open going to put this uh next to it in this window here so we've got our add to inventory here and we're going to need to do some similar stuff but not the exact same so that's why I'm not uh deriving this from like an item system uh we can just copy it over uh for the most part so the main thing is this a contained item let's just copy this over and then we'll have to change some of the code so copy that paste it over so we've got contained uh item zoom out just a tiny bit so instead of passing out a list of inventory slots this is just going to pass out a shop slot and it's going to pass out and here we're going to say shop slot is equal to shop inventory is equal to shop inventory. find which is a um function so we'll do shop inventory do find we can say uh I for item so if the item data equal to the item to add which we've passed in here and we're just going to find the first one and then we can return we um return shop slot is not equal to null so if we found the item already in the shop then we're going to get the shop shop slot that that item is uh in and then shop slot won't be null so it will return that it's not equal to null it be true so it'll say yep we contain the item and if it returns false and if it is null cuz it hasn't found the item it'll return false so in our add to shop we can say that if contains item we can pass in the data and get back out the um shop slot let's put shop slot then we're just going to add the amount to the stack and again we don't care about like enough room left in the stack on a shop slot it's just can it can hold an infinite amount of items so we'll say add to stack the shop doesn't already contain the item we need to get um a free slot and that's just going to make a new slot so we can say um bar free slot is equal to get free slot and then this can be a private function which returns a shop slot so private shop slot get fre slot and all this is going to do is um going to make a free slot and it's just going to find the um shop inventory first or default and it's going to find the first slot where the slots data is equal to null and if for some reason our free slot is equal to null so if it hasn't found a empty slot then our shop can have as many slots as it needs so all we're going to do then just as a bit of a fail safe we can do free slot is equal to a new shop slot We'll add that slot to the inventory so we're going add the free slot and then we're just going to return our free slot so this will never be null we're always going to get a slot ideally it'll be the one from our inventory but just as a fail safe as I said we can create a new one and add this to the inventory we can always get the free slot here and then we can assign fre slot. assign item and we'll pass in our data and amount and this is complaining because we need to put from our inventory slot oh yeah so on our item slot we need to make another function that assigns an item by taking in some data and amount so public void assign item and this will take in a inventory item data called data and it'll take in an INT for the amount and if the slot already contains data so if item data is equal to data let's just add to the stack the amount else item data is uh equal to data Item ID is equal to the uh data do ID stack size is equal to to Z just to default it out and then we can just add to stack the amount so back over on our shop system so we're going to add it to the shop if it contains the item we'll just add to the stack and if it doesn't then we're going to make a new slot and assign the data to it so back on our shop system uh back on our shopkeeper we can now see uh this method here and that's all working so when the shopkeeper um when the game starts we're going to make a new shop system and then we're going to add uh an item to the stock of that shop so we're going to Loop through all of the items that the shop holds and we're going to add it to our shop system and that's it for the shopkeeper for now okay so let's make an MPC to try and interact with so I'm going to come over to our scene here and I'm going to right click create uh an empty and I'm just going to call this our shop MPC and I'm going to right click create 3D object uh captur so this is our shop MPC so let's drop the shopkeeper script onto it you see that it needs a um item held list I'm going to get this and let's bring that over here you see we've got a bit of an issue here where it already adds a script when it adds the unique ID script to an object um it's not working straight away so let's just um we can do uh context menu generate ID and we can just uh generate an ID for that to get rid of the error that we were having so now in our shop system let's create a folder called um shop item list list so for scriptable objects and we can right click create shop system shop item list and we'll just call this um default shop list for now for the max allowed gold let's say the shop keeper can start with um 1,000 gold and for the markup this can be um this is going to be a percentage so we can say it's going to mark up the price by 25% by 25% so if something is um you know worth 100 gold so and what that's doing is if we look into our item data folder you can see we've got our gold value here which is going to be um set to something like 100 for example and that's kind of a base value now using these markups if uh if I put 0.25 here and say 0.5 in the buy markup what this is going to do eventually is the when we try to sell a um if we try and sell that Cog which is worth a 100 to the shopkeeper he's actually only going to offer us 75 gold for it instead of 100 cuz he's going to take 25% off and then he will sell cogs to us for 150 gold so that's kind of the markup um so now you got to think of these is kind of like a base value this is kind of you know so in an Ideal World if a shop really likes you for example they're not going to mark up this is how much it's going to cost but we've now got that flexibility to kind of you know rip off the player or even reward the player we can offer him more um more than the actual value if for example that MPC really wants certain items um or really likes you they can you can specify that here and in our items um list we can now drop in um some stock so we can open up this and we can say Cog so the shop is going to stock 99 cogs and let's say it will stock 10 potions and let's say it can stock um one sword So that's its stock list we can go back over to our shop MPC and let's add our default shop item list to that and then let's just um we're not going to get the UI set up in this video um but let's just put a debug. login so back on our shop system so over on our shopkeeper script um we'll say for each item in shop items held let's just debug.log um item and we'll make a new string and we'll say say um item do uh item data do display name and then we'll put a colon and we'll put in the item do amount so this is just going to debug.log every item um that's getting added to the shop and the amount of the item as well so if we hit play you can see that when we've set up our shopkeeper system we've got our cogs 99 health potion 10 and the shop contains one sword now and if we go over to our shop system uh we can actually add uh system do serializable uh to our shop system so we've got our shop system so after we've added system. serializable uh we can serialize these fields and we should be able to see them in the inspector we'll do serialized field serialized field and then if we go over to our shopkeeper let's serialize this field as well and then if we go over to shop slot we also need to mark this as system. serializable as well and now this is serializable the shopkeeper is serializable so if we go back to Unity we should be able to see this all in the inspector so we've got shop inventory and we can see our inventory there so if we hit play we can now see our shop inventory has 99 of item id 2 it's got 10 of item id 50 and uh one of item id zero and we can see that our Cog has an ID of two we've got our Cog here got 99 of them and our shop MBC has 99 of item 2 so the great thing about this is we can have multiple NPCs now so if we uh um contrl D and duplicate our PC and make another one and it's got the same list so let's right click create shop item list and we'll say um weapon shop and this can be a shop that has all of our weapons so we've only got one um item here but let's say it carries 10 swords it can have 2,000 gold it's got a sell markup of 1.5 and a buy markup of 1.5 now we go back over to our MPC we'll give it the new sort of stock list we'll hit play you can now see that this has got 10 swords this one has only got one sword but it's got all of our other items and we've defined all of these different things in our shop systems and again to show you kind of how easy it is we can make shop system and we'll say potion shop this will stock two items it'll stock the poison potion and the health potion and it'll have 50 of each they'll have 500 gold but they're going to rip you off with the um with the markup and then we can make a another Bean this will be our potion shop so we'll make a potion shop hit play so we've got three individual um shops here so we've got our uh MPC here which has got the default shop list we've got this MPC which is a is a weapon shop we've got this MPC which is a potion shop so that's going to be it for this video um I know there's a lot of like jump in between different scripts and refactoring stuff but that's kind of the way these things go um but hopefully that all made sense and if you followed if you've got to this point in the inventory tutorial system uh hopefully it will all make sense because these are scripts that we've kind of dove in and out of numerous times and it's a lot of the kind of same concepts of the uh sort of inventory system so if I skipped over anything um quickly maybe go back and watch the previous videos to kind of get up to speed with for example how the contains item function works or you know whatever um in the next video we'll start to set up the UI for the shopkeeper which will display their inventory in a list and we'll see how far we get with that um and whether we have to make another video about actually purchasing and selling items to the shop if you want access to the project files from this video you can head over to patreon.com where they are available I'd just like to take a minute to thank all of my patrons on screen now we can see the 10,000 XP tier which is a sector sweep and I want to thank all of the 4,000 XP tier members as well if you need any help with this video make sure you head over to the Discord server which is linked in the description below or just leave a comment on the video and I'll do my best to help you there but in the meantime thanks for watching and I'll catch you in the next one [Music] bye hello and welcome to episode 13 of the inventry tutorial series and episode two of the shop system so we've got our shop system here you can see that we've got this kind of popup window that's the going to be our shop and you can see it's going to be able to have a buy and sell tab so this is going to show either the shoping ventory or the player inventory we're going to add things to this window here which is the shopping cart and then we'll be able to buy the items or sell our items that'll be coming in the next video in this video we're just going be working on laying all this out getting it all set up um making a few scripts and just you know laying the groundw to actually plug in the UI to the shop system we made in the previous video and you can see currently if we hit play we can walk over to our NPCs which we've made and we can interact with them and it'll bring up the window that's what we're going to get to in this video it's not the most exciting thing but it's a necessary step on the way to displaying our shops so let's just jump straight into it okay so let's get started so let's go on our canvas here and I'm going to make a new um empty I'm going to call this the shop UI controller and to this I'm going to make a panel so right click UI and I'm going to put in the uh graphic that I've been um using for the other inventory stuff um panel it's not there uh what's it called so with our panel I'm just going to make it a kind of uh brownie color you know you put any sort of Graphics in here that you want so I'll make it this color here and I'm going to get the panel and uh let's go into sort of 2D UI mode going to be doing a lot of UI stuff let's zoom out and we can make this panel nice and big uh you can make it fill the screen if you want um if you want the shop to kind of fill up the whole screen I'm just going to make it like this so it'll pop up like this and then I'm going to make a new um empty I'm just going to call this uh window left cuz we're going to split our shop window into two uh sections and I'm also going to make a empty say window to our panel object we're going to add in a uh horizontal layout group and we're going to let this we're going to let this control the child size and we're going to say the child alignment is going to be the upper center now if we go over to our window left you can see see that the box is now uh half of the panel that we've uh made and the other box is on the other half of the panel that we've made so to our window left object I'm going to create two uh UI buttons um and if you've got all of these weird lines up you can remove uh visualize I'm just going to bring this up here let's make it a bit uh bigger and this will be the buy tab so we'll click this and it'll show us the items that we can buy from the shop and then we can click we're going to make a sell button which will show us uh the items in our inventory and this like and allow us to sell them to the shop so we've got our buy button uh let's rename this just so we know exactly what it is buy button and then we'll uh contrl D duplicate this will be the uh cell button move this over and then Swap this text to say cell and then underneath our buttons um we're going to make a UI um scroll scroll view I'm just going to drag this just above the buttons in the hierarchy and we're going to select a stretch to fill the whole um the whole canvas but then we'll just bring it down um to not kind of overlap the tabs I don't want the horizontal bar on our scroll wck so I'm just going to uncheck horizontal and we can remove the horizontal scroll bar we'll just select nonone then under scroll view we can just delete the horizontal scroll bar and then if we go to the vertical scroll bar we can just drag that out so it fits our entire panel then I'm going to twirl out that and I'm just going to rename this content um object to um item list just so we know kind of um I'm going to rename this to item scroll list just so we know um that when if we're just looking at this that this is the scroll list and then we need to just make this a bit bigger um just kind of just below the scroll button you can see depending on how big this is that's kind of responsible for for how much we can scroll um so we'll we'll have to change and tweak this probably as we go uh but for now that's fine and then over on the right hand side so let's just close that on the right hand side I'm going to make a um Another Empty we're going to call this uh item preview and can make this fill this side of the screen take it all the way to the top and to our item preview we're going to add um a Sprite so UI image and we'll call this the item Sprite and let's just drop in a Sprite just so we can see how this is all looking so we'll do our bottle we'll do preserve aspect um and let's just make this a little bit bigger we're going to add some text so we can say UI text mesh Pro bring this down we'll Auto size it we'll align it um horizontally and vertically and here we'll just say uh health potion again just so we can lay this all out this will be all changed through code anyway way um and then let's so we'll rename this to item dis uh item name then we'll let's just duplicate it we'll move it down this time I'm going to make this a little bit bigger there and I'm going to uh left align it and top align it and say this is the description and we'll make the max size just a little bit smaller and then we'll rename the object to item description and then we're going to make another object we'll right click uh create empty and this is going to be the shopping cart so this is going to have uh another scroll view so we'll right click UI scroll View and then let's drag this um down so we'll position that kind of down here again we'll make it fill the uh this half of the canvas so we'll just drag that out and like before we don't want a horizontal one um we can get rid of the horizontal bar the um vertical scroll bar fill the actual frame and it says missing let's just select none um on there got our scroll list here and then again let's rename the content panel just so we know exactly what this is so this is going to be the uming cart list and then to our shopping cart item let's create a button so we'll say uh UI button text mesh Pro and this will be the um buy sell button and we'll just drag this down here just under our uh shopping cart let's make it a bit bigger we'll go to our text and we'll say um buy items so we're going to make some more text so we're going to right click shopping cart UI text text mesh Pro let's bring this down here uh we can make it a bit bigger kind of to here and I'm going to Center and right align this and I'm just going to put in um total uh 5,000 gold that's how much our shopping cart this is going to display how much our shopping cart is worth so we can rename this object to basket total and then I'm going to duplicate this and let's move it up and this is going to be um shop gold so this is how how much gold the shop has access to so let's say uh th000 um and I'm just going to make this a little bit smaller this is the sharp gold and then let's duplicate this again got to move it over um we need to left align this rename it to player gold oh what's going on rename this to play player gold and then in the text we can say player gold and we'll say 500g so this is how our Shop's going to look and it's going to have um items kind of added to it uh into this scroll view here and let's get a look for what that's going to look like so if we go up to our um window left scroll view let's go to our uh item scroll list and let's create an empty and can call this um shop item list UI so to this we're going to add in a item Sprite so we'll say UI image let's call this item Sprite and again just for Simplicity let's put our um item in it and I'm going to make this the size of our panel here so we've got our item Sprite I'm going to add some text to this so we'll say UI text mesh Pro uh left align it I'm going to center it though um and we'll say health ocean that out to about there we can position this kind of where we want it this is going to be item name we'll duplicate this move it down this will be the item amount so this is going to be how many of the item the shop has so we'll say it's got five potions and I'm just going to make this a little bit smaller than the text and the name of the text and then I'm going to add two more buttons to this and then that should hopefully be most of the UI done um we'll just need to start the kind of code side of it so let's do button text mesh Pro and I'm going to say add to cart button I'm going to make this uh square and for the text I'm just going to put a plus symbol this a bit bigger so it's going to be to add it to to the cart we can drag that over and then let's duplicate this move it over we'll call this the remove from cart button and instead of a plus it can be a minus um and then you may want to move it up so it's sort of Center in the button there's our shop item list UI and to get this working correctly into a list we just need to add a grid um layout group to the item scroll list um so we'll say grid layout group and we'll say upper left instead of constraint we'll say fixed column count and there just going to be one column pivot on our shop item okay so you can see it's gone off kind of kilter here uh we need to set the items to be pivoted to the top left corner um so unfortunately we're going to have to relay these out we'll select all of our items we'll click onto the anchor preset so we'll hold down alt and then click the top left corner one and then let's just reset our layout here okay so we've um adjusted them got our item scroll list and then we can start to put in some padding um we'll do 32 on each of the grid layout Group which again is on the item scroll list uh object and let's just create um these just to see how these are going to lay out so um now we can adjust the sort of spacing and the cell size so if you want a bit more of a gap between them you say like 64 32 32 kind of works uh cell size shouldn't matter too much um because we're kind of controlling that all through the sort of position of this uh shop list item UI so you see that these are looking quite good we can duplicate them and because it's in a scroll box it'll go kind of below the scroll View and we'll be able to scroll down kind of in the game I'm actually going to delete all these go to our prefabs and I'm going to drag in this shop item list UI and I'm going to make a prefab out of it and then we're going to delete it from our view and I'm going to go over to the shop UI controller which is the kind of top level of object and this is going to be what sort of pops up when we access a shop so it'll bring up the shop and it we can close the shop so this is the sort of top level object and to this I'm going to add a script I'm going to go to my UI scripts folder going to right click create C script and we'll call this the shopkeeper playay and let's open this up in our um editor and let's get started adding some variables to this okay so we're going to need to start um making fields for all the kind of UI elements that we've just made so I'm going to make uh a serialized field private um and this is going to be shop slot UI which is going to be uh another script that we put onto that shop slot that we just made um so I'll say shop slot preab and then let's actually make that so in our UI scripts folder let's create another script we'll call this the shop slot UI so this is a thing that we just made with the buttons to add and remove to the cart um we're going to need another one for uh we're going to have to do something quite similar for the shopping cart section um but we'll get to that kind of later on um we want a serialized field for um a private button and this is the uh Buy Tab we'll need a one for the cell Tab and you see this is red here cuz we need to import type uh using Unity engine UI we need to make sure we've got that to kind of access the button um I'm going to make a header here I'm I'm going to call this the um shopping cart this will be the shopping cart section I'm going to do serialized field private mesh Pro yugy basket total text I'm going to duplicate this a couple of times we're going to have the uh player gold text as well as the shop gold text and I have another button reference so serialized field private button and this is the uh buy button on the shopping cart and then we want a serialized field PR private private text mesh Pro UG goey and this is the buy button text so this is going to change to say either buy or sell depending which sort of tab we're in and I'm going to make a new header we'll say uh item preview we'll do serialize field private image and we'll do the um item preview Sprite serialized field private text mesh Pro ug and this is is the item preview name and we can copy this and this is the item preview description and we need a serialized field private game object and this is going to be our um item game game object uh item list content panel and we'll duplicate this and this will be our shopping panel so let's go back to Unity going go to our shop UI controller and to this we can add our shopkeeper display and we need to hook all of these up so the shop slot prefab that was the prefab that we just um made so if I go over to prefabs shop slot uh shop item list UI oh to that we need to add the shop slot UI script that we've made that doesn't do anything yet but that's fine uh we can drag in our shop slot UI for the tabs we'll do Buy Tab and sell tab basket total gold drop gold and the buy sell button the buy sell button text item preview so we've got item Sprite Which can go down there item name item description and then we've got our item list content panel which is this item scroll list and then we've got the shopping cart panel which is under scroll view scroll bar view uh viewport and we've got our shopping cart list so that's our UI set up there just going to press save so let's make the other prefab which is going to be the um thing that we populate the shopping cart with so so all this is going to be um let's go to our shopping cart list so that's this content panel here I'm going to right click create empty and let's call this um shopping cart item and to that I'm just going to add um some UI text for text mesh Pro and we'll put in uh item name time 10 we'll stretch that to fill kind of the available space it has for our shopping cart item I'm going to again anchor it to the top left let's make our um item kind of fill the content panel here we will just going to make this a bit smaller and just give it a little bit of padding and then on our shopping cart content panel we need to do what we did earlier so we need to make a um grid layout group on this uh fixed column count again is one we'll give it some padding so 32 um spacing we'll do 32 so let's anchor that to the sort of Center left actually and let's uh Center it out on there drag that in a bit so this is our shopping cart item see as we've duplicated them they've gone off the panel uh we need to reduce the Y on the cell size about there going to reduce the padding on the top as well padding on the left a bit there we go so we can add multiple items to our basket now so let's uh delete them make a prefab out of our shopping cart item delete it from the list let's make a new script then called um C script uh shopping car item UI let's add that to our the shoping cart item prefab that we've just made we'll jump back over to our shopkeeper display um script and we're going to do uh serialized field private shopping car item UI we'll do shopping carart item refab and we can hook that up in the inspector as well so let's go back to our shop UI controller drag in our shopping cart item UI okay so let's actually just get this displaying and I think that' be a good place to end the video cuz it's gone on for quite a little bit um so let's go over to our project and I'm going to open up up our shopkeeper script and we can see here that we've got um the I interactable interface on it so when we interact we can ask the UI manager to display the shop system so um in our interact function we can just uh let's make a Unity event so we'll do public static Unity action and this is going to pass to the shop uh panel it's going to pass the shop system our shop system it's going to pass that in and it's also going to pass in a player inventory player inventory do we not have and it's going to pass in the player inventory holder and this is just going to be called um onshop window requested so in our interact we need to get the player inventry component so I'm going to say player VAR player inv is equal to interactor component player inventory holder and then if our player INF variable is not equal to null then we've got the player inventory successfully we can say uh on shop window requested and we can invoke that by passing in our shop system as well as the player inventory we can end the interaction um for now and then we'll do interact successful is equal to true and actually let's get rid of that we don't need the end interaction function in there and then we can say else interact successful was equal to false and then let's just debug do log error um player inventory not found okay so back in Unity on our main canvas object I'm going to add a kind of top level UI controller so right click create cop script UI controller and then let's add the UI controller to our UI canvas and let's open that up so in here on the um on enable function we're going to subscribe to shopkeeper do onshop window requested and let's do display shop window which is um planing because that's not a thing so let's Implement that so we've got a method that takes in a shop system and a player inventory let's rename this to shop system and player inventory and then in on disable let's unsubscribed so on shop window requested let's unsubscribe the display shop window function let's take in a serialized field shop uh private shop keeper display and we'll say shop display let call it shopkeeper display yeah so the first thing all we're going to do for now is we're going to open up that panel so shopkeeper display dot set active uh game object sorry do set active to true and then in awake let's make sure the shopkeeper display is closed so game object do set active false so back in unity shop UI controller goes into there so if we go over to our NPCs we need to add them to the interactable layer so let's just choose um interactable and we'll just say no this object only we don't want to set the capsuls As interactable and let's add a captal colliders to the actual top level MPCs and remove them from the captal graphics so if we hit play that should work go over here we can hit e and that's going to bring up our shop system uh window so that's going to be it for this video in the next video we're going to work on looping through the shop system and the player inventory and displaying them accordingly in this panel here and then when we click the buttons on those um shop UI panels we'll add them to the car and will'll allow the player to actually buy the item by clicking the buy item button obviously all of this will update and work very nicely if you'd like the project files for this video and this entire Series so far they are available on patreon which is patreon.com dmos I'd just like to take a minute to thank all of my patrons on screen now we can see the 10,000 x x b tier which is uh sector sweep and I want to thank all of the 4,000 XP tier members as well if you need any help for this video or any my other videos feel free to leave a comment below or head over to the Discord server which is linked in the description and in the meantime thanks for watching and I'll see you in the next one [Music] bye hello and welcome to this video at the end of this video we'll be able to interact with our NPCs and utilize the shop system UI that we made in the last video so we're going to come over here we can press e to interact with our NPCs so we'll press e and it'll bring up the shop window it's going to list all of the items that the shop has in stock so you can see from our script of objects that there's 99 cogs 10 health potions and one sword item in this shop and the shop has 1,000 gold available so let's just jump straight into this video okay so let's just continue where we left off so in the previous episode we'd set up the canvas um and we'd made this shopkeeper display script but it currently doesn't do anything so let's make it do some stuff okay so the first thing that it would make sense to do is actually to spawn the um the items from the shop in our shop list on that left hand panel so let's set that up first so we'll do a public void display shop window and in here this will take in a shop system we'll just call this uh oh just call that shop system and we'll do player inventory holder and we'll call this player inventory holder so let's assign the um shop system in the player inventory holder to some sort of like uh script wide variables that we can kind of keep a reference to so we'll do a private shop system and we'll call this uh underscore shop system and we'll do a private player inventory holder and we'll call that player inventory holder so the first thing we'll do is we'll get our shop system and we'll we'll get underscore shop system and we'll equal this to shop system and underscore player inventory holder and we'll equal this to player inventory holder and then we'll refresh the display which is going to be a new method that we'll make so we'll do private void refresh display and the first thing we'll do here is we'll clear our slots you'll notice this is seeming and this is sounding a little bit like the Dynamic inventory display and our um static inventory display there's not really a huge amount of copied functionality like we don't need to be able to click on the slots or anything um so I didn't want to kind of have shopkeeper display derive from inventory display but of course there are um some functions that are of course there are some stuff kind of in common so for example uh clear slots but we're not going to copy this over wholesale I just thought I'd point that out um I am aware that there's similar sort of naming but they're not they're different enough to not kind of need to derive from uh inventory display so we going to have uh clear slots and this is going to be a private void clear slots so this is going to Loop through every uh item in our um item content list panel and the do transform and then we'll do cast transform so that's just like we're doing here but we're doing it on our display and we're going to destroy item. game object and then we're going to do the exact same thing again on the shopping car content panel that's going to clear the slots um and we actually need two dictionaries which are going to keep track of um what we have in our shopping cart so let's come up here and we'll do um private oh private dictionary which is going to take in uh inventory item data as well as an INT and this is going to be our shopping part which is going to be a new dictionary of inventory item datas and int and then we're going to have a private dictionary again of inventory item data and this is going to be the UI kind of side of it and this is going to take in our shopping cart item UI and this will be the shopping cart and this will be the shopping cart uh I'll call it UI so that's equal to a new dictionary of so there's our two diction so as well as in in clear slots as well as deleting all of these items we're going to clear out these um lists these dictionaries as well we're just going to delete them make new ones replace them with these new um dictionaries to make sure they're nice and fresh um so that's our clear slots function which we need in our refresh display and then we're going to disable the basket total text because obviously there won't be anything in the basket at first so we may as well disable it you could also just set it to zero um but I am going to set it uh to false so basket total text. enabled is equal to false going to turn off the buy button so buy button. game object do set active false um we're going to make another int up here uh we'll do it here so private int and this is the basket total this is going to keep track of how much our basket is going to cost um so obviously when we're refreshing the display and the slots of being cleared we can actually set that back to zero cuz we know there's nothing in the basket so it won't be worth any kind of amount of gold and we can refresh the text so we can do player gold. text is equal to um ring so player gold we'll set this equal to the player inventory fer do inventory system dot gold and I don't think we've actually implemented that yet so let's go over to the primary inventory system let's actually um serialized field private int gold so let's introduce the concept of gold to our inventory system and we'll do public int gold and we will return gold our private int gold up here and then as well as this public inventory system Constructor uh we're going to make another one which can now give us some gold so public inventory system which will take in a size and a gold amount and here we can say gold is equal gold and then we will call our um here we say gold is equal to the gold amount that we've passed in and here we'll just set gold to zero as a default and I'm going to take this bit of code and I'm going to a private void method called create inventory which takes in a size and then we can just say create inventory size and that down here as well so we've got two Constructors now one just takes in a size this one takes in some gold to give to the player so we've introduced the concept of gold to our inventory system let's go back over to shopkeeper display so we've now got gold so we're going to display the player gold and then we want to do the same but for the shop gold text and then we'll say shop gold and this will take from the shop system the available gold and I don't think that's um we haven't got kind of getter for that so we'll just do public in available gold which will return available gold and then we'll go back over to our shopkeeper display and you see that that's working there now okay so now we just want to uh make another method and this one is going to be a private void display shot inventory um we're not going to use this one just yet but I'm just going to make uh private void display player inventory as well just while we're doing that um so up in refresh display let's call that so display um shop inventory and all we're going to do in this method is we're going to Loop through every item in our shop systems inventory so shop system do uh items which I don't think we can get uh it's this shop inventory here we need to allow a getter for that so public list of shop slots all shop inventory which will allow us to get the shop inventory um variable go back over here and we can say for every item in our Shop's inventory if the item do uh item data is equal to null then let's just continue because we only want to calculate we only want to spawn in a slot if it's not null and then we can say V shop slot is equal to instantiate the shop slot prefab underneath our shop list uh panel what's it called underneath our item list content panel. transform then we can initialize the shop slot so shop slot in it and this is going to pass in our item along with the shop system. buy markup which again we can't get I'm going to do a public float uh buy mark up which will return the buy markup and then we may as well do the sell markup while we're here we will need to do that so this init function this is going to be on our chop slot UI um class that we made and never did anything with so let's do a public void in it which will take in shop slot and a float so shop slot slot and Float uh markup okay so let's work now on initializing our shop slot so we'll go over to the shop slot UI class and we'll serialize field private image in unity engine UI uh uh item Sprite we'll do serialized field private text mesh Pro ug item name and let's just uh duplicate that to be item and we'll do a serialized field private shop slot find item slot in our awake function we're going to um set the item sprite. Sprite equal to null uh item sprite. preserve aspect equal to True item bright. color equal to color. clear item name. text is equal to uh just a blank string and item count. text again equal to a blind string an empty string uh we want our buttons as well so we want a um serialized field private button and this is the add to cart button so add item to cart as well as a remove item from cart button now I'll call these buttons just so we know exactly what they are so to our buttons we're going to add some methods so we're going to say uh add item to cart button if it's not null we're going to uh sub we're going to add a listener to the onclick button and it's going to be an add item to cart method we've got remove item from cart onclick We'll add listener we will remove item from cart and we can also get a private shopkeeper display let's call this parent display once you going to make this public with a getter and private Setter we don't need to assign that in the inspector so we're just going to do get private set parent display is equal to transform. parent. get component in parent. keeper display now let's make these functions here so add item to cart let's create a method for that and let's create a method for remove item from cart Okay so so before we start hooking up these buttons and making them work let's get rid of these throw new not implemented exceptions I'm going to make a priv void um update UI slot which is going to take in shop slot so shop slot as well as the markup so float price markup and just going to move this init function up here just so it follows a bit more of a logical order so in our init function I'm just going to set our assigned item slot equal to slot and call all update UI slot passing in our shop slot and mark up and then in our update UI slot we can say if assigned item slot. data is not equal to null just as a check we're going to say item sprite. Sprite is equal to signed item slot. item data. icon we can set the item sprite. color equal to color. White the item count do be equal to the item slot the assigned item slot. stack size. two string and then the item name. text is going to be equal to item slot assigned item slot. dat. display name and then for now we're just going to do um the item slot item data do value so this isn't going to take into account the markup for now but let's just um let's just get this in and work in and then here we can say uh else so if the item is null and let's just uh clear the slot out so let's that there um think about it we don't actually need to pass in shop slot like that let's just get rid of those um and then let's store this markup so we can use it later uh in a public float and markup again with a get and private set here we'll just say markup is equal to markup just so we can access that down here when we do actually want to use the markup and then assigned item slot obviously we're setting here when we initialize it and then just to make sure the buttons are getting um set up properly and kind of registered to these events let's just say uh let's debug.log adding item to cart and then uh removing item from cart okay so now on our UI controller here when we set our um display to active so when we interact with the NPCs and we turn on the shop window we want to set it active and then we want to call the display shop window method on this function and we can pass in the shop system and the player inventory here so we're going to interact with NPC it's going to call this method which is going to turn on the actual game object so it pops up and we can see it and then we're going to call the display Shop menu uh shop window method that's going to set up the shop system in the player inventry holder and then it's going to refresh the display which is going to clear any slots that were already there on the panel it will then reset all of the sort of text and the variables and then it will display the shop inventory which is going to spawn in our shop system prefab it's going to instantiate them under the uh scroll list that we set up on the left hand side and then it should initialize the shop slot with the item so let's see if that actually works so let's hit play and before we do that we need to set up some stuff obviously uh I always forget to do that let's go to our prefabs we've got our shopping list item UI and you can see that we've now got all of these um fields that we need to fill in so drag in the item Sprite item name item count we don't need to do anything with the assigned item slot but we can drag in the add item to cart Button as well as the remove from cart button okay so hopefully we've not missed something we probably have let's hit play and just see what happens and see in which way it breaks so let's go over here so this is is one of our NPCs we can open it oh and there you go I'm surprised that worked first time we've got our cogs which are worth 1G our health potions which cost 100 G and our sword items which he's got one of they cost 100 G as well um currently I've got no way to close the panel uh which is a bit of a an oversight so let's uh come out and go back in here this has got our sword they've got 10 of them at the sword shop and then we can come over here we can access the potion shop and we've got the poison potion and health potion and okay I know this was a bit of a shorter video but I'm going to leave this one here because in the next video we're going to set up the actual shopping cart system and there's a lot of quite like dense kind of stuff we need to do uh involving kind of like the marking up of the items um so I'd rather do that in its own separate video to try and keep that one concise but hopefully you liked this video uh all of the kind of series doing this shop system is already available over on patreon.com along with the project files so if you don't want to wait a week for the next part feel free to head over to the patreon and if you support me there you'll get access to the videos kind of early cuz they're they're all done and filmed I'd just like to take a minute to thank all of my patrons on screen now we can see the 10,000 XP tier which is uh sector sweep and I want to thank all of the 4,000 XP tier members as well if you need any help with this video or any of the other videos in this series leave a comment below or head over to the Discord server where you should be able to get an answer from me there and in the meantime thanks for watching and I'll see you in the next one [Music] bye in today's video we're going to be carrying on with our shop system that we've been working on you can see over here we can go to our NPC here we can see the players got 500 gold and the shop has 1,000 gold and we've got cogs we've got 99 cogs uh 150 Health po uh sorry 10 health potions there are 150g and there's one item which is 150g if we then click on these buttons here we can add to our basket total we can remove from our basket and you can see that it's updating here if we add too many items to the uh basket that we can't afford so if we go over the player's gold the player's 500 gold the basket totals 610 gold we can't afford them if we hit the buy button nothing's happening so let's just remove um the potions from the basket total so now we've got five cogs three health potions and then we hit buy items you can see that we've bought the items the amount that we had in our baskets gone into the shop gold and it's been taken away from the players gold and then if I shut this panel you can see in our inventory we've got the cogs and Potions here I'd already picked up some potions from the floor let's just drop them on the ground um let's drop the cogs on the ground let's go over here press e so let's uh buy some more cogs I'll buy seven cogs close our inventory and you can see that we've got seven cogs in our inventory now and we've got our four potions which we bought earlier but that's what we're going to do in this video Let's just jump straight into it okay let's just jump straight into this one then so we're going to work on adding the functionality to add and remove things uh to the shopping cart so the first thing we want to do is we need to introduce a variable that's going to keep track of like the temporary count we don't want to actually change the underlying uh shop slot what we want to do is have a private int which we will call temp oh temp amount and then then when we set up the shop slot UI and we assign everything here we're going to set the temp amount equal to the slot. uh stack size so now we can change we can add and remove stuff to the car but if we exit out of the interface we're not going to have actually changed the Shop's uh inventory we're not going to have removed anything from the Shop's slots until we actually press the buy button once we press the buy button then will actually take it from the stack size so we're just creating this temporary amount to keep track of that so let's work on adding stuff to the cart first so with add item to cart we want to just check to make sure that there is actually an item to add to the cart so if our temp amount is greater than zero then we're going to remove an item from the temp amount because it's going into the cart we're going to call our parent display and we're going to um add item to cart and we're just going to pass in ourselves as this and we can make that function there over on the shopkeeper display script we're going to have a add item to cart which takes in a shop slot UI um variable and we'll go back to our shops slot UI script and then we're just going to update the um item . text is going to be equal to our temp amount. 2 string I'm going to invert that if so if it's less than or equal to zero then we're just going to return and if not then we can reduce uh one from the amount add it to the cart and then update the UI slot text and then for the remove item from cart we're just going to do the opposite so if temp amount is equal to the assigned item slot. stack size then let's just return because there's nothing to we have because if the temp amounts the same then there's nothing in the cart so we we don't need to manipulate it in any way so we can just remove um and the remove item button won't work it won't do anything um but if the temp amount is different to the actual amount of the shop slot then we're just going to uh increase our temporary amount we're going to call parent display remove item from cart again passing in ourselves and then we're going to update the item count. text to the temp amount. two string and again let's make this method over on our shopkeeper display so it's going to be remove item from cart taking in a shop slot and that's on the shopkeeper display script and for now I'm just going to remove these uh system exceptions okay so if we go back over to Unity and we hit play Let's go over to one of our shops so you see that there's 99 Hogs 10 health potions and one sword item if we hit the plus this is going to start adding stuff to the car and removing from the temporary amount if we actually check the MPC we haven't changed the shop inventory we're not going to do that until we actually press buy because there's no guarantee that the player would complete the purchase they could press escape and close this panel and then go back to it and that we need the shop to have been reset so we don't want to actually change the shop inventory until we've hit the buy button which is going to be over here and you can see that we can remove um items from the car and we can go back up to the original stack size but we can't remove items that we don't have so we can't go up to 100 cogs and you know we can do this all the way down to zero and we can't add any more than the shop inventory currently has so now we need to actually change add them to the car which is going to be this window over here let's go do that so let's go back over to our editor and this is where it's going to be quite confusing hopefully you'll follow along um I'll try and explain everything as I go so we're going to get a reference to the data from the shop slot UI and we'll get the um assigned we're we're going to need to go through to the shop slot UI and we need to make a public getter for this um shop slot so we're going to make a public shop slot called assigned item slot which will return our assigned item slot and now back over on our shopkeeper display we can get the assigned item slots item data we can just cache that in this uh variable which we're going to call data and then um here we will update the item preview passing in our shop slot UI again this is going to be another method we're not going to we'll work on this later but this is going to be where it shows the name and the description and the thumbnail um but we'll do that okay so we're now going to use this uh shopping cart dictionary that we made which remember takes in um an item data and an INT so so here we're going to say if our shopping cart dot uh contains key data so if our shopping cart already has this data in it um and how do I stop that so if we already have the data in it so if the if this item is already in our shopping cart then we are going to add to the shopping cart one so if the shopping cart already has it and we're adding an item to the cart we're just going to increase the in in the dictionary by one meaning that there's going to be one more of that data in the cart and then this is where the markups going to start to come in um the shop markup so we're going to do um make a new variable called price and this is going to equal and I'm going to make a new method called um get modified price because this is going to we're going to use this in a few different places so we're going to pass in the shop slot so so to this we're going to add in the data going to add in an amount which is just going to be one in this case and then we'll do shops slot UI do uh markup so this is going to be the markup value and let's make this method so this is going to be a private static int again called modified price which is going to take in um some data and amount as well as the markup here and all this is going to do is we're going to get the base value so base value is equal to the data dot val gold value Times by our amount so remember this gold value here is what we Define as the the value of the item so if the gold value is 100 and we pass in two of the amount the base value before we change it with the markup is going to be 200 once we've calculated the base value we can just return the math f. round 2 int and we can do the base Value Plus the base value Times by the markup let's just see that math kind of in action so so if we take our base value of um 100 and we have one of them so the base value is going to be 100 and then we have a markup of 50% which is going to be 0.5 so 50% of 100 is 50 and then we're going to add that to the base value so we're going to do the base value Times by the markup that'll be done first and then it'll be added to the base value so that would be it would be 50 plus 100 is 150 so that's the markup and that'll work for sort of you know any so if we do a base value of um 75 there's a markup of 30% and then we add 75 back to that the price is going to be 97.5 and the reason we're rounding it to an INT is that obviously the price the gold amount is an INT we don't want 0.5 gold um so we're just going to round that up so that's how we're going to get our modified price once we've got this price we can then make a new variable called new string and we'll equal this to string that's got the shop slot it's got the data. display name and then I'm going to put the price in Brackets so we'll do um price with a G so that's how much gold there's going to be and then we'll pass in from our dictionary the amount of that data that we have so shopping cart at um data so that's going to be the value so that's going to be the int so it's going to be display name with the markup so you know a cog for 100 gold and it'll show that we've got 10 of them in the basket for example and then remember we've also got the other dictionary which is this shop the one with the shoing cart item UI in it which will correspond to this uh bit of data here so we can go to our shopping cart text shopping cart UI dictionary I'm going to get the value the value with the key of our data and we're going to set item text we're going to pass in our new string now again this is another method we need to make so let's create that method so this is over on our shopping cart item UI which we've not fully set up any of the variables yet so let's do that now so all this is going to have is a serialized field private text mesh Pro UGI and we'll call this item text and then all we're going to do here is set item text. text equal to our new string and let's actually set up this prefab um in unity so let's go back over to Unity and we've got our shopping cart item prefab here with the shop and cart item UI script so we're just going to get the script and drag the text into the serialized field of the item text we'll go back to our main scene here so that's the shopping cart item UI script let's jump back over to our shopkeeper display script and here we're going to increase the basket total by the price so this is the current cost of the basket so basket total plus equals the price and then we can set the basket total text to display that price so we can say total and then pass in our basket total and that's the amount of gold that the basket is currently going to cost so this is if our shopping cart already contains the key so this is our shopping cart this is if our shopping C already contains the data that we're trying to add if it isn't then we're going to need to add to the dictionary and then do some of this stuff so we can say else shoing cart do add we can pass in the data and the amount so it's going to be one in this case then we're going to instantiate a new shopping cart text object and I'm going to get a reference to this so we can modify it so we can instantiate and we're going to do the shopping cart shopping cart item prefab and that's going to be attached to our shopping cart content panel um transform we're going to get the price um and I'm actually going to just copy that and I'll pop it outside of of the um item cart I'll pop it out outside of this if statement and then we can just use the price down here um and we could actually do that with new string as well here and we want to set our shopping cart text obj we can do set item text passing in our new string and we want to add this shopping cart text obj to our dictionary that contains the text so um shoing cart UI dictionary do add and we'll pass in the shopping cart text obj and that says the value we need to pass in the data as the key and then after that we can update the basket total so again I'm just going to cut that out and I'm going to place place it at the bottom here so that's just cleared this script up and made it a bit easier in my test project I I seem to have a lot of duplicate code hopefully this will work um so then once the basket total is um calculated we can say if the basket total is greater than zero and the basket total text isn't active then we just want to enable the basket total text and we can say um enabled equals true and then we can set the buy button to be true uh to be enabled as well so game object do set active true and then finally we're going to have a new another method called check part verse available gold and we'll press we'll make that method here so this is going to be a private void check C against available gold and here we're going to do um a new variable gold to check and here we want to see whether we're selling an item or buying an item so to do that we need to introduce a variable that's keeping track of which kind of buy mode what we're in are we in selling mode or buy mode so we can just make a new Bull and I'll move this to the top in a second I'm just going to put it here for now um private bull is selling and we can say are we selling if we are selling an item then we're checking the shop system do available gold and if we're not selling we need to check the player's gold so uh we can do player inventory holder do inventory system gold again we've got those tabs that we set up the buy and sell button if we're buying when we add things from the shop system to the cart and then we try and buy it we need to make sure the player has enough money and then if we are selling items to the shop we're going to add items from the player inventory to the shopping cart and then when we click the sell button we need to check to see if the shop has enough gold to buy all of that so that's what this is doing here um and we'll use this bull a bit later on by default this is going to be false until we set up the tabs so this is going to be checking the players inventory um for their gold amount and here we're going to update the basket total text. color and we're going to set that either to um white or red depending on whether the player has enough money just as a bit of an indication that you've gone over the sort of the basket amount that you've gone over the amount that the player can actually afford to buy so we can set the color based on this um the basket total is the basket total greater than the amount of gold that we that we currently have available to us if it is greater then we're going to set the color of the text to red and this could be sort of any color that you want that fits your style and if we're if we do have enough we're just going to set it to White and obviously if it's already white it won't change um so that's that for now we'll be doing uh a bit more in this method later on um when we set up the selling mode but let's just focus on getting uh buying items to work for now okay so then we need to check as well um as well as the available gold we need to check to make sure the player inventory has enough space in it to buy the um to buy these items and if they don't we can update the basket total text to say something like not enough room in inventory so let's make an if statement here so if we are selling items to the shop then we can just return because we're not going to um so if we're selling items to the shop then we don't care about this step of you know checking uh the inventory so we're going to do if we're selling or the player inventory holder. primary inventory system and then we're going to make a new method called check inventory remaining and we're going to pass in our shoping cart dictionary so this is going to be a method over on our inventory system script and it's just going to return a ball and we're going to do some stuff to check whether we have enough room in our inventory for the um shopping cart to fit so to make this work we're going to make a clone of the current inventory system the players inventory and then we're going to attempt to add all of the items from the dictionary to that cloned inventory system if we get an error saying that the inventory system is full and we we failed to add it then we're just going to return false and if we successfully get through that check of on the Clon system will return true because there's obviously enough room in the inventory to add all of this stuff to the players inventory so that if that doesn't make sense hopefully it'll make more sense as we start to clone uh to code it I'm going to make a variable called cloned system and this is going to be equal to a new inventory system and it's going to be of the same size as our current inventory size and then to this cloned system we need to go into a for Loop and add all of our current items to the cloned system so we can say uh for in I whilst I is less than our inventory size i++ and then we're going to get our clone system get its uh inventory get its inventory slots at position I and we're going to assign the item that corresponds to our inventory's um inventory size so we can say uh this. inventory slots I do data and this. inventory I sorry inventory slots stack size I'm just going to make that go onto a new line so we can see that so we've got a clone system and to every inventory slot we're going to add the corresponding slot on on this on the players inventory to this clone system so this is the actual cloning of the players inventory inventory so now we need to go into a for each Loop and I'm going to say for each um I'm going to call this kvp for key value pair in our shopping cart dictionary we're going to add one by one the items to the player's inventory so we're going to go into a four Loop now so 4 in I whilst I is less than our P value pair. value so remember this shopping cart takes in data and an amount of that data so we' we've got Cog is the data and the player is trying to buy 30 cogs from the shop we're going to go through each of those 30 cogs and try to add them to the players's cloned inventory so if cloned system do add to inventory we're going to pass in the data key and in this case and the amount which is just one cuz we're adding them in one by one I'm going to return false so if we fail to add this to the inventory system then we're going to return false and just as a refresher add to inventor this public bull method here and this will return false if we don't have a free slot so if it gets to here and we can't successfully add it to the inventory system we're going to return false so if we get to this point and we can't add any more stuff to the Clone system we'll break out of the loop we'll just return false and then that'll say that the the player doesn't have enough inventory to fit the shopping cart in it and if it successfully Loops through all of this and completes this uh method then we can just return true we clearly do have enough uh inventory space remaining so then we can go to back to our shopkeeper display and now this should work so if we're selling so if we're selling or the player has enough inventory space then we're just going to return but if neither of them are met then we're just going to set the basket total text. text to read not enough room in inventory and then we can set the basket total text. color equal to color. Red ah and there was a bit of an error there um that was my mistake the price can stay outside of this if statement but the string can't because we're trying to access the um shopping cart we're trying to access uh the value which is at the shopping cart dictionary but we don't know if it's there yet until we get to this if statement so let's just cut new string and paste it back into our um if statement and we'll do it twice and if this is the first one to be added to the shopping cart dictionary then we can just say uh X1 cuz there's one item in the dictionary and here we know that we contain the key so then we can actually access the key here so that should work so let's go over to un and make sure that we've what we've just done is actually all set up and working let's hit play and we'll come over to this um MPC here we'll press e and let's try and add some cogs to our inventory and you can see here that as we add them the player doesn't have enough gold so it's the total has gone red to kind of indicate that we don't we can't afford it that's adding stuff to the basket currently we don't we can't get any back out of the basket but you can see that's working um and we actually need to use this modified price up here when we add stuff to the display so let's just add that quickly so to do that we're going to go up to the um display shop inventory method here and we're going to jump into this init function on our shop slot UI script and here instead of setting it directly to the assigned item slots um gold value we can actually get the modified price uh from our shopkeeper display so let's do shopkeeper display and we made this static method so we can we don't need to reference our parent we can just do shopkeeper display get modified price and I've just realized that we need to make this public so public static in not private so that should work here um and I'm just going to put this up here so we'll do um we'll make a new variable so variable uh modified price is equal and then we're going to get the modified price so remember this takes in um some data so we can do the assigned item slot. item data it takes in the amount of the item which we just want um one for now uh we're just going to show kind of how much one costs and then we can pass in our markup so then here in the text we can just pop in our modified price instead of um the sort of Base value so that should be that so now we've got the cart set up and working we want to be able to actually buy the items when we hit the buy button we want to buy the car and add it to the player inventory and take the from the player so let's do that and I'm going to I'm going to move this B up to the top just to try and keep everything sort of up here so private B is selling and here in refresh display just before we click uh just before we do clear slots let's get um let's do some stuff with the buy button to set it up so we can actually buy the basket so if we'll say if our buy button is not equal to null then we're going to set the the buy button text. text equal to and then here we're going to use the is selling bull again so are we selling an item or we buying an item so will we selling our items to the shop or we buying items from the shop so we can say is selling if we are selling it'll be sell items the button will say and if we're not selling uh we'll do buy items and maybe this should be renamed to to like the use cart button instead of the buy button I'm just going to leave it called buy button for now um then I'm going to get our buy button and I'm going to remove all of the listeners from the onclick event and then we're going to check if we're selling so is selling if we are selling we're going to add the add a listener to the onclick button and this is going to be a cell items method that we're going to make and then we'll do else buy button do onclick do add listener buy items I'm going to make a method called buy items so every time we refresh to the display we're going to change what the buy button is doing which is this button here we're going to change what this button does and says based on whether which tab we've clicked up here um so let's make these methods so we've got a private void sell items and we'll make a private void buy items method um we're not going to focus on selling stuff at the minute I'm this video is already getting on quite long I just want to focus on being able to buy the items and add them to the player inventory so let's allow the player to actually buy their basket and add it to their inventory so we're going to say if the layer inventory holder. primary R system. gold is less than the basket total then we're just going to return the buy button doesn't need to do anything uh we could just disable the buy button based on this if we wanted but I'm going to leave the button there um so the player could click it but nothing will happen if they don't have enough gold for the basket and then we want to check if the player inventory holder do primary inventory system dot check inventory remaining shopping cart so we're going to see if the player doesn't have enough space for all of the items in the basket then we're just going to return and maybe this would be a bit more performant if we used it as a bull if we keep kind of a reference to the result of that here so we're only doing it once um I mean that's up to you if you want to do that I'm just going to leave it like this for now um again I don't want to get I don't want it to get too bogged down with extra stuff um and then we're going to say for each AVP in our shopping cart we're going to purchase the item from the shop so shop system do purchase item which again is a new method we're going to need to make which takes in a key and an amount so let's make that method over on our shop system script we're going to make this purchase item method and all this is going to do is um I'm going to check whether we actually contain the item which this is just a fail safe we should we should have the item in our inventory in we should have the item in our inventory anyway because we've you know we've added it to the basket from our inventory but this is just you know another sort of catch all just to make sure that you know nothing's gone wrong anywhere we don't actually have the item for sale and then we're just going to remove from the slot and the other thing it does is it gives us the slot back so so if this is true we still get this slot and we can just say if we can just say slot. remove from stack and pass in the uh amount which is what I'm going to call this so um amount I'm going to rename that to data instead of a new inventory item data just going to pass in data so if we have the item in our inventory we're going to add this amount to so if we have the item in our Shop's inventory we're going to remove that amount from the stack and if we don't we'll just return um because you know like I said we don't want to let the player buy something that the shop doesn't have so back over to shopkeeper display so we're going to buy the item from the shop we're going to add now the item to the player's inventory so we can say for in I whilst I is less than the key value perir i++ and then we're just going to add the item to the player's inventory so play inventory system do add to inventory p vp. key and one because we're going through one by one and we're adding them all to the shop and then we're going to um add the basket total to the shop so the shop system is going to gain gold passing in the basket total and the player inventory holder. primary inventory system is going to spend some gold basket total so let's make this gain gold method first back over on the shop system screen R and this is quite simple we're just going to do available gold minus equals uh plus equals the basket total and then let's make the spend gold method over in our inventory system so spend gold and that's simply just going to minus from our gold the basket total and then back on our shop uh shopkeeper display once we've done all of that we just need to refresh the display again because obviously stock has changed so we can reflect the UI to handle that so let's go over to our project let's give our player some money give him a Payday so we've got gold here let's set this to um let's make him Rich let's give him 5,000 gold actually no I want to show it working um to show that the player doesn't have enough gold for something so we're going to do gold 500 and let's go to our shop let's go to our item scripts into the database and the item data and let's make something more expensive so what have we got so swords 100 gold value 10 100 okay and one so that's that's fine they're good values so if we press play and we go over to our shopkeeper and we've now got our inventory system here now got our shop system display here we can add cogs to the basket and the player gold didn't update let's fix that okay the reason that didn't work is when we create the inventory system here we set the size to uh if we don't pass in the gold it'll just reset it to zero so even though it's um even though we put it in ahead of time the inventory holder is kind of overwriting that so what we need is we just need a uh serialized field and we can do a protect uh in gold and then when we create our inventory system on the inventory holder we can just pass in that gold amount and the good thing about this is because we're doing it on the inventory holder not the player inventory chests could have a gold amount as well um if you know you've got enemies and they have Loot on them they're going to have an inventory system you can give them gold for the player to get from the um the enemies and stuff um that should be fine let's go back over and try this out now so so it's not the inventory system gold it's this gold that we need to change so we'll do 500 gold here and let's press play and if we go back over to our shop so we can now see the players got 500 gold let's add some cogs over and you see that these uh are reacting now with the markup value so the health potions and the sword are 15 50 gold even though the base value was 100 we can add um these into the basket and then let's get some health potions as well you see that we can't afford all of the health potions so let's and I've forgotten that we've not actually set up removing items from the car as well we may as well get that done now um it'll extend the video just a little bit but not too much um let's go back over to our shopkeeper display and here we have have um do we have a remove item from cart method yet remove item from cart yeah let's move this up above um add item to cart just so we can go there okay so this is very similar to the add item to cart but we're kind of doing it in reverse so we're going to get our data so VAR data is equal to shops slot UI dot uh assigned item slot do item data and then we're going to check does the shopping cart contain data already if it does we're going to reduce the value from we're going to reduce the amount that the C holds by one we're going to get the modified price so we just going to copy this underneath data here we're going to copy the new string as well and in fact let's just copy all of this so going to copy the new string in the shopping cart UI at the data and if we reduce the amount of the item in the cart to Z so if shopping cart data shopping cart data is less than or equal to Z then we're going to call shopping cart remove RP because it's no longer in the cart we're going to get a reference to the game object of our shopping cart text so equal to shopping cart UI data. game object we're going to remove the shoing cart UI from the shoing UI dictionary so shopping cart UI do remove the data key and then we're going to destroy our temp obj so here we instantiate it when we add it to the cart and then when we remove it completely from the cart we're going to destroy it and then we're going to say that if the basket total is less than or then we need to modify the basket total so we can do um basket total minus equals the price we can update the basket total text to reflect the new um total amount so total basket total G and then we're going to say if the basket total is less than or equal to zero and the basket total text is active then we're just going to hide the text so basket total text do enabled is equal to false we'll hide the buy button so buy button. game object do set active do false we're going to clear the item preview which is we've not implemented the item preview section yet we'll do that in the next video but let's make that method now ahead of that and then finally we're going to check the C ver available gold and we only need to do that if we haven't just uh set it to active so let's just return here if the Bas if there's nothing left in the basket let's return cuz there's nothing left in the shopping cart so we don't need to check it against available gold so hopefully you followed along with that because it is just the kind of the reverse of what we're doing down here let's go back over to Unity and hopefully oh wait let's just check one more thing sorry we need to go over to the shop slot UI go to our remove item from cart um method on the shop slot UI um and okay we've already set that up so that's fine I just wanted to check that so let's go back over to Unity hit play over to our shop C uh our shop MP see here let's add some cogs let's try and remove them okay so you can see that we can now add and remove things from our basket let's add in you know some potions okay we can't afford that many potions we can afford this many we'll hit buy that buys the items it adds the amount to the Shop's gold it decreases the player's gold and now if we go back which I've just realized we still can't close the shop panel let me just manually close that shop controls UI okay so you know we can see that we've got the four cogs and three potions in the players inventory so I know that was very very longwinded and I apologize um hopefully you follow along with it if you want the project files for this video they are available over on patreon.com dmos I'd just like to take a minute to thank all of my patrons on screen now we can see the 10,000 XP tier which is a sector sweep and I want to thank all of the 4,000 XP tier members as well if you want any help with this video or any of the other videos on my channel feel free to leave a comment below or better yet join the Discord server which is linked in the description but for now thanks for watching and I'll catch you in the next one bye hello and welcome to today's [Music] video hello and welcome to episode 16 of our inventory tutorial series as well as episode five of the shop system Series so by the end of the this video we're going to be able to pick up all of our items off the ground we're going to be able to come over to this shop which doesn't currently have any poison potions so we can sell them a poison potion so we sell items and you can see that as we click these items it updates the um item preview panel that we've got here we going to click sell items and sell a poison potion to the shop the shop now has a poison potion in stock I'm going to come over here to the poison to the potion shop shop and let's sell them one of my swords and they've got a sword in their inventory I can come over here and we'll put some items in that chest put some cogs in this chest and maybe let's store our sword as well let's save our game come out let's go back in we can now load the game all of those items will disappear cuz we've already picked them up we've got our cogs and our sword in this chest got our potions in this chest let's make a new stack because we can why not you see that you can see that the sword item has been stored in the shop we can check over here and this has got the poison potion in stock that we sold them so we've got the shops saving and loading as well as remembering their gold and the player gold uh all of that is saving quite nicely that's where we're going to be by the end of this video so let's just jump straight into it okay so let's crack on with uh getting the item preview working and being able to sell items from the player inventory to the shop so let's go over to our inventory system script here and we're going to start by displaying the player inventory based on the tabs at the top so in our refresh um item display in our shopkeeper display class we've got this thing here um and currently we're just saying display player inventory actually what we want to do is we want to say if is sell in then we want to display the player inventory else we want to display the shop inventory uh display layer inventory let's cut this put that there let's go R of them okay so let's check let's start to build this display player invent inventory method so what we need to do here is we need to Loop through all of the items in the player's inventry and then display them in the list on the left hand side of the shop so for that we're just going to do a for each Loop and we're going to go through every item in the player inventory holder primary inventory system and then we're going to make a method called get all items held which is going to return a dictionary of items that the player holds so let's create this method this is over on the inventory system. CS script and it's currently public I enumerable and I'm going to make it a dictionary of inventory item data as well as uh an amount of that this is going to be a uh a dictionary made up of distinct items that the player has cuz currently the player's inventory is organized into slots and those slots can have mul the same item in them and multiple amounts because of the stack splitting and stack assigning and stuff so what we need is we need an organized list of um how many cogs does the player have we don't care about what Stacks they're in just how many cogs are in the player's inventory so that's what this is going to do here so we're going to make a new dictionary called distinct items and this is going to be a dictionary of uh inventory item data and an INT and this is what we're going to return at the end of this method and here we're going to Loop through all of the items in the players's inventory so we'll do for each um item in our inventory slots if the inventory slots um if the item. data is equal to null then we don't have an item in that slot it's empty so we can just continue which will skip to the next item in the loop if it's not null then we can check this dictionary to see whether we've already put the item in it um so we want to say if distinct items doesn't contain key our item. data which you know the first time this goes around it won't um so if distinct item. contains key item data then let's add it let's add the data to the dictionary so item. data and the int is going to be how many of that item we have so stack size and we can say else so here we're checking if it doesn't contain the key then let's add it to the dictionary and if it does contain contain the key let's just increase the amount of the item that we've got so we can say else distinct items using the data as the key and then we can plus equal item do stack size and then finally we can just return our distinct items dictionary here so now we have a dictionary that's organized by inventry item data and the amount of that that we've got and that's looped through all of our slots so now we're going to make a variable called temp slot and this is going to be equal to a new shop slot CU obviously the other shop slots in the display shop inventory are coming are being driven by the Shop's inventory list the script object here we're doing it from the players inventory so we're going to make a new temporary slot to that slot we're going to assign item and it's going to be our item. key and item. value from this dictionary That We're looping through and then we're going to instantiate a a shop slot so shop slot equal to instantiate shop slot prefab on the item list content panel at the transform and then we're going to initialize that slot by passing in our temp slot as well as the shop system and this is going to be the cell markup so here we can offer the player more or less for items based on the shop cell markup um and that's it for displaying the player inventory everything else should work kind of fine with it but the one thing we do need to do is we need to set up the tabs that change mode that change kind of you know whether we're buying items or selling items so to do that we're going to make two methods here we're going to do a public void on by tab pressed and a public void on sell tab PR and we're going to say is selling is equal to true if we've clicked the sell Tab and then we can refresh our display and if the Buy Tab is pressed then we're just going to set is selling to false and again refresh the display and while we're here we've got this update item preview method that we made but never implemented let's just Implement that um just so we can kind of get everything tied up in this video so we'll do uh variable data is equal to the shop slot UI do assigned item slot. item data and then we're going to set our item preview Sprite to the data sprite. Sprite equal to the data. icon we're going to set the Sprite color equal to color. White we can update the item preview name. text to equal the data. display name and and the item preview description do TT is equal to the data do description and I'm just going to copy these copy I'm going to go to our clear item preview um function that we made method I'm just going to paste them in and then here we can set the Sprite to null we can make it invisible we can set the text to an empty string and we can set the data uh the description sorry to a empty string as well and now we can copy the clear item preview method and when we display the shop window and we call refresh display as as clearing the slots let's clear the item preview as well so let's just check that that is all working see where we're up to with that so let's pick up some items here we've got um poison potion health potion some cogs and two swords so let's go over to to this shop here so we're currently in buy mode if we click the sell tab oh sorry nothing will happen because we need to hook up those buttons the tabs don't actually do anything so we'll go to buy button we'll get this onclick event we'll drag in our shop controller shopkeeper display on Buy Tab pressed and then with the sell button again drag in the shop UI controller shopkeeper display on cell tab pressed so again let's make sure we pick up some items so we'll come over here look up all these we'll go over here let's press e to bring up the shop window and let's click the cell Tab and we can see here now this is the player inventory you see this shop is actually offering us more for the potions than um they're actually worth which is quite good but it is selling them for 150g and we can add these to the basket here you can see that the Shop's got 1,000 gold if we go over um the th000 gold Mark don't know if we'll be able to I don't think there's enough stuff to go over the th gold Mark I mean there isn't because we've got shop gold because we didn't pick up enough stuff there wasn't enough stuff in the world but that's now adding it to the players um to the shopping cart so now when we click the sell item button we need to be able to sell the items like we can buy items from the shop so let's go back over to our script and we've got private void sell items on our shopkeeper display so here we're going to do similar to sort of the buy items we're going to say if the shop system. available gold is less than the basket total and let's just return because we don't want to continue we don't want to sell anything to the shop but if the shop does have enough gold to buy all of the players items we're going to Loop through with a for each Loop going to Loop through every item in the shopping cart and then we're going to get our shop system and we're going to make a new method called sell item and there we're going to pass in the key value pair ke as well as the kvp do value and we'll make that method in just a second and then I'm going to do uh variable price is equal to get modified price kvp dokey kvp Dov value shop system do cell markup and the reason we're not doing this in here is because we need to use the price to reduce the gold from the shop and increase the gold on the player's inventory what we could do is pass the price through to sell item actually let's do that that might make a little bit more sense so let's do that so we're going to calculate the price we'll pass in the price to this sell item method and then we can do player inventory holder primary inventory system do gain gold which will take in the price let's make this method in a second over on the player inventory and then we'll do player inventory holder. primary inventory system and then we'll remove items from inventory and we're going to remove the key value pair do key that's the the item that we're going to remove and how many of the item we are going to remove so let's make this sell item method first so this is over on our shops system. CS script and all this is going to do is it's going to add to shop and it's going to add a the key VP key and the kvp value to the shop and then we can just call game gold and we can pass through the price so now let's make these two methods on our inventory system so I'm going to implement gain gold and Implement remove items from inventory so gain gold is just going to do available uh do gold plus equals price nice and simple now for the remove items from inventory let's get rid of that I'm rename that to data and um amount just to keep so that's what I've named kind of all of the other inventory kind of add in variables uh makes sense so we're going to say if contains item data and we're going to get back out a list of inventory slots called in slot we're going to get out our list of inventory slots from our contains item method and then we're going to see for each slot in our inventory slot list we're going to get the stack size so VAR stack size and set that equal to slot. stack size and then we can say if stack size is greater than the amount that we're trying to remove from our inventory then we can call slot. remove from stack and we can just remove the amount from that one slot if however we have but for example if a was greater than stack size then we need to go to the next slot in our list and remove it from that so we can say else slot. remove from stack stack size and then from amount that we've passed in we can minus equal the stack size then it'll go around again to the next slot that has the item in it and it'll remove the next from that stack size until it's been through them all um and we need to also once the slot has been modified we need to call on inventory slot changed and invoke that method or that action and pass in the slot and we just need to add to this remove from stack function so we want to say here if stack size is less than or equal to zero then let's clear the slot because at that point you know it's all gone we don't need to um obviously at that point we don't want to go into Min us we just want to clear the slot out once we've got to zero we can just make it an empty slot let's go back to shopkeeper display so we've got sell items here and then we just need to call refresh display so let's see if that is working so let's press play going to come over here let's pick up these items and we can come over here we can press uh e bring up our shop window go over to the sell Tab and let's sell two potions to the shop so we should see the player gold will increase by 250 and the shop gold will reduce by 250 so let's hit sell items and we've made a little mistake um instead of gain gold we need to uh reduce gold which isn't a method that we've made so reduce gold okay so this this is where this gets a little bit confusing we're the way I've named all this is from the players perspective so sell item we're a shop so that can be a bit confusing are we selling the item to the player or is the player selling an item to the shop system I've gone from the point of view of the player cuz it's the player that's doing kind of the axe in the world so when we sell an item and call this we're selling the player is selling an item to the shop so it's going to add to the shop and then we need to reduce the Shop's gold amount so let's hit play and just make sure that works as planned so let's go pick up all of this stuff press e sell two of our other let's buy uh let's go over to our sell tab so let's sell two health potions and we can see here that the description the item preview it shows the last item that we clicked so if we try and add a cog to the basket it'll display this is a cog um we can remove that Cog from the basket and then let's sell our items so now you can see the player gold increased by 250 and the shop gold reduced by 750 and then if we go back over to the Buy Tab we can see now that the health potions have been added to the bottom of the list and we've got a bit of an issue here so you can see that it's added them to the shop but it's also added them at the bottom of the list there so let's just figure out what's going on there let me just sell those items to the shop go to the Buy Tab okay so there's a little bit of a bug there it is adding it to the shop but we're getting this um these additional items as well which we don't obviously want so let's figure out what's going on there okay so the problem was uh we just need to return so when we on the shop system script we've got our add to shop function once we've added it to the stack we needed to call return so what was happening is we were adding it to the stack and then we were also assigning it to a free slot so if we just put return in our add to shop function on the shop system script that should solve that issue that we were having let's just confirm that let's pick up some items let go over here go to the sell tab we'll sell the items to the shop so there's three cogs we can hit the sell button the store sold the money go back over to the Buy Tab and now we can see that the cogs have increased the health potions increased but we've not actually got in the bottom um that issue that we will Happ so and then we can buy items from the shop so we're going to spend 610 of the player gold and increase the shop Gold by 610 so let's buy and then we can go over to the sell Tab and now we can see we've got our four health potions and five cogs and we'll sell the cogs back you see there's a bit of an issue there the rounding seems to be having a bit of a problem let's figure out why that was okay so that was a quick change all we needed to do um in our get modified price it was rounding up we just needed it to round down so instead of round to in I've put floor to int and that's on the shopkeeper display so that's what that issue was there um so one of the kind of other things that we want to do um is be able to save and load our shop system um to kind of reflect that we've you know the shop has gained and lost stuff and the place that we do that is over on our shopkeeper docs script so over on our shopkeeper script script just like we've done with our other um save and load items what we want to do is in awake um we're going to install a reference to our ID so let's do private string ID and then here we'll say in awake ID equals uh get component unique ID and let's get the ID of the MPC and then we're going to make some shop save data so out side of our class we'll do public class shop save data and we could do system. serializable for our shop save data and this is just going to hold a public shop system uh reference in it which I'll call shop system this could take in a position and a rotation if you wanted so for example if the shopkeeper kind of wandered around you could save that data um I'm just going to keep it basic though so we'll do I'm just going to store the shop system for now but just so you know you can store other stuff in this like whatever you care about for your shop um and I'm just going to say public shop save data this is the Constructor and it's just going to take in a shop system which I'll call shop system and you guessed it we'll do shop system equals shop system so back up to awake we're going to get the ID here um and then that we can say shop save data which we're going to keep a reference to so private shop save data called shop save data a shop save data is equal to new shop save data passing in our shop system in a start method so private start we're going to make a new dictionary on our save game manager um just like we did with the chests they're all stored in a dictionary if you think about it the NPCs are kind of like chests but slightly different so we can do if save game manager. data we'll do dot um and then we're going to do shop keeper dictionary and then we'll check whether the dictionary contains the key of our ID so let's make this um shopkeeper dictionary over on our save game manager it's going to be save data this class so I'll do this underneath our CH uh our chest dictionary so I'll do public serializable dictionary taking in a string and um some shop save data and we'll call this the shopkeeper dictionary and then here we'll do shopkeeper dictionary is equal to a new serializable dictionary of string and Shop saave data so if it contains the ID Let's uh so if it doesn't already contain the ID we'll do save game manager dot data dot shopkeeper dictionary. add ID and Shop save data and I'm going to rename this to be consistent to just have an underscore and then in our on enable function we can say save load. onload game and we'll do load inventory which will be a new method that we make as well as on disable copy this paste in here and we'll unsubscribe from it and then we're going to make this load inventory method which takes in some save data which I'll just call data and here we'll say if the data do shop keep a dictionary and we'll try and get our ID out of the dictionary and if it does exist if the value is there um we're going to get out the shop save data which I'll just call shop save data and we'll return so so um if the shopkeeper dictionary doesn't have a reference to the current shopkeeper then we'll just return but if it does then we can say our shop save data is equal to shop save data which is this here and then we can say our shop system is equal to the shop save data. shop system so again this save and loading this way of doing save and loading is what we've done with the player inventory what we've done with the the chest inventory what we've with the stuff that's on the ground so that should hopefully all make sense to you if not maybe go back and watch the save data video again um that should work we may have an issue with the unique IDs so if I go over to our shop MPCs so I just I want to make sure that these IDs stay the same so 2D 93041 we'll hit play okay so that's staying the same there's no errors there from from console um I'm going to get rid of this debug dolog though so let's hit play Let's just check that this is working so going to go over pick up these items to our shop I'm going to it's got 99 cogs I'm going to buy let's say buy nine cogs we'll buy them from the shop we'll sell them a poison potion so sell items that's now there in the shop if I close the shop walk away go back so that's all working it's got n cogs one poison potion let's hit save so we can see saving game Let's exit come back in so it's reset to default let's load our game we can see that the stuff that we'd already picked up has gone we've got the cogs that we bought in our inventory and the poison potion is there and the cogs are all gone in the shop so that's the saving loading of the shop done um one thing I do really want to quickly do CU it's annoying me is on our UI manager that we made the UI controller in an update function I'm just going to say if keyboard. current. get UHC key was pressed this Frame then I want to set the shopkeeper display to false just so I can close the shop without having to keep uh actually selecting the game object so that's pretty much it for the shop system that's all done I don't think there's anything else we need to cover I thought maybe there'd be a couple more episodes left but there's only I think that's everything done unless there's something ridiculously glaring I may have to pop in from the future while editing this to say that that's the case but I mean that's all that's all working that's the shop inventory done we can close these shop Windows now with with the Escape key which makes it a lot easier got all of our items on the ground which we can pick up we can come over here we can put poison potion and some cogs in this chest in this chest we'll put a sword to this shop we will sell a sword we'll save our game we'll come back in we'll hit play we will load the game they'll all go got a sword in that chest poison potion and a cog in this chest and they've got one more sword than they had earlier so yep that's that's all working we got the save and loading um I hope this I hope this series was enjoyable and you kind of got it all if there's any big glaring issues that you need some like Clarity on um let me know in the comments or join the Discord server where I'll be able to help you a bit better um if there's like frequently asked questions then I'll probably do a follow-up video or maybe like a code review or something um but for now thanks for all your support from this series I'm going to take a little break from this inventory tutorial series while I just think up of kind of what I want to do next um I may do in a couple of weeks a crafting system so that was quite simple to set up so if you want to see how we can use items from our inventory to work in a crafting system do let me know what I may do though is do a bit more of a general crafting system video and I'll probably mention in that on how we could probably hook this into the system uh just to make it a bit more generic but for now thanks for watching and I'll see you in the next one bye I'd just like to take a minute to thank all of my patrons on screen now we can see the 10,000 XP tier which is a sector sweep and I want to thank all of the 4,000 XP tier members as [Music] well hello and welcome to today's video today's video is just going to be a little quick uh video hopefully quick uh showing how we can set up this uh hot bar system to be able to choose a slot and then for example if we uh left click we can use Whatever item that we've currently got highlighted on our hot bar so if I left click you can see down in the console we're saying using health potion but using Cog using poison potion and using sword item you see with the scroll wheel I can scroll kind of just infinitely through all of these slots and then I can also select individual slots with the number uh row on the keyboard so this isn't going to be a line by line tutorial like kind of follow along the project files are available obviously to download on the patreon uh account if you do want to download the code and just plug it straight into your inventory system uh you can obviously do that by downloading the patron files if this video ever ends up on YouTube cuz it's originally going to be a patron exclusive the URL for the patreon is linked in the description below if you're watching this on YouTube kind of in the future if I release this uh sort of down the line um but what I will be doing is I'll be walking through exactly what I've done and I'll be showing the code on screen and obviously feel free to pause and kind of copy it down if you want to do that or like I said just download the project files so let's just jump straight into it there's only going to be a couple of changes really to get this to work so I've made a hot bar display script so if we open up this I'll go through this kind of line by line you can see there's a lot of just Oiler plate code which I thought it' be quite boring to just type it out line by line so we've got our hot bar display class which inherits from our static inventory display previously our hot bar was just a static inventory display which is this class here that we set up uh way back when when we did the UI or the inventory system and that itself inherits from inventory display but we don't need to worry about this class we're not going to do anything there and all we're going to do on this class is we're going to swap our inventory slot UI variables over to protected instead of private so we can access it from our hot bar display class we're going to make sure our on enable and UND disable are protected virtual voids instead of private voids and that's it for the static inventory display class we're not going to um change any of the other functionality it's just making that protected and making these two protected virtual voids so if we now make a hot bar display script and have this inherit from our static inventory display class here we're going to keep track of Which slot on our hot bar we've got selected and this is going to be done uh via a int an index and I've set this as a private int we've got a Max index size which I defaulted to nine but we are setting it to the slots. length minus one cuz obviously arrays are zerob based so if you've got 10 inventory slots and you want to access the 10th slot we would actually want to be a index 9 to access that in the array and then this is a little bit butchered um over on our player movement code you can see here that we've got private player controls and we're making some new player controls and that's how we move our little bean around without getting too bugged down so we need some input on our hot bar display script and you can see we've got copied code here we've got private player controls player controls equals new player controls now what you'd probably want to do is not do it this way and have instead a separate uh input manager script but again that's his own separate video I'm just trying to do this the easiest way to show you the logic of this hot bar display script just like our player movement code where we're setting up new controls so we can access those controls we're doing the exact same thing here so we're making some new player controls in our protected override void on enabled and protected override void on disable we'll call in our base. on enable which is just going to do this and then we're going to do our own stuff so we're going to enable the player controls and then in our undisable we we're just going to disable them this just avoids any memory leaks now we can see this big kind of uh subscription to all of these events and then we're unsubscribing from them here so the way I've set up these input controls you see we've got hot bar one hot bar two through to 10 and then we've got use item as well and then we've also got uh a mouse wheel input here I go back over to Unity go over to our input control so here's our player input controls using the new input system up until now we've only had movement cuz we've just been moving been around we haven't really we haven't needed any of the controls you can see here I've got hot bar 1 through to 10 plus Mouse wheel plus item so 1 through 10 these are all of the same so it's just a action type of pass through and it's a button and one on the keyboard I've got an interaction of press only and then I've done this on every single one it's the exact same so hot bar 2 is number two on the keyboard with an interaction of press only and you can see all the way to 10 um 10 is actually zero on the sort of row of number keys on your keyboard obviously that's slot 10 which is after nine that's zero on the keyboard we have Mouse wheel which is pass through an axis and I've chosen for the path Mouse scroll Y and then use item again is a button for the left Mouse button and there's an interaction of press only there as well so so this is how you need to set up your input action asset with a key for every single row on the keyboard of the numbers from 1 to 10 or 1 to zero Mouse whe and use item and with that done we can go into our script and then we just just listing out for when the player presses a button so we've got hot bar 1. performed plus equals and then a method called hot bar one which just takes in an input action. callback context called OB and I've done that through one through 10 and then I've made um a method called use item as well and we're unsubscribing from them here and you can see that we've got hot bar one and then we've got a set index method which takes in an INT which I'll show you in just a second we've got set index in 0 1 2 3 4 5 and the reason these are offset so we're pressing number one on the keyboard and again the array is zerob based so if we press one on the keyboard we want to access the first slot in our slots array which is index zero because of because of the because they're zero based so it's a little bit you know Annoying that that's the case so we're setting when we press one on the keyboard we're going to set our index to zero to access access the first element in our slots array and we do that through hot bar 1 2 3 4 5 6 7 8 9 10 and obviously when we press zero on the keyboard we actually want to set it to index 9 and I've just wrapped these in a region just so I can collapse them they're kind of messy to look at in our update function I've got if player controls. player. Mouse wheel. read value float is greater than 0.1 then obviously we've scrolled the wheel up during that frame so we're going to choose the so we're going to change the index and we're just going to knock the index up one and similarly if it's less than minus 0.1 we're going to knock it down and you can see here that I've got private void use item so again we're listening out for the left Mouse button when that's performed we're going to call our use item method we'll do private void use item and we're going to say if there is item data in the slot that we have selected so if that item if that slot actually has an item in it then we're going to call the use item method over on our item data I'm going to jump quickly over to the inventory item. CS script and I've just added a public void use item and that's just going to debug.log our display name depending on your game you're going to do different things based on which item it's selected so you may have use item and then if you've got a weapon you may want to make a new scriptable object that inherits from inventory item data and that's the weapon class and then use item called some weapon logic if you'd like to see that kind of set up let me know and I'll do a follow-up video for that I wanted to keep this video just about the actual hot bar display to keep it short and sweet so then we've just got our actual index handling um code so we've got change index which takes in a direction to change it so are we changing it up or we changing it down and again we're calling that here in our update function based on which way we're scrolling the mouse wheel and here we're going to toggle the slot you I highlight which I'll show you in a second and then to our index we're just going to add the direction so we're index three and we go up one that'll obviously change current index to four and if we're index three and we go down minus one obviously that'll put the current index to two so once we've changed the current index we need to we need it to wrap around if it goes over the max index size so if we're at index 9 and then we go up to index 10 and our maximum index size is nine then we're going to Loop it back around we're going to set the current index back to zero and the sort of inverse of that is if we're already at index zero and we try to scroll the mouse wheel down we go below zero then we're going to set the current index back to our Max index size so it'll loop back around to the top and then we can carry on scrolling down minusing one until we're back to below zero and then we're going to call this toggle highlight code again which again I'll show you and then set index is pretty simple we're just directly setting the index um to you know whichever key we've pressed on the keyboard I do have some sort of validation stuff here um again just doing that wraparound functionality we should never need to use it because we are setting it directly but just for example if you set a static to if you want a hot bar of size five instead of using the full number keys and you've forgotten to um change this and like remove the the keys this is just a good way of making sure that we're safe that it will always um display the correct sort of index so if our Max index size is five and I press zero on the number pad I'm just going to set it to the max index size and that'll just make sure we don't get any errors you may want to debug.log something there as well just so you know that you've gone kind of out of bounds when you've pressed the key and then we're going to set our current index to our new index then we're going to call this toggle highlight functionality and the reason we're calling this twice here is because we're going to toggle it so we're going to turn it off for the slot we're currently on then we're going to change the index and then we're going to toggle that new index on so if we just click through to our toggle highlight script this is on our inventory slot UI script and we've got a public void toggle highlight and it's just going to set our slots highlight to the inverse of itself so we'll toggle it on or off this just saves having to have a toggle highlight on and a toggle highlight off uh method you can see up here we've got a serialized field uh private game object slot highlight so we're just setting that active so we're just turning that on or off um by calling set active here so then if we go over to our slot inventory slot UI prefab you can see here we've got I added a new image which I've turned off in the inspector we need to remember to turn that off um and all this is is it's an image I've made in Photoshop it's just a square uh you know Square sort of highlight which I've made it white in Photoshop so I can change the color of the Highlight here maybe we want it to be sort of a nice kind of green color um or keep it kind of yellowy orange and then I've dragged that image over into our slot highlight um on the prefab script if we look at our canvas you can see we've got our highlights here um and again I need to remember to turn that image off so they are all off and then one last thing in our hot bar display class over in our protected override start so here so here we've got protected virtual void start and this is uh this calls refresh static display our display we're just overriding start we are refreshing the display by calling base. start we're going to set the current index to zero we're going to set our maximum index size to slots. length minus one and then we're going to toggle the highlight of slot Z zero on if we press play there you go we can see we've got that if I click in the slots empty nothing happens you can see nothing's happening in the console but then if I pick up some stuff we've got our Cog we've got our potions using health potion and then we're using our sword so there we have it that's how we can set up a little hot bar selection obviously there is more that we can do with this um depending on your game so for example when we change index we might want to instantiate the sword for the player to be holding it and then then if we scroll off it it will disable the sword um you know we might want to show a potion in the player's hands again using sort of events like we've used events all throughout this project you know you could call an event that says slot changed and it passes through the item that is in that slot and then you can do logic with and then wherever you want and whatever your game calls for you can do logic with that this was a quick sort of fly through again this was there a patreon exclusive if you're watching this on YouTube Project files for this are over on patreon which is patreon.com dampas if you've got any questions let me know in the comments or join the Discord server um I'll be able to help you kind of debug anything that's gone wrong but for the meantime thanks for watching and I'll see you in the next one bye