Interesting ways you should use collections in your Unity3d game development - fixed audio

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up I'm Jason and today we're gonna talk about collections I think this is a really important subject that a lot of people don't learn about early enough in their careers and they start off with a single collection or a set of collections that they use and they don't even know that that's what they're doing so if you're used to just using arrays all of the time or maybe you use lists all of the time and that's pretty much it this video should be very helpful for you if you're using all of the collections that you see up on my screen right now oh hopefully this is still helpful because I'm gonna cover a couple real-world examples or at least close to real-world examples that show some ways that you can use these other collections and in kind of cool and interesting ways anyway if you're interested in this kind of topic please please um don't hit like don't hit subscribe just share the video hit share put it up on Facebook send it out to all your friends email it to your mom and tell her to share it too or or hit like and subscribe but really if you can share it that's the best thing I really appreciate it also everybody on patreon and on my email list that really push you guys thanks a lot alright let's get going so the first type that I talked about wasn't a race I just want to briefly cover what Ana Reyes show a real quick example of an array in a kind of kind of boring example right here with a random particle player so I've got this class here that's a monobehaviour so it's a component I can drop it up in the inspector and it has an array of particle systems that I marked public even though I put an underscore there so really this would probably be like private and a serialized field just to match my common naming standards of underscores being private there we go all fixed up now we've got an array of possible particle systems and this would be like a set of child particles on this object maybe that I've assigned to it and then I've got a play random particle method that takes a position on line 9 we pick a random index from 0 to however many particles are in that array and then on 11 we move it to the right position and 12 we tell it to play nothing special but a very simple example of how we would use an array now we can't really easily grow this array or add particles to it at runtime we could but it's not simple and we wouldn't want to use arrays for everything so the next thing that people usually find and the one that we're gonna cover next is the list and that's on enemymanager right here and this is really the next one that I found as a c-sharp developer too so as I go over this I'm kind of hitting them in the list that are in the order that I learned them in right it's kind of like a sorted list which I won't talk about today but it does exist I also just don't really use them that's why I wasn't going to talk about them so let's look at our enemy manager our enemy manager is a mono behavior and before we dive into the list specific stuff which is all down here the little bit of junk up here is just to make it a singleton and this is just because I've got a little demo that I want to show and I need to be able to reference this thing so we've made a singleton by making a public static enemy manager property named instance and then in a wake we set the instance to this thing if you haven't seen this before this is an expression body method and it's something that I used that it basically replaces the little brackets on the beginning and the end there but it shortens it up if I just do a little one-liner for a method and that's kind of the only time that I do it if it's something small like this so let's go on to lists like I said we were going to talk about buying ten we have a private list of enemy so the brackets there means that that's the type that our list contains and we have enemies right there like enemy right Brett between me yeah right between my fingers so a list of enemies right and we instantiate it right here so it's not no we always have to with our collections new them up and Stan she ate them somewhere we have to give them something otherwise it'll be dead or no reference exception if we did something like this go oh no when we try to add an enemy it's gonna blow up so we have to make sure that we instantiate it somewhere so then we have an add enemy method which just adds the enemy to the list very very common thing right everybody here hopefully probably has added things to a list you can also loop over the list you can remove things from the list so we can have a remove enemy with a public void remove enemy like just like this but enemy enemy and we can even make this an expression body method and just say enemies that remove enemy and it's not even gonna blow up it'll be fine even if the enemy is not there the list is gonna say hey don't care no problem I did whatever you yeah it wasn't there it's removed you're fine so there we go we can add remove we can loop over these things we can even kind of find things in the list but finding things in a list is not the fastest so if the list is small it doesn't matter at all like if you got a list of 10 things 100 things and you want to find one of them based on some property could loop over those and find it really quick you can use a link statement find them really quick when it gets to be a much much bigger size though things start to fall apart and we're gonna talk about that and a solution to that in just a moment but first let's go back to my notes so let's see my notes were in the random particle player and we're gonna look at the hash set next which is in the spammy trigger so remember how I said in the enemy manager that this is not unique we could technically add the enemy two three four or five six times there's nothing that would stop us from adding that same enemy to the list over and over a hash set however will so let's take a look at our hash set in the spam you trigger class so our spammy trigger cuz just wanted to come up with something really annoying and simple right is a trigger that spams whatever is in it with debug log messages it could be something in a real-world case that maybe heals everybody around them gives them a buff that they get when they come in and they lose when they leave or does some damage or pulls everybody in whatever it is maybe it's like sucking them in towards it whatever the thing is it's just a trigger that does something to everybody that's inside it you know how we're keeping track of everybody that's inside it is with this hash set so on Line six here I've got a hash set of enemies and the hash set likes it works a lot like a list except that it will keep the items unique and the details of how that works I don't want to cover today you're welcome to look into it I recommend it it's actually pretty interesting but what you really need to know is that if you add things to a hash set and they're already there it will not add them again and here's my example of that right here on line 11 so say lion can we get an enemy that entered our trigger and then we say enemies that add our enemy on line 11 but we get back a return value at bool for true or false whether or not we added the enemy so if we did at it I say hey we added them otherwise I say hey it was already in this list of stuff and where's my brackets a little bit weird there let's fix that up anyway I think you can kind of see the value here already we don't have to do a check to see if the things in this enemies collection we know that it's not there and it's not going to get at it again we also don't have to worry about some other chunk of code adding things to it so you might think like hey I don't need to do this I could just check with the other list in the other thing no the like just like the entity manager or the enemy manager right I could just do a check and say like hey if enemies dot contains enemy return and yeah I could do that it would work it's not quite as fast but it also has the downside of you know when Bob or Joe come over here and they go public void add two enemies and then they take in two enemies and they add them both I'm not even going to type it out but I hope you get the idea that somebody else could come in here add a new method add things to this list and the list is no longer safe if it's a hash set it's always safe I don't have to worry about it I don't need to write this extra code everything's good so that's just one good example of a hash that I use them for a lot of other things if I want to take in data from a bunch of sets or sources and just kind of make sure that everything is unique I can do that just dump them all into a hash set or add them all into a hash set but a lot of the time it's just when I want to keep things unique and I want to make sure that things don't get added twice and that's yeah usually what I use it for that was the use case there so let's jump over to the next one and the next one is the dictionary so I talked about slowness and the slowness that you're gonna get from searching a giant list versus a small list very smallest doesn't matter it's generally fast right unless you're doing it all the time but a big list that you're searching all the time will be extremely small extra yes small slow it would be extremely slow so let's take a look at this let's take a look at a dictionary and how we can use that well in one way to speed this up and then we'll dive into a couple of their dictionary examples because really dictionaries are probably the coolest data type you see today so let's look at the item repository item repository here is just a static class with a static dictionary of type int comma and it's named items it's not initialized notice that and let's talk about what this means the first thing here is the key so a dictionary is kind of like it's a key value pair or a way to look things up fast so we have a dictionary of integers as the key so we'll have a number for our key and items as the values so when we add things to this we'll be adding them with a number that's some sort of an idea or some identifier and then the actual item and then what happens is we can look at things up by that item ID or that the idea whatever the key is that we have and we can do it really really quickly we can also verify that things are unique because we can only have one of each key in there they have to be unique it's kind of like a hash set for our keys so we can do the lookup really fast and then we can find the related item very fast too so it's a really good way to speed up lookups of large sets of data and in this case we've got this public static method called load items and it grabs a list of items from some remote web service or database right like some other thing that's got a bunch of data that we're pulling down in my case this could be like a hundred thousand items coming from some memory cache or a database or some web service or something right and we want to be able to look these items up instantly on a server this could also be pulling in from some local files or some serialized data or some scriptable objects or something like that it could be anything that you want to be able to look something quickly in so we're getting this list of items so let's take a real quick peek at the item item it has an ID a name a value and an item type kept it really simple but this could be huge it could have all kinds of properties on it so we've got this list of items and right here this is kind of the cool part of the thing that I wanted to show in here didn't the most which is the on line 18 we can actually use the link extensions to generate a dictionary from our list with a key about from the our properties so as long as the IDS of our items are unique this will work fine if our IDs are not unique this will blow up we'll get an exception saying that it can't add the thing twice as the key but as long as our IDs are unique which in this case they are we can actually create a dictionary by using this syntax right here and the way the syntax works let's just split it out into multiple liens the first thing we have to do is give it the lambda statement for our key and usually I just have this as K and I just make this be K so what happens is it's figuring out what the kit the key should be and putting it into here so it's whatever this ideas and then the same for value I usually do V and V value value it doesn't matter it's just like any other link statement or lambda that you've done before if you're used to them should be really familiar if you're not I don't think I can dive into that right now but using this syntax the two dictionary with the key and then the property right there and then the value just allows you to build up a dictionary that's very easy to search and very fast to search so then I can just call get on an item and get back that item from anywhere the other nice thing about this is if I want to be able to hot reload my data I can just replace the items or replace the data in these items and then constantly read into it anyway a lot of cool use cases for this stuff most of the time though it's just kind of done on awake and it's parsing some scriptable data or some other data and just shoveling and shoving it into a dictionary so we can access it quickly now let's go on to another dictionary setup that also uses a queue and actually talks about a real full fun inventory system well real full not so full partial we full but still find inventory system here we go we've got an inventory system and let's take a look at the top we actually have a stack oh wait a minute nope we're gonna do a selection counter first I lied to you before we hit the inventory system let's look at the selection counter because I said I wanted to jump into the unity project and I want to do that the selection counter is gonna allow me to really do that so let's take a peek here we have a selection counter and here we've got the dictionary reversed so I've got an enemy for the key and an integer for the value so notice I'm not just using a number for my lookup it's not just an idea lookup I can also just use any old object so I'm using my enemies here and I've got this is that same singleton pattern stuff so just ignore this this is the same single thing so I can find this in the code now I've got a select method here and let's see what I really care about let's go to the update ignore everything else for now let's start in update because that's really where we want to go so in our update we check to see if we left click with get mouse button down if we did we generate array based on where we click yep don't use camera dot mean I know just an example then we get the Ray here and we do a ray cast and then we say out ray cast hit and hit info if you haven't seen the syntax by the way and you see sharps awesome can declare the raycast hit right in there you don't have to do it outside and then if something is hit we check to see if it's an enemy if it's an enemy we call select so it's just saying hey if I click on something call this method okay so you've got all that now you know what it does so if I click on something select it gets called and if select is called we say hey does the enemy selection count contain the key of enemy this is a very cool and important part of dictionaries this contains key it allows us to check to see if there's anything in there with the key pretty simple right it's a name really well so if it does not contain the key so if it equals false then I actually add it right here so I there are two ways to add this by the way you can add it by setting it just like this with the square get sequels or I could alternatively just do this dot ad and put it just like this with the key and the value that's kind of what it looks for I have a habit of doing it with the square brackets in this setting only because if I'm not doing an ad if I'm doing like an ad or update then it just works and I don't have to do the contains key check I can just do equals that value and then I don't have to worry about it so whatever I'm gonna leave it like this though because it really works either way so what we do is we set the value to one to count that I've clicked on or selected the thing one time the first time through otherwise so if it already did contain this key I just find that value and increment it so I increment the integer at this key in our dictionary so it's gonna go to one the first time to go to two and then I have this method called pin to enemy if we clicked enough which just checks the dictionary here by the enemy to see if it's greater than five so if I've clicked it more than five times we turn it red let's go take a peek at that so here I've got the project set up and I have this um in a beta version of 2019 so it's a little bit finicky so I'm just gonna do a real quick re-import just to make sure that everything's good all right we'll hit play and fix those tricky lights behind me and we should be able to spawn some enemies there we go and as I click on them so let's click five times on this cube turns red if I click on this guy and one two three one two three I am five and one two more turn this guy red so here I'm just using this dictionary to keep track of how many times I've done something to some object now you might think like hey whatever we could add the click count onto the object maybe if the object is really supposed to be keeping track of how many times it was clicked but maybe you've got another system that wants to keep track of things and you don't want to keep loading your other objects up and you just need to keep track of it for something unrelated to the object the object shouldn't know about in this case it's a really easy way to associate some data with some objects so we could do you know the objects key and the number of them that you have or the state of it or the condition that's in how much damage it's taken anything like that that we don't want to necessarily put on the object is it is a really cool and interesting use and of course there are hundreds and hundreds of uses probably I don't know I could probably come up with a dozen at least but there are probably hundreds out there for dictionaries so let's go on to one more the one that I kind of tricked you about that I thought I was gonna hit earlier but I didn't yet and that's the inventory system the inventory systems using two different data structures here we've got a stack and a dictionary our stack is of type item and our dictionary is an item with our integer key with an item value and you probably tell by the name it's based on slots so this is saying like oh maybe I want to have a slot based inventory system and for this example I want to have ten slots available this could be variable I could have some way to get more slots or change the slot system completely or even not use slots but slots is a really good simple example here and it works in a lot of games where maybe you just have a bar of slots of things or you've got no however you display these slots it doesn't really matter so let's just say we've got numbered slots here in this case maybe they're hot key slots how do we use it how does it work in how does the dictionary and the stack what's overflow items what does it all mean well let's take a peek so in our constructor here we just initialize these slots so what I'm doing here is actually stupid because we don't need that and I'll show you why because I actually made the other code even smarter so we can delete this delete that delete that delete that and shrink stuff up so just remember when you see stuff on the screen doesn't necessarily mean that's good if I put it up doesn't necessarily mean it's the right thing or somebody else does like sometimes people put code up and they forget to delete it in that case yeah that was me so let's see the the cleaner version of it right here so I've got this add item method and it takes in an item and what do we do we look at the number of slots available and we loop from zero to the number of slots available of course you're thinking hey we could cash the next available slot sure we could we're just doing it simple though there are definitely lots of optimizations here and we're also we're looping over ten things it's never going to matter unless this number gets a whole lot bigger so anyway we look to see if the dictionary contains the key of the slot number so right at the beginning the first time we add something this dictionary is totally empty it's going to be false so we don't even care to check to see if it has an empty item in it and that's what this is does it contain the thing or does it contain an a null thing either way if it's empty or it's no then I want to set the value there to this item and that's where I was talking about using the assignment instead of the ad this is exactly the case because it could be that it just didn't contain it or that the value was null in either case I want to put the item into that slot and then my code gets a little bit simpler because I don't need an ad and a set I just have this one call and then we bail out we say hey we added the item we're good but what if we ran out of slots so we've got ten slots and we're adding item number 11 oh nothing ever gets added here so I've got this overflow item set up and this is a stack of items now a stack is a collection that you can add things on to and then pull things off of so whatever whenever you add something to a stack it goes on top it's just like literally a stack of things if you stack a bunch of crap on top of each other you have to take them off from the top you can't take things off from the middle or the bottom so as you stack them up you have to pop them off the top and it's called what does it push and pop but it's really like stacking it up and then taking it off the top so that's how a stack works and that's what we're using for this because I want to keep putting items on there but as I take items off I want to take them from the top so let's see how that works and how I'm actually using it and I'm doing it in this delete item method so I've got a delete item where I take in a slot it's just the number so okay I want to delete item four first thing I do do I have an item in slot four if I do if there's a value there there's an entry there Oh first I also make sure the items not know because if it's no I don't want to blow up let's just make sure that it's actually not a no item and we're not deleting an empty slide if we're not deleting an empty slot then we set the item and what I'm doing here is a little bit weird and I feel like I should just refactor it to make it a little more easy to read but instead I'm just going to explain it in detail because I know a lot of people see the operators here and they get a little confused so what we're doing is assigning the value for this slot to either this or this so if the overflow items has any entries that any is a link statements we just do dot any if it has anything then we're going to assign it the value of whatever the top thing is we're gonna assign it the thing right after the question mark so if this is true we we assign to this if this is false we just assign it null so the other way I could do this is just like let's just do it I want to write it out to make sure that everybody understands it if you understand this already sorry it's gonna be a couple of seconds the other way to write this would be just like that so you can see it does the same thing but it's just a lot longer so I like to write it the shorter way so hopefully that was helpful oh no I've undone too much hopefully that's helpful though and you kind of understand how these work but we're filling the item with whatever the thing is on the top of the stack now if we wanted to take the oldest item from the overflow so say I've gone out I've picked up five items with my inventory full they're all in this overflow stack and then when I delete items I'm getting my most recent one say I want to change that so that I get my oldest item instead of my most recent item that is where we just simply switch to a queue so you change the stack to be a queue and we changed these keywords just a little bit to in Q and D queue and that's it now it's going the other way so now the oldest item that went in my over went into my overflow will be the first one that pulls out so and of stacking up and up and up and having to pull from the top I stack up and up and up and I pull from the bottom it's more like a queue or like a line at an amusement park or a store or anywhere else or the first person in or the first thing in is the first one out so that's the difference between the stack and queue and one of the many many use cases for when you'd want to use them a lot of the time if you're doing like a pooling system it doesn't matter at all you could use a stack or a queue or whatever and it's not gonna make a difference but there are cases where you know making a choice you know or knowing the difference between them can make it so that you can make a choice like this and you usually switch back and forth between them relatively quickly well yeah very easily right anyway I'm gonna stop talking about collections for now but there there's a lot more to learn about them I think there are a lot of cool extension methods on them if you haven't used link extension methods I highly recommend you check out some of the videos and stuff on that because it makes it very easy to get data and filter data and it's important to note though that they can be bad for performance not not the collections but some of the link statements so when I do those I they're usually like one-shot things for things that are rare they're not something that you want to do constantly you don't want to be doing a to dictionary every frame or something like that but you can do it totally fine in your load because the hell its reload doesn't matter alright anyway if this the kind of stuff you like again just remember please share it whatever you do just share it let me know drop comment and if you have some other ideas for collection stuff to talk about just let me know - I'm kind of curious what other stuff people want to hear I thought that these were and the most important ones and the ones that I use most of the time there are quite a few other ones but I don't know if anybody cares anyway thanks again bye it's all I got you
Info
Channel: Jason Weimann
Views: 23,650
Rating: undefined out of 5
Keywords: game development, unity tutorial, how to make a game, game dev, unity tips and tricks, unity, unity3d, unity tricks, tips, tutorial, unity best tips, gamedev, unity for beginners, unity3d college, u3d, unity solid, #unitytips, game programming patterns, hashset, queue, stack, dictionary, list, array, design patterns, game development unity, script, how to make games, programming, c#, coding, tips and tricks, unity3d tutorial, data structure, unity 3d, beginner, unity tips, brackeys, tutorials
Id: CymKpDuHJ0E
Channel Id: undefined
Length: 26min 36sec (1596 seconds)
Published: Sun Sep 08 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.