Delegates - Unreal C++ Course #15

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so we have something that halfway resembles a game we've got an anime that will shoot at us it will look at us I'll show you what I did to change that in a moment and if we get too far it will chase us down before it starts shooting at us again so at this point you can start designing levels and you're pretty much good to go as far as a game development goes but there's a couple of things that I still want to show you and that you should really know about but first and foremost the way I made this guy always look towards is very easy unreal has a building system for that you can set an AI focus and that will just rotate the porn towards that Focus unless it's doing something else that takes priority so if it's standing still it will always try to orientate itself towards its default Focus which I just set to the player every single time we go through this selector it's a little bit of a Overkill way of doing things but if you were to set the focus to something else anywhere else in the behavior tree it will always reset back to the player on the next Loop so today what we're going to do is we're going to talk a little bit about delegates because that's one of the more important things that I haven't really covered yet and what is a delegate well a delegate is if you're used to working with blueprint it is the C++ version of a event dispatcher it is moral less and I'm going to go into a blueprint here things like the undestroyed this one event destroyed is an event that fires based on a delegate whenever we use the destroy actor node that fires off a delegate that then fires off this event so if we uh for instance say um on begin play we destroy the actor and then on destroyed we print a string right that means that immediately when the game starts this exor is going to get destroyed and as a result it's going to print out a string saying hello and we can see that is the case so this is not directly hooked up to this but still it's running that way and that's the way um it works in Blueprint but we can also do that in C++ and there's a bunch of pre-existing events in blueprints that you can use like event possessed that's also a delegate which fires whenever a controller possesses a porn and so on and so forth so let's make a delegate and uh for now because unreal itself has so many pre-existing useful ones like undestroyed that is what I would usually use as an example but that already exist so we're going to make a delegate that fires whenever a bullet is shot from any character really and then we're going to on one of the characters subscribe to a delegate and do something with it right so let's go into our base Magic character header file and and the Declaration of a delegate we actually do outside of the class and I'm going to copy and paste uh the Declaration here because this is kind of annoying to type otherwise so what you want to type is declare Dynamic multicast delegate and then you can also uh put in a number of parameters so you can make a delegate which fires a function with a specific amount and a specific type of parameter so let's make one with uh one param and then in these parentheses we first put in the delegate name which has to start with a f so we say F uh on bullet fired delegate something like that and then we can put in the type of parameter that we want so we want to know what actor fired this bullet Maybe will be useful uh information for us to have so we can say a ector pointer and then we do something a little weird because uh then we put in another comma and then we put in the name of that parameter so unlike what you're used to in these uh functions that we uh have been using so far where we have a function and there we do a type a name then a comma then the next type the next name then a comma next type of name comma next type of name in making a type of delegate you actually separate a everything with a coma so I also made a little typo here let's call that fired ector and of course end that with a semicolon if you want to expose this delegate type uh to blueprint for any reason you can make it a u delegate and the specifiers that you can put in here are the same ones that you can put into a u function so that's I've got a page open here uh blueprint Authority blueprint colable blueprint cosmetic blueprint implementable event and so on and so forth that's not what we're going to do here right now today but you can do that if you would like to and you might see some squiggly lines under this as an error but you can see I can still compile this and this works fine after a minute it catches up and now we have this delegate to work with so let's add one I'm going to add this into the public section because that way other actors will be able to access this delegates and say hey I want to know about when this delegate fires so we're going to put this in the public section and we can just use this as a variable type now and we can make multiple uh instances of it so we can say uh onf fired bullet delegate uh fired bullet but if we wanted to we could also make a second one and say this one is called bullet fired or something like that and we could run this one in some situations and then this one in other situations we're not going to do that but you could for instance if you go into the CPP file here in our shoot bullet function we have uh two different paths here right so if we can fire we execute all this and then when we return uh this last line here doesn't get executed so we could have uh one of those delegates firing in here and saying hey I'm calling out which means that whatever is listening knows that bullet has just been fired and we could put another one in here which would mean hey anybody listening out a bullet was just tried to be fired but it didn't if that's for any reason for anybody interesting information there you go I don't see a reason to do that so we're not going to do that but that's just an example of you can use this just as a variable type and you can have as many of these as you want we're going to use this fire bullet though and we're going to put that into our shoot bullets and we're just going going to put that into the if can fire is true so at the very end here we're going to say our delegate fired bullet dot broadcast not broadcast that that would be quite nice as well um and that needs a parameter because that's how we defined it an actor parameter uh so we're going to just say this because this class is an actor so it can just pass itself through to that parameter that means that this delegate is now anytime we're going to fire a bullet as the player as an enemy because this in the base Magic character anytime anything fires a bullet it's going to just scream into the void hey I just fired a bullet any other actor that might be listening out for that which we're going to get to in one second can then say hey when you fire a bullet I need to do a thing whatever that thing might be and I can use whatever parameter is getting F through here so whatever character or whatever actor is firing that bullet I have a reference to it now through this delegate uh which is quite nice what can we do with this well let's make um something silly something that we're not actually going to be using uh but let's make something that increases in size every time the enemy fires a bullet that seems pry neat right that that seems pretty cool it seems real weird to me is what it seems like so let's make a new C++ class it's just going to be a normal actor it'll be private and we'll say uh base weird growing thing do we need that name to be so long uh no and as a matter of fact it's actually quite bad that it's so long because now every time we need to reference this we're going to need to type out that entire thing and at this point we're used to it when we make a new class for whatever reason we need to go into our U project and generate Studio files and here we can make a new function let's put that under protected here and we'll call that simply a void grow and it will be a very simple function because all it's going to do is we're going to um set ector scale 3D and we're going to set that to the get actor scale 3D um multiplied by 1.1 F so it's going to grow 10% every single time well actually maybe we don't want to multiply maybe we just want to add to it so uh we will say plus 0.1 and the wonderful thing about this by the way is if you add a float to a vector like this it would just add it to all three components so now we're going to add 10% of its base scale every single time this grow function fires but how are we going to link this up to a specific enemy because that's the thing we want to link this up to a specific instance of the enemy or the player for that matter we could also link it up to a player well first first things first in order to access all that we're going to need to include the base Magic character and we're going to need a variable for that as well so let's make a protected U property which we can addit anywhere and that will be a base Magic character pointer and I do need to spell that correctly and let's call this character to watch and we'll likely need to forward declare this so now we have a pointer to a base Magic character this can be an enemy this can be a player whatever and we can say in our begin play using that we can now access our what do we call it uh fired bullet delegate and from here we can say we want to add uh what we want to do actually is we want to add Dynamic and there we just have to pass in does it tell us a user object so the the object that the function that we're going to run exists on So in theory what we could also do is we could have one actor saying Hey whenever this character does something this other actor has to run a certain function it doesn't need to necessarily be something that they do themselves you can have a manager object that just listens out for specific pairs of actors when one does something the other one will do something as well that could save you having to include certain header files in other header files if you want to prevent that that's a possibility for the most part you would just run a function on the object that is exists on and then we need the it says the function name uh but what you do need to put in there is the address of that function this function actually um will not be accepted and I'm going to pretend like that was intentional uh because I entirely uh didn't think about that the only thing that you can put in here the only functions that you can put in here are functions that match the signature of the delegate so let's go back real quick to our uh base Magic character header file that's somewhere in here surely there we go we made this delegates to take in an acto pointer and when we broadcast it it passes through a pointer to itself as that parameter so now when we bind a function to this delegate it needs to be able to take in that actor pointer even if we're not going to use it the signature does need to have that parameter so let's go back to our other header file somewhere around here add into our grow function just an a actor pointer and we'll call that um enemy watched something like that it doesn't matter what you call it one important note though is that the function that you're going to execute through being linked to a delegate needs to be a u function you don't need to put any specifiers in there but it needs to be a u function otherwise it'll just straight up not do anything and put that in there as well that will uh solve all the issues it'll take a minute for this to uh disappear but now all the errors are gone so we can compile this and now go into the editor we will add some meshes but we'll do that through blueprint because we don't need to have all that accessible through C++ so let's make a quick blueprint here and still ignore the fact that this is all very unorganized and let's look for our weird growing thing class which is a great name and let's call that BP growing we'll simply add a um a cube I think that will do just fine and in our top down map we'll put in this BP growing Cube here and we'll say the character that we need to watch will be our BP enemy you knowe that it only has things that are children of the base Magic character so if we put in the player character for instance it will also give us this as an option in the drop down menu now while there's a bunch of other different actors there as well I'm going to actually put you up a little higher and you're going to watch this enemy so now anytime this enemy will shoot this thing is going to grow and this enemy shoots quite quickly so this thing is going to grow way out of proportion way too quickly let's take a look so now we can see whenever that thing shoots uh that cube is growing and the reason this is very very nice is because it eliminates having to have a two-way communication I'm going to stop before that thing grows way way too big so this Cube knows about this character and it has an include to that class which it needs to have in order to subscribe to that delegate but this character doesn't necessarily need to tell this Cube to do anything and as such it doesn't need to know that that Cube exists and it doesn't need to know all of the variables and all the functions on this Cube and you can definitely like imagine a situation wherein maybe 10 different classes all need to do something when a certain character does a certain thing right maybe 10 different classes all need to do something when a bus or a um a mini bus dies right a door needs to open and barrels need to explode and money needs to drop and whatever all those things can just look out for that character without that character needing to say Hey you do this you do this you do this you do this and as a result need includes to all of those different classes because as we talked about previously doing an hashtag include on top of a class pretty much just copy paste the entire header file into that CPP file meaning that it now has that entire class accessible and if that's a class that's multiple megabytes big every instance of that is going to take up unnecessary amount of memory which we don't want so this is a good way to limit the amount of includes that you need this way is just a one street communication this block needs to know about this character but this character doesn't need to know about this block so we don't tell it anything about that and just to make things complete we can go back in into our base magic class header file and this delegate can also be a U property and we can mark this as being blueprint assignable and now we can go into our blueprint and we can assign blueprint events to this as well so if you for any reason want to do something in Blueprint when a certain thing happens in C++ that's a good way to link those together as well and now they just function as an event dispatcher so we can say assign fired bullet and there we just get an event which has the fired actor variable or parameter that we talked about before and now whenever we fire a bullet we can do whatever this custom event as and of course we can also do that from a different um actor here a different blueprint so we can say begin play we can cost to base Magic character uh because we can assign fired bullet and now we have an event on a different blueprint that will fire whenever a bullet is fired so that's also a good way of getting information from C++ to blueprint sometimes between this video and the next one I would like you to make a door that opens itself when a certain enemy is defeated because I'm going to make that between episodes I'm not going to show you how I make it with all this information you should be able to create that on your own and a very big thank you to all of my patreons you can see them on screen right now if you want to help out supporting the channel there's a link Down Below in the description to the patreon page and a special thanks to my cave Digger tier patreons Serj Thomas
Info
Channel: The Game Dev Cave
Views: 4,818
Rating: undefined out of 5
Keywords: unreal engine course, unreal engine tutorials, unreal engine learning, unreal engine beginner, unreal engine tutorial, unreal engine, unreal, unreal tutorial, unreal course, unreal lessons, unreal engine lessons, the gamedev cave, C++, CPP, C plus plus, c++ tutorial, c++ development, unreal c++
Id: qX1tBA8Q1pY
Channel Id: undefined
Length: 18min 17sec (1097 seconds)
Published: Sun Nov 12 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.