How to Change Scenes in Godot (Building a Level Switcher #1)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

You have a natural flair for teaching. Very good tutorial. The only thing I would adjust is your tendency to over explain or repeat some of the more obvious directions. The tutorial probably could have been half the length without losing any key information. It can be hard to judge what's necessary when you don't know the skill level of your audience, but in general I think it works better if you assume they heard you the first time.

Not to discourage though - you're very good at this.

👍︎︎ 5 👤︎︎ u/bigboyg 📅︎︎ Apr 22 2021 🗫︎ replies

Good stuff you weapon

👍︎︎ 2 👤︎︎ u/Set_the_timer_to_eel 📅︎︎ Apr 22 2021 🗫︎ replies
Captions
in this video we're going to go through how to make an advanced level or scene switching system in godot using some custom child handling and doing something a bit more advanced than godot's built-in change scene function you're going to be able to go back and forth between scenes just like this and have a really nice dynamic code that you can apply to your own level switching system in your own game in this video we won't get to doing a transition animation or passing data between scenes those will come in the next two videos in this series to really round out how to make an amazing scene switcher in godot let's get started okay so let me introduce you to the example scenes i've created to help make this tutorial i've got two levels they're exactly the same this is the grass level it's a scene that has just a colored rectangle a label with a title and a button that we're going to connect to a signal to change the scene and besides this grass level i've also got a desert level which is literally the exact same same tree same scene tree only difference is that the box is sand colored instead of green and so we're gonna be running our grass level here hitting this button to change this scene to the desert level and you'll notice that on both our desert level over here on the top left and in our grass level on the top left here we've got a script attached it's the same script this level script for both of them and right now i've got an on change scene button pressed the change scene buttons in both of these scenes are connected to this signal and if you don't know about signals you want to look at another tutorial for that we're going to be using signals pretty heavily here so i would suggest looking into that first there will be a suggestion for a video you can use to do that on the top right as a card anyway though so we need to connect this change scene button this signal here we need to actually make the function this signal is connected to change scenes now in godot fortunately the engine makes it really really easy to change scenes it's actually something we can do in just one line of code and that is get tree so this is a function and then on the return value of this function we're going to call change scene and you'll notice as soon as i do that we start getting some auto-complete here which has a bunch of paths to our different scenes in the game and you'll see a bunch of stuff here but you'll notice right here i've got desert level and grass level so now i've got grass level here this is the one that we're currently working from so i can just enter desert level and so this change scene function takes the path in your resources directory so this relative path that godot creates to the level it's a string path to the scene file itself and so we'll give it the scene path for the desert level and now whenever i click this button it's going to change to that scene now let's talk really briefly about what's happening under the hood here the first thing we're doing is calling get tree we need to do this because it gets the scene tree object itself in godot so it gets the overall scene tree and this scene tree this this special object in godot is the is the actual object that has a change scene function on it so whenever you want to change scenes you need to call get tree first and then once you actually have the scene tree then you're calling change scene here now another thing to know is that when we change scenes this new scene is loaded in they create a new instance the engine creates a new instance of this desert level and then it will get rid of or it will kill it will free up the current scene so once we change to this desert level our grass level will be freed um it will be q-freed so it'll be freed when it's safe but it's going to change into our desert level and free our grass level in the background now this is okay but what it means is that once we initiate the changing of the scenes if there are things we want to finish up or sounds we want to play etc or an animation we want to play in our grass level before the scene changes we're not going to be able to do that because godot is going to change the scene instantly so we'll talk about in just a second some ways we can get around that but first let's run this and see if it works so if i hit command r to run our scene here or you can just hit this button up at the top right if i do this we'll see our grass level and now if i click this button all of a sudden we're on our desert level now there's a problem here because we are hard coding our desert level scene path in our script so we're always going to be changing back to our desert level so we can't get back to our grass our grass level but we'll also change that right now so this line of code is the easiest and simplest way to change scenes in godot it is incredibly easy it's one line of code you can either hard code this path in or you could do something a little fancier where you can pass in a dynamic path if you have multiple scenes you might want to change two or multiple options both of those are very easy to do but we've talked about two limitations one is that hard coding the string in here limits the ability or the amount of scenes it limits your options on what scenes you can transition to and more importantly the second limitation is that it prevents you from doing any cleanup or animations etc on your current scene before you transition to your new scene additionally there might be things you want to load or initialize on your new scene before it actually becomes present or visible to the player there's a lot of things you might want to do in the background just because even if your scene is loaded you might want to spawn in a bunch of things or do some custom logic etc there's a lot of cases and so in order to get around both of those limitations we're actually going to build a scene switcher parent node that's going to handle all of our scene switching logic so in order to do this i've created a new scene it is consisted of just one node a regular node not a 2d a node 2d or a spatial but just a regular node that i've called scene switcher and what we're going to do here is actually instance a grass level or whatever your default level would be you know you can expand this to be the level system that you have in your own game but i'm going to instance our grass level as a child of our scene switcher because that will be our default level so i'll hit the instance button here and i'll find grass level and i'll hit open and now all of a sudden if i select our scene switcher here and now if i select the 2d view we can see in our scene switcher we've got a grass level and so we've got this script here on our grass level already on both of our levels but we're going to take some of that scene switching functionality up to our scene switcher now so because our button to switch scenes is tied to our specific levels our grass level or desert level we need to have a way for those levels to communicate to our scene switcher that the player wants to switch the scene so now instead of having this get tree.change scene line we're actually going to add a new line on our level script and i'm going to say signal level changed and this signal is going to tell our scene switcher hey the player has changed the level so now you need to adjust our game to actually change that level and so we'll have this and i'm actually going to get rid of this line here line 8 and change this to be emit signal and this is going to be our new level changed signal here there's also going to be one other thing i'm going to do which is to give an export variable here with our level name or level index you don't have to do this it might work better to do a numbered index or maybe you don't even need an index at all maybe your levels are self-sufficient in your game but the reason i want to give a string index to our levels in this one is just so we have an easy way for our scene switcher to tell which level is the current level in which level the player wants to go to so i'm going to say export and i'll say string because we're going to do a string and a variable and this will be level name and i'm going to just default this to be level and then we'll be able to edit this in the editor for each level to make it really easy and so what i'm going to do is add a parameter to our level change signal here which is going to be the level name and then when we emit this signal i will just pass in the level name as that parameter really easy and now what i'm going to do in the editor is actually give our levels a name so this grass level is going to be grass and same for the desert you can tell where this is going to go i'm going to go to our desert scene and change this to be desert okay now all of a sudden our levels are emitting this signal here and our code is very generic it doesn't matter which level we're on anymore we're not hard coding anything which is really nice now our grass level and desert level can reuse the same script and it's not going to cause any issues so if i go back to our scene switcher here now we know that our level whenever we hit this button is going to be emitting a signal and that signal is going to be level changed so now that we know the name of our signal here we're going to add a script to our scene switcher so i'll just hit the new script button hit create and what i'm going to do is on the ready function so in ready i'm going to say grasslevel.connect and this is going to be you'll see it even pops up level change and we're going to connect it to our self so a scene switcher and we'll make a new function on our scene switcher called handle level change and this is the function where we're going to handle everything that comes in and whenever we change our levels here and so we'll say function handle level change again make sure that this match is exactly what you've typed in the string over here and remember our signal has a parameter and that parameter is the new level or the current level name so we'll say current level name and this is going to be a string parameter okay and now that we're getting our current level name there's a few things we need to do here to make our scene switching work really well and before we dive into writing the code for this it would be good for you to take a second and think about in your own game how you're gonna handle getting your different scene files i'll talk about it briefly about how we'll do it for this tutorial but you know take a second and think about for your own game and extrapolate as needed now when you use that change scene function that we saw earlier we have to get the path right our scene path the file path to a scene and so in order to do that we kind of have to know somehow from one scene to another which path we need to take and there's a lot of ways you can handle that in a bigger game let's say your game has 50 levels and they're indexed by numbers so you have level 1 2 3 4 instead of grass level and desert levels so it's numbers that drive your levels names what you could do then is have them all your level scenes exist in the same folder and then have them named appropriately so it's always level one two three four etcetera and then you could make it really easy on yourself by having a hard-coded string that gets the path to that levels folder but then you pass in the dynamic a dynamic variable or a parameter that just has the number of the level and then so you don't have to worry about getting the hard-coded string every time because you're only you really only care about the number of that level the index of that level because you are using a consistent naming pattern so there are multiple ways to make this work with a bunch of levels you'll have to figure out some logic in your own game about how to easily and consistently get the level you need from one to the other but we're not really going to worry about that now even though we'll write some code that will help you do that so with that in mind we need to think about for our own game if we are in the grass level we need to go to the desert level and if we're in the desert level we need to go to the grass level and so somehow we need to get the correct scene file path depending on which level we're on so in order to do that we're going to first add a new variable here in our scene switcher and i'm going to make this an on ready variable and i'll explain why in a second and this will be current level and this is going to be the level in our scene so not the path but the actual level instance itself in our scene tree that corresponds to the current level so because our grass level is default i'm going to set this to be grass level and what we can do now is get rid of this grass level in our already and just say current level you don't have to do it it'd still work if we got grass level but this is a little bit nicer and this is why we're doing an on ready variable here is because we want it to default when our scene readies up to our default scene that we've got our default level so now that we have that let's think about what we need to implement here in our handle level change function so when we have this function called when the signal comes in and we get our current level name we need to determine based on our current level name what the next level should be so we're going to make a variable here at the top of our handle level change function it'll be variable next level similar to our current level this is going to be the actual scene we're going to instance and so we'll say next level and we'll just set it to that for now just because we'll keep it as a scene or we'll we'll keep it as null for now and instance it later and i'm going to use a match statement here a match if you're not familiar in gd script is the same as a switch statement in other languages now since we only have two levels using a match statement is kind of silly we could just use an if else or a ternary but because having two levels is kind of unusual i'm going to write code here that expects more levels and that'll be easier for most of you with your own games so just bear with me here even though this is kind of contrived so we're going to match on our current level name so match current level name and then we're gonna we we have um in order to get the possible options our current level can be we we're just gonna use the fact that we know there's grass in desert but if you had a lot of levels you might want to use an enum for this or another or a consistent file name scheme for example something that makes it easy for you to know or do a match statement here or however you want to do it again we have the benefit of just having two levels but you'll want to use some kind of consistent naming pattern or an enum or something that makes it so that you know ahead of time what possible options you'll have here and so now that we're matching on the current level name we'll use the two options we know it could be which are grass and so if it's the grass level we will set next level to be our desert level and remember that our levels our scene files are resources in godot so we have to load them in so we'll say next level equals load and here we have to give it a path so we'll say res and it's not going to give us good auto completion for this path but you can look in your scene tree here so we see it's res and then change scenes and then desert level you'll have a different path in your own game but i'll just use this so change scenes remember i'm getting it from the scene tree over here on the left so res change scenes and then desert level so i'll say desert level.t scene and we'll make this a little bit nicer in a second and so what i'm doing is i'm loading in our next level here and now we can do the same for desert if our current level is the desert level i'm just going to copy this line and then change this desert level to be grass level and you see that these lines are almost identical except for the grass and desert so that should suggest to you hey maybe there's a way we can kind of consolidate this code and you're exactly right if that's what you're thinking we'll get there in a second now we do want to have an error case here so we'll just use this underscore which in gd script says just match whatever and if this is the case we'll just return we will not change the level because we got a level name that is invalid we don't know how to handle it so let's make this match statement a little bit more robust and easier to work with um so let's let's extrapolate a little bit of the code here so we know we're always going to be writing next level equals load actually let me just copy this line so we know that we're always going to be writing next level equals load because we've done that twice now right so in each of these match statements these cases we're going to be writing load and then res change scenes and then something level it might be grass it might be desert but it's something level so what we can actually do is then just have we can do some string concatenation and say like next level name this is a variable we don't have but we're about to make it let's say we did have a variable with the string level name and then we can just do a plus sign there and so we can just do a dynamic variable here that prevents us from having to load this in every time and so now what we could do if we create a new variable called next level name this will be a string we can change these lines for example so this one right here instead of saying loading in the entire scene we can just change it to be desert and remember capital because that's the name of our file there same thing here we can just change this to be grass and now all of a sudden what we're doing oh and we also need to change this from next level to be next level name so i hope that kind of made sense what we're doing here is just simplifying this a little bit we are using this match statement to get the level name for our next level and then we're taking advantage of the fact that we have a consistent naming scheme for all of our levels to just dynamically insert or concatenate our string our the string of our our file path to our scene and we're just going to pass that in so we'll depending on our current level get the name of our next level and then insert that name into this string file path to load in our next level into our actual next level variable now even though we're loading in this variable or this uh scene resource though it's not actually in our game yet we have to instance this and all scene files this is a packed scene is what godot calls it's a type of resource that holds a scene file we can there's a function on them called instance and so we're going to call instance and this is going to actually create a new instance of this resource and store it in our next level variable so now our current level stores the actual instance in our scene tree of our current level and our next level stores the in an actual instance of our next level but it's not in our scene tree yet so that's another thing we need to do so now we have our next level we can say add child next level and this is going to add our next level as a child of our scene switcher just like our grass level is and now that it's in our scene tree we'll actually be able to see it but there's a couple things we need to do then now that it's going to be visible one is we need to get rid of our current level so we can say current level dot q free and this is going to free our current level then we can set our current level to be our next level so now we have a new next level and now that we've done all this if we run our game we should see again that we've got our scene switching work working except now we've got something much more dynamic and able to adapt to anything our game needs than we had before when we were just hard coding the path so if i run the scene and i hit change scene we'll see that we switch scenes which is amazing but if i hit the button again we'll see there's still a problem it doesn't go back to our grass scene and the reason it doesn't do that is because we never connected the signal to change levels again when we get our new scene so in order to do that we need to use pretty much the same line that we have on line eight the same connection variable here so i'm going to copy and paste this connect part and then say we'll say next level dot and then i'll just copy this paste in so next level connect level change self handle level changed so what we're saying here is like hey when we click the button on this next level which is now about to become our current level then we also need to emit the same handle level changed signal because we're doing the same line in two places it does suggest we could probably pull this out into its own function which would be really easy to do and a good thing to do but we've got a couple more changes we need to go through so we won't get to that quite yet so now we've got a system that lets us change back and forth between our levels really easily and it's dynamic the code works well and it's going to be really easy or it's going to be able to handle any type of level switching we need so we've really improved our basic level switching that we have and you'll notice that we're not using the built-in change scene function that we looked at earlier that's because you can basically do the same thing by adding and removing children you're kind of doing the same thing that that change scene does except instead of what change scene does is it changes the route scene we're not actually doing that because we have this scene switcher scene the scene switcher node that is persistent it's never leaving the tree so we don't actually need to change our root note itself we're just changing which child of our scene switcher is currently present so it's a little bit of a difference but this gives you a lot more fine grained control over how to change scenes in godot so my recommendation generally is to do it like this if you can avoid it and you've got any sort of complexity in your game you're probably not going to want to use godot's built-in get tree that change scene function you're probably going to want to handle manually changing scenes like we do here by adding and removing children so this is really awesome we should be really happy with the system that we have that lets us change scenes now now there's still one problem with this which is that when we hit this change scene button our new scene isn't really being or isn't really waiting until it's fully loaded to show and our current scene isn't really making sure that everything it needs to do is done before we change scenes and so what we're going to do in the next video is actually create a transition animation that while that animation plays and there's a there's kind of a fade away on the screen everything is happening in the background so all the things we need to do the old scene is cleaning itself up and the new scene is loading everything it needs to in while our transition animation plays and that makes the transition a lot less jarring and it gives both the old and the new scene the new levels that we're switching to time to actually load in or clean up and do everything they need to do so stay tuned for that next video it's going to be really exciting and then after that we'll finish up the series by talking about how we can pass information between scenes thanks so much for watching everyone i hope this video has been helpful in creating your own level or scene switcher in your own game if you did find this video helpful like and subscribe always helps and supports the channel we'd love to have you in our discord you can ask any questions there and the link to that is in the description below and if you do find my work helpful you can donate a coffee on buy me a coffee the link to that is also in the description below and doing that is much appreciated helps me to continue to make great videos thanks so much for watching see you in the next video now
Info
Channel: jmbiv
Views: 6,000
Rating: undefined out of 5
Keywords: godot, godot engine, godot 3.2, godot tutorial, godot 2d, how to make a game in godot, game development, game development tutorial, game development for beginners, godot for beginners, game dev, indie game dev, indie game development, hobby game development, gamedev, godot game engine, jmbiv, godot change scene, godot switching scenes, godot scene transition, godot level transition, godot scenes, godot scene change, godot level change, godot transition between scenes, gdscript
Id: XHbrKdsZrxY
Channel Id: undefined
Length: 22min 4sec (1324 seconds)
Published: Thu Apr 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.