Godot 3 Tutorial - Mobile RPG - P7: Accessing Battle Units with Scriptable Objects

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good morning afternoon or evening wherever and whenever you are my name is Benjamin and welcome to part 7 to our mobile RPG series this series is sponsored by my Kickstarter course it's a Godot Kickstarter course you can find a link to that in the description and there will be a card in the video let's get started so last time we set up our we we spent some time setting up our different sword actions so that they wouldn't be quite as coupled to the battle object up here and so I want to talk a little bit about that because I have I I kind of mentioned earlier that this really wasn't a good solution where we're getting access to the player and the enemy like this and and so I want to talk a little bit about coupling so in your project you want to try and reduce coupling as much as you can and coupling is basically when one part of your code relies on another part of your code and so you can see this right here this relies this code right here relies on us accessing the player and the enemy nodes and there's no way you can remove all of the coupling in your projects because obviously certain areas of your game have to communicate with other areas of your game but you want to try and keep your scenes as decoupled as possible so and one of the ways you can check to see how much coupling you have is if you open up your scene like this sword button right here if I run this scene on its own and I don't get any error messages and I click on the sword and I still don't get any error messages then it's probably not super coupled because if you're running an individual scene and it's not working on its own then you've got some problems there so let's try running the enemy here and see we don't have we don't seem to have any errors right there so that's a really good first way of kind of checking to see if your if your game has very high coupling in it or if your scenes are self-contained like the scene itself can run on its own you could put it inside of anything and it would be fine there so see that was part of the problem with our earlier sword button is that it was it was connected to the battle scene and coupled to it and it wasn't its own scene at the time it was just a node so we kind of got away with it for that because you couldn't run that node it wasn't its own scene but it wouldn't really have worked the way that we had set it up and signals are actually a pretty good way to for nodes to talk to each other because certain things are higher coupling than others and certain things are lower coupling now if our sword action button right here for example we're currently using find node which is a signal that will which is not a signal a function that will it will it will attempt to find that node and then if it can't is just like well I couldn't find it so no big deal right but if we were using get node like this if we run the game normally it's going to work but if we run this scene on its own it's going to break and we're gonna get errors and the reason is because get node is like um that nodes not there I couldn't find it and so I I have a solution to this problem and I'm honestly not sure whether it's like the best solution out there but it feels like a better solution so let's actually bring up an image here so let's talk let's let's kind of visually show what coupling looks like right so you've got some different objects in your game some different scenes you I'd say and some of them need to talk to each other so maybe these two need to talk with each other so you have a signal like this and maybe this one right here needs to talk with it and there you go and you've got a few things that are talking with each other right this is a this looks like a game with low coupling but what if you have a game that you know looks like this where everything is talking with everything else it gets really really ugly right and by talking with sometimes I mean accessing directly so you know this object needs access to the player and everything's accessing the player everything is touching the player and this is this is really bad you want to try and avoid this as much as you can and that seems quite obvious right but let's go back to our game with low coupling so let's say we need let's say we need let's say a lot of things need access to the player because in a lot of games that's true right stuff needs access to the player so let's say this is our player right here we'll just put a big p on this one for player so a lot of stuff needs access to it well I have a solution well one solution you could do is you could create a global singleton variable that accesses the player directly and then everything else in your game would have access to that global singleton right and the reason this is there are some benefits to this solution like first of all let's say you change where your players located or change the name of your player right let's just remove this for now then you only have to change that direct access one time right here you only have to change this and then everything else just accesses the reference to that inside of the the global singleton but the problem with this system is that it's a global singleton and Singleton's are their global that everything has access to it and not everything needs access to it you know a lot of a lot of things in your game might need access to the player but everything doesn't right everything doesn't need access to the player and that's the problem with global Singleton's like this however let's say that let's say that this object right here this one and this one and this one all need access to the player but the other ones don't right well instead of creating a global singleton we could create a resource or a scriptable object and that resource would have access to the player it would have a reference to the player we could then choose which scenes inside of our game needed access to the player and give only those scenes access to that resource right here and in their script they would actually load the resource at the start at the very top of their script so you could whenever you open up a script you could immediately see what that script had access to like oh it has access to the battle units resource which would include maybe the player in the enemy and this is what we're actually going to do and like I said I don't know if this is the best solution but I think it's a good solution and if you guys have different alternatives to how to solve this problem I'd love to hear them in the comments so let's get started let's set this back to fine node for now and this back to find node so we're going to create a new script oops I want to clear clear the area messages here we're gonna create a new script so let's come on script file new script and this is going to inherit from resource like that and we're gonna call this script battle units like that now inheriting from resource this is kind of like extending Godot in a way we're kind of almost adding new functionality to the engine almost like an add-on or a plug-in or something because we're going to be adding a new resource type because if you right-click over here and do create new resource there's lots of resources you can create write scripts textures font style boxes all teams the stuff that we've done over here we're gonna be adding our own custom resource now we get it a site what it's called and the way you do that is with class name so this resource will be called battle units okay and this resource is going to have a few variables it's going to have a player and it's going to have an enemy and we're gonna set both of these variables to null and we'll save okay so this right here this didn't create a resource though it created a script and this script because of the class name right here this script is what tells Godot that we want to add a new resource to the game so we can save and we can now come over here and right-click and do new resource and if we type in battle units you can see our new resource type and we can create it we'll call it battle units tre s-save and now we have this resource down here we have the script that allows us to create this resource and then we have the resource that we just created now the first thing we need to do is make sure that the resource has access to the player and the enemy so it's got a reference and the way that we do that is by having the player and the enemy directly give give the resource access so first let's come into player stats and up at the top we'll do const battle units equals preload battle let's see [Music] GREs let's hope that works okay and then we'll have down here after our setters will have funk ready underscore ready battle units dot player equals self so we're giving we're giving the battle units access to us however we want to make sure and remove that access if were removed so func exit tree battle units dot player equals null so if this node exits the tree then we'll remove that access so if we have our diagram here again we've got our player right here and we've got our resource right here when the player is added to the scene we connect up with resource and we tell it how to get access to us but then if we are removed from the scene we remove the access that's what we're doing we'll do the same thing with enemy and I'm just gonna copy this come into enemy and then we can say after our setters and getters underscore ready [Music] battle units dot enemy equals self under exit tree battle units dot enemy equals null there we go Save now we've given we've given we've give we've connected our player object and our enemy object or node I should say or seen whatever to our resource now we want to give access to we want to give our Reis we want to give access to the resource to other things one of those other things is actually the enemy well the enemy already has access you can see up here you've already got access to the battle units resource so now when we're dealing our attack we no longer have to get the player the way that we did so if we come down before we had all this target nonsense going on we can remove this remove this remove this and instead of doing self target we can just do player why did I call it player should we player stats let's just let's just fix that so we'll come into battle units player stats maybe I should just just call it player because I've been doing player the whole time let's teach that if you do control shift let's see control shift F you can find player stats and we can replace this yeah we've got a lot of locations where we were doing player stats you could do find/replace and that's how you would do it control shift F but let's actually not do it it's too much work let's fix let's fix this one control shift F let's fix player except we want to do whole words player right here we'll just change this to player stats and this to player stats there we go okay clear this so all we did was come into the player stats GD and replace battle units player with player stats and we also did it in the actual battle units GT so now our enemy will have player stats dot it will have battle units dot player stats dot HP - equals four but you want you don't need to because there's no way to destroy player stats but you could have a check to make sure that it's not null before doing that so there we go the enemy now I'm just targets that directly will need to change attack here because attack if you this is one of the areas where we have coupling right if you come into our battle we're calling attack on enemy like this and we can remove that like that and I think I think we're going to want to give battle access to the battle units as well so Const battle units equals preload battle unit stop T R yes and then we can say var enemy equals battle units dot enemy and we can say var player stats equals battle units top player stats and then we can get rid of these direct accesses right here it doesn't really matter as much for the player stats but for the enemy it matters because we're going to want to be doing we can get rid of that now we're going to want to be doing different we're gonna want to be able to have different enemies and if we access the enemy directly up here then we're gonna have to update that access each time we add a new enemy which technically will be doing that with battle units but with battle units it's going to do it automatically it's it'll be inherited now whereas we would have to do it manually if we were to do it this old way so I don't feel like I explained that very well but basically our new the new enemies that we create will inherit from this enemy scene which means they will automatically update the the battle unit enemy when they're created and when they leave the scene so this only allows for one enemy at a time but that's what our game is designed to do and I've actually used the same system with with a scriptable object like this or a resource for having multiple enemies as well it just has to be modified but this game only needs one enemy so we're gonna make the system work that way so once we have access like that we can then so we've given a couple things access right now if you look at our thing here we also have battle which now has access to this as well so it has access to the player in the enemy there's one other thing that needs access in our game and that is our action buttons so if you come into if you come into the action button GD we want the base 1 action button Gd we can do const battle units equals preload [Music] battle units dot TR yes and then we can just save and then we come into sword our sword action button and right here instead of trying to find these we can say battle units dot enemy and battle units top player stats so then we get access this way and that's the only one I think we need right there then we come into our heal action and once again here instead of using main dot flying node we can do battle units top player stats and we don't need to get access to main anymore right here and we also don't need to get instead of our sort action button we also don't need to get access to main anymore right here we do need it down here though but this is this is not a this is not a bad way of getting access to main right there so then now our this is battle be TTL battle this one over here will be action buttons which will just do a B now they have access to them as well however once again if we need to change these in any way we only change it in this one spot and then everything else still accesses it directly and there we go the everything should still work the way that it was set up before oops I accidentally double clicked on it so I didn't get a heal there but that's gonna be it in the next video we're going to be creating some new enemies some different enemies to add to the game and thank you all so much for watching this video hopefully you learned something and let me know in the comments if you have any other ideas for how to solve this problem in Godot any better ways that you might go about it and I will talk to you all later
Info
Channel: HeartBeast
Views: 10,373
Rating: undefined out of 5
Keywords: pixelart, pixel-art, lets pixel, pixel art, Pixelart, Godot Engine, Godot 3, Godot Tutorial, Godot Game Engine, Godot 3 Engine, Godot Engine 3, Tutorial, Make Games, gdscript, Open Source, godot, game development, game engine, godot tutorial, godot 3, open source, godot engine 3
Id: 900MO07hq1A
Channel Id: undefined
Length: 23min 10sec (1390 seconds)
Published: Thu Aug 15 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.