 I've got a basic little prototype here where the Godot icon that's included with the engine fires a little bullet with the same icon of itself when you press the space bar. I want to make it so that we can fire two bullets or one bullet. Maybe in this fictional game there's a power-up the player receives that makes it so more bullets are fired simultaneously. I'm going to show you how to use enums to write code that makes it a lot easier to change between the player's firing state and wires into the Godot inspector so that you have a much better experience managing how that's set and it'll just be a lot more resilient. We're going to start out by just I'll walk you through what we've got in our project. So we've got a 2D scene here called main with an instance of the player scene. The player scene is just their icon in a collision-shaped 2D. Player has a script attached to it called input. Input says when the space bar is pressed, the UI accept, instantiate a weapon which is a packed scene, a bullet, set its global position to the player, add it to the root of the game and then set its linear velocity to the bullet speed. And I have all this code in here so that it's more visible as we're working on it. But you could also put some of this code into our bullet script. But the bullet is simple. It just keeps track of itself and it's this is a smaller version of it looks like the player but it's just a smaller version and all it has is a visible on-screen notifier that cleans itself up with Q3 when it leaves the screen. So that's what we're working with here. Let's go ahead and make our code support firing two bullets at once instead of one. We're going to start by coding this sort of in a naive way that is prone to errors. And then we'll refactor it, which means we'll take the code we have and we'll adjust it to make it better. And that cycle of writing code that's working and then cleaning it up and refactoring it, that is a really important thing to learn where it's okay to do things at first with the intent of making it better. Maybe you make it better weeks down the line or minutes later. It doesn't matter. It's just a really common pattern. So don't worry about getting it right right away. You know your code is malleable and it can be changed. So what we need to do is have a variable called fire type and we'll set it to single. We'll go ahead and we'll say if fire type is equal equal to single then we'll fire the bullet once. Now if fire type equals double, we'll do this two times. So we'll just take that. I think we can copy and paste it just twice, but we need to rename this bullet to be bullet two. And what I did just there is you press control d or commandy. You can select all code of similar style and drive multiple curses at once. Really helpful little side tip. Let's run our game again. For a space it's still firing single, great. If we export this variable that makes it accessible within the inspector to change its value. So here if we change fire type to double and save that. Now it fires two bullets and the bullets have collision on each other. So they're spawning at the same point and separating. That's why they're really close up to each other and not overlapping. Let's make it so that we can space them out a little bit. So when we set the global position of the bullet when we're firing the double, we'll just do plus vector two. We'll do 10 pixels to the right and here we'll do vector two, 10 pixels to the left. So we're just adding to the global position of our main big guy and firing there. We want to add the negative. I think that's a little clearer and I want it to be a little more spaced out. So run that again. I don't think I have to keep quitting and rerunning. I think that's just a weird habit I have from these screenshots, screencasts. So now we have the double. Great. And you might be thinking this code is, yeah it's duplicated but it's working and that's good enough. But the problem is that in your code if you're using fire type elsewhere or you're trying to reference it, you don't know what it is, right? Like if you accidentally have a typo, your game's not going to catch that typo or your code's not going to catch it. So like you could go here and like you could type in single, right, S-H-G-L-E, sickle. So now we have two typos and this is like the tyranny of strings, right? When everything is coded against string values and it makes it more prone to user error. But yeah, you could write some code to help make your code a little more resilient. Like you could do print debug and say like player fire type, not recognized. And then sub that in with fire type. And you'll see now it's not firing but hey, at least we have an error, right? And we say, okay, it's sickle, great. Let's go ahead and make that single run it again. Well, huh, fire type not recognized single. Oh, wow, we have two typos, right? I knew that, but I don't know why I like feigning lack of understanding. I'll stop doing that. That's a little bit better, but we can make it way better. And that's where enums come in. Enums are short for enumerators and they're just a way to describe something that can only be like of one state at a time usually. So we'll make fire type and the, the like style guy is usually Pascal case for enums. That's where you have every letter of the word is capitalized and the rest are lower case and then the values within screaming snake. So single double and like snake means it would be like that. But since ours are just single words, we do that. Now what this does is it creates a easy way and easy way to access and assign these values. So now here we can actually say fire type is equal to set of our string. We can say fire type dot single and we have that reference there. We can also say that player fire type is of type fire type. And now we've got errors, helpful errors in our code saying we can't compare our string values to the fire type enum and that's really, really helpful. I think we can even do the shorthand here of colon equals that automatically gives fire type the type that it needs to be and you'll see here we still have our error. So instead of comparing our fire type to the string value, we just compare it to the fire type enum value. And here we'll do single and then here we'll do, whoops, I selected too much. We'll do fire type double, great. Now if we go ahead and run our code, let's see what happens. It's working. Now here's the kicker. Here's the best part in my opinion. If we go to the inspector and we go to player and we have fire type, we can select it from a drop down, Godot knows that this is an enum and there's only a limited number of values that can be set to, I'll just create a drop down so you can easily select it and you can change fire type in the code to like you could wire it up to be changed. You would just say fire type is equal to you sign a new value, right? You know, whatever, whatever it is, you would just assign it there. That's essentially what this drop down is doing. So we have that there. We can also, we can even document this and we can say like weapon firing pattern. And then when we hover over fire type, hmm, that's interesting that didn't work. Well, maybe I don't know how that works. I will edit this out. So we've got our enum now set. We've got a nicer interface for selecting it. We can change it and verify it works. All you do is compare the values and that code is significantly better. What fire type is the enum values, it sets it to integers by default. So if we do print a bug, let's do every time the actions press, we'll just do print a bug and we'll output fire type. I just want to show you the internals of what an enum is. So right now it's set to double and print debug is outputting one. Let's go ahead and change fire type to single. Now print a bug is outputting zero. This is because what's happening here is that Godot is automatically assigning indices to these and we could even assign like string values to them if we wanted. Nope, you can't not in this language. It must be an integer. So Godot does it automatically for you. There might be a time where you'd want to change it yourself, but for the most part you just create your enum like this and you can assign it to a variable and that's what it's doing. So if you were to look at the value, it's an integer instead of this. So it's a way to reference them. That might be confusing sometimes in code if you're debugging, but so that's why I want to let you know. You can also do a quick enum where you call export enum and you can say like you can pass in arguments of what the values are. So you could say like up, down, var, direction and yeah. So the docs here are kind of interesting. It shows you like if you had a character class, you could export export them and have them accessible. So that's another way to do it like you could have, for us, we could have done single double fire type. But I honestly, I prefer having the enum accessible in this way because I'll show you now that we can access fire type in different places. Like maybe you have code that you want to compare and use elsewhere. So like let's say in bullet if we, for some weird reason, we just wanted to print debug fire type dot single. If we add that and run it, it won't work because it's saying fire type is not declared in the current scope. So what you can do is you can actually add a class name in your script so that you can reference data within it elsewhere. So instead of doing fire type that single, you can do player dot fire type dot single and it works. And you can see the auto completion works too. So we have this enum that's available here and you can get at it here. So like we'll see when bullets fly off, it'll just print to bug zero because we're outputting that value. So if as you're working with enums, if you find that you need to check what it is and you have the enum specified here in a script or maybe in another script and you give it a class name, you can go ahead and just add class name and then access that enum values as you need. Great. So that's enums. That's how to export them. That's how to use them in the inspector. Have them be accessible via class name. Let's go ahead now as like a bonus end and clean up this code because, you know, it's pretty gnarly. It repeats itself quite a bit. So we'll just add a function called fire bullet and we'll copy this basic code here and make that a bit better. So we'll say function funk fire bullet and we'll say it returns void because why not? You could make it return the bullet if there was some reason to, but we don't have a good reason to. And then here we'll just fire bullet fire bullet and we'll go ahead and run it. Press space. That works. Let's verify that firing double bullet works. It works, but we don't have the spacing. So let's bring back support for the spacing and we'll just call it offset vector two and we'll default it to vector two dot zero. So now it's optional. You don't have to pass an offset, but you can. And then we'll just add offset to the positioning of the bullet. And then because we want this centered and it defaults to vector two, we don't have to pass it in. And here we just do what we did before where we say vector two, 20 to the right. Keep it centered. Vector two, negative 20 to the left. Save that. Now we've got our spacing again and we can verify to that good old single still works. And you know, here's here's like another powerful thing is like we could duplicate player and have one player be a single and one be double. And then in our 2D view, drag this one here and this one here. And you know, they fire at the same time. So like you could create a debug mode where you could test all these at the same time to verify they work. That's another like little tip, I guess, on like how to work with this stuff. But now our code is quite a bit better. We can pass in a vector two optionally. We could like, you know, as a kind of a joke, I guess, let's offset this like 40 y. Just say you see what's happening here with the code in case that's not clear. That starts them lower on the player. Like if we made it 200, one of them, we'll just make one of them 200. It starts way, way low. So we want to be zero anyway. That's enums with a little bit of refactoring at the end. Hope it helps because they sure helped me. They're the foundation of state machines in Godot and we'll help you make your code better. All right. Till next time. See you.