Delegates | Implementing a Game Phase System | Section 2 | Part 2 | Core | RTS Framework | UE5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello in this video we're going to start on our game face system before I do that I just want to cover off on some things that we'll be using for the game play system so the game phas system is going to rely heavily on the use of delegates so I thought I'd just cover a little bit about delegates and how we're going to use them so delegates are a method for implementing what's called The Observer pattern so you can look that up it's just a generic uh coding practice that they call pattern there's a whole bunch of them and delegates is an observer pattern so what's the Observer pattern Observer pattern is where an object maintains a list of dependence so the object is generally called the subject dependent are generally called observers it sets up what's called a one to many relationship meaning that you're going to have many observers subscribe to one subject and these observers are subscribing to the subject so that they can be informed about some sort of State change or an event that happens you often hear delegates reference to as events and I think unreal even may still have it in I think maybe they're phasing it out but they had a delegate set up where it was called events so when a Observer registers with a subject it's defin you'll hear it referred to as binding or being bound so the delegates bound or something like that and you can see an example there of uh two the delegates being uh assigned The Observer will Define what what it wants to occur when the uh notification comes of the state change so in that example there it's they're both executing a function when the uh subject notifies them of their change or the event and the the subject notifies The Observers through what's called a broadcast here it referred to as executing the delegate or an execution and it's but the actual uh but in un really actual functions called a broadcast you can see an example there on the multigroup command execute and a broadcast can include variables so you can see there it's passing the actual command variable whatever that is you can pass whatever variable even object pointers and things like that any variable so there's two main types of delegates in unreal there may be others but they're um these are the two main ones so there's multicast delegate which mostly is just used in C++ and the only difference really is that it allows uh static binding so that's like to a static class means you don't have to have an instance of the class to uh execute that binding and then Dynamic multicast delegates they're designed to be integrated with blueprints and they could be bound to blueprint functions so if you're going to be implementing you know um delegates from C++ into blueprints you want to use the dynamic B delegates so another thing I just want to cover is the concept of left value and right value and you may see these in some errors you get sometimes the R value and L value terms come up and I was always confused about this when I was learning what what's an RV value what are you talking about r l value so we're actually going to use an R value in the without delegates so all the R value means is is it's the right value of a a variable declaration so if you have you know a Vue called int or sorry VAR type of int and it's called value and then it's got the sign and it's equal to 21 then 21 is the r value so it's that temporary temporary unnamed value for that instance on on the right side of the variable assignment and it's temporary because it's it needs to be immediately used so it's it's going to turn into an Al because we assigned to that variable that we just called value and then alvo is the left side of that uh variable assignment so it's it's generally an expression that refers to memory location It'll point to a physical object or variable and it's persistent so you can modify it over time it's like every variable we assign in like if you assign a variable in a H.H file then that is an L value and it's you know you can access it at any time and later on where are values come in is they're often using something called move semantics and move semantics is used to efficiently transfer ownership of a resource without copying it so it's only temporary so you have to do this straight away but you can change who has ownership of that value we're going to use move semantics to allow us to execute Delegate for a single Observer or combine that Observer into the uh main broadcast so if we have a delegate that has its broadcast list so we have a subject that has a broadcast list and then the Observer comes in and and as it comes in we say okay do we want to add this Observer to the list or do we just want to tell that Observer to execute that delegate straight away so by doing that we can execute the delegate to a single Observer or we can add it to the list and call it for everyone on that list later on so there's some complex topics there I just thought it was it's worth putting out there the more you hear it the more you get to know it but now we'll move on to setting up our game phase system so moving on to our game phase system the game phase is just series of stages that we move through in the back end of the game so we'll transition from stage from each phase and then the reason why we need the the phas is so we can handle different actions required to prepare our game at different time so it'll allow us display different things at different times and then transition through the game just in an orderly manner and the phases that you need is going to depend on your game type really however the system we'll be designing here is completely flexible it'll only use the phases we need for particular game type so we're going to be using our game data to determine what we need and what we don't need and then essentially the things that we need to load we'll register with the game phase system to say hey I've got a task I want to complete in this game phase and then if there's the game phase system we'll check is there any tasks to be compl completed in this phase and if there is it'll wait until they're completed and then it will go to the next phase whereas if if there's no task to be completed it's just going to skip straight to the next phase so this eliminates the need to statically Define what phases you're going to go through you can just have a general list of phases that you're going to need and you don't need to add or remove phases because phases that uh won't be used will be skipped in any case so I think we'll start with setting up our enum for our gam phases I'm going to create that in a separate H file because that's how I usually set up enums and strs so I can just include that file in any one file I don't have to include the class that I need to so we're going to create in the data file we're going to create a file going to call this RTS core data types H at the pragma once which if you're not aware of what that means it means uh to only load this file once class once if it's included in multiple places pretty sure that's what that does we need a a generated reference here so going to include uh the name of the file RS call data types do that but then we need it doesn't need to be the H CU that's referencing itself it needs to be the generated H and now we're going to declare an enom and it's going to be I'm going to prefix my enams with the plug-in name as well just so there there's never any overlap between naming between the plugins or the project so it's going to be erts cor and call it game phase date so we're going to have a few phases here so we the first one is I just want a generic phase so I'm just going to call it loading generally when you have an enum you you should have a a value that's nothing like it's not that thing so it's it's like a default value so you know it hasn't been said or something so that's what loading will be for us here uh I'm going to have new game you can call these whatever you like it's this is just what I've decided so load game data I probably should describe what these are put in uh this is the default BAS this one is this is just indicating we've just started a new game load game is pretty self-explanatory next one initiate so we've sort of done all the pre preloading of the so basically we've loaded the game data but now here this is where we want to create menus and do things um create menu host session things like that have another one called setup reference to like game set set up so we may have this is more like a Lobby before the game fire settings or some sort of setup U uh now we'll have sort of going into the game phase now so we're going to have a preload phase where we load the game actual game data so we preload assets or or and and or data required for this game type and then prior to we'll have a pregame game play which is then we can use that loaded data to for on anything that we want to for like units or players and it'll be just any pre-configuration prior to actual game starting so let's call it that let's call it pre configuration before game play we're going to have our actual game play then so that is just where the player playing the game game play then we'll have post gameplay so post gameplay you know you might want to show some sort of end screen or stats page or whatever and then we're going to have a a phase so this phase uh this phase will be such as when you like just press Escape menu and exit the game all right so that's our phases defined go back to our game State the first thing we want to do is have a property here uh replicated that is our game state so we'll make that replicated using we'll have that on rep be ANS core name phase so that's for declaration actually no I won actually include it that's our H file and this will be the game face date and I'm going to set a default here so I'm just going to call it and it's going to be that loading phase yeah the first phase so I'm going to create a private section here and I'm going to put our I think it has to have a u function on rep usually when you're referring to something in a U property it requires a u function this and we can Implement that that so what I want this to do is broadcast that the phases change so we're going to create our first delegate and we're actually going to pass parameter so come up to the H file and after the definitions here we're just going to put play multicast delegate oh sorry one pram actually Define how many parameters in the uh macro there all delegate names only start with a prefix F like just like a struct so I'm going to call this on game pH changed delegate but this this is just a name you can call these delegates whatever you like I usually prefix the sorry always say prefix suffix that right I can't remember they suffix the name with delegate so I know the difference between the actual variable for the delegate and the delegate itself so show what I mean a sec so we're just going to pass a g face state so one difference with the multical St is in the definition you don't Define the you just Define the type you know name of the variable so uh and then down here we want that to be copy that and I'm actually going to have protected delegates and I'll and then I'll have a a public function that's like a getter for the delegate so I'll just find the delegate here and then this is what I mean I just I'll just take off the F and I'll change off the delegate and there's no confusion about what's the the variable and what's the actual delegate same name you can match it up easy no confusion and then in the public section I'm going to copy this again going to I'll put a description here this is going to be the delegate Getters it's going to return a reference and it's going to be I'm just going to call it the name of the delegate and I'm going to put check what we're going to do is we're just going to validate that delegate or return it delate and we return we get a reference to the delegate and then we just put it through check and that'll uh cause a break point if it's not okay so we definitely know that that delegate is valid and then we can use this to bind to the delegate wherever we need to so then in our on rep and broadcast that and I can pass our game play State whatever that is at the time it would have just updated as this reps oh we need to add the replication well duplicate that each time the game p changes it's going to broadcast this the state out to whoever is listening so now we're going to have to run some sort of system that checks the state all the time and if there's any tasks that are outstanding I think ticks a bit Overkill so what we're going to do is we're going to just set up a timer that starts so we'll do that in begin play we want the St the time to start straight away so we're just going to check we are the server the uh Game Face system is only going to run server side so if we have authority and then we can start the FaceTime so let's create a function for that deted void start game pH ni and obvious what that's going to do then in the start game phas timer we're going to check that we have a world reference cuz we're going to need to get the time manager here we're going to need a handle so let's make that private pull it sorry it's timer handle or timer handle timery that and it's going to be bound to this object and we're going to execute a function uh which we'll just call Game Face timer this is what's this will be the function that's called each tick of the timer and we'll set the in rate to be know half a second or we could do 1 second let's just do it as one for now we can we can optimize this to whatever works and then it's going to Loop and we'll put in delay of 1 second at the start just so got of other stuff going on in begin play Then time to sort itself out this automatically changed to start so I don't want that I want to be Game Face timer and I need to create that function so in here we basically want to run a Check should we start the next phase and if we should start the next phase so we're going to need a couple of functions for that so we're going to need should and start Bas Implement those in our phase timer we're just going to go if should and I need to change change that to return a ball this should return a ball and then if we should start the next phase we will start the next phase so now in the should start next phase this is where we need to check if there's any outstanding tasks for this phase what we're going to use for tasks is a struct and we're going to use a good to as like a reference like an ID for that task so let's we we'll have a map for that which will be our reference so I'm just going to create this first even though we don't have the struct created is going to be a tmap it's going to have f it as the key so that's we'll be able to use that to look up a a task like unique identifier for the task and then we're going to have a fbas registration data so this is what uh other classes and things or anything really that needs to do a task in a phase this is what it will register so we'll call this the phase registration registrations a big time so let's create this struct and we'll go back to our data types and we'll say UCT call it FS pH registration data so I'm just going go back iot to add the the core in front forgot that part so in this struct we want to have a reference to the phase that this task is a going to be applied to so that's the game face we're going to have some we'll just put in some text so we can it's probably more used for debugging this so I'm just going to call it um yeah text and this will just be some sort of description of uh like who the who's who's the task belong to and what's it doing sort of thing so we can display that in a debug message or something and then we'll have a bll for whether it's complete or not I'll call that we want a Constructor for this so have and we just initialize this it give us some defaults so this is a blank Constructor this first one this will just be it'll keep it happy uh we're going to make this loading oops and we'll just make the text a blank string that duplicate this so this will be a Constructor we can use to just pass in all our parameters and having existing data so in here we want to pass a c game phase and we'll call this in game phase we want to pass a con reference in text we want to pass in the actually no we don't need to pass in whether it's true or not it's we're creating a a new task it's always going to be false so we can just it to false which it's doing and I think that'll do for that let's go back to our game State and in our should start next phase we're going to create a an iterator over registration so let's just put in a comment here check if all the registration tasks for a current phase are completed so we're going to create a constant rator for the on the on the map we just uh we just made so that's the phase registration data and we're going to create a con iterator cuz we're not changing anything we're just checking and now we need to check if the game phase that we're checking is the actual current game phase so if the current uh value game phas so that's now that's reading our struct so we're reading the structs game phase if it's not equal to the current uh so we need to get get have a ghetto for the current game phase State we can make that con we'll come through I'm going put that up here it's going to be ER RTS core case state is what we're going to return and it's going get cost return name pH we're going to use in our function here if that's true then we're this current registration that we're checking is the current game phase and then we want to know if it's completed or not going to be same if the Val uh sorry if if it's not completed we want to return false that we should not start the next phase is what we're going to return if it's not if there's an outstanding task and as soon as we find one outstanding task then we can just return false because we don't need to check anymore but if we get through this whole Loop and nothing returns false then we know there's no outstanding task for the current game phase in this here we we already know we're changing to the next phase so we want to increment the phase and then we're just going to do a check if the phase is valid because we have like the abort phase and we may have some others that we don't want to actually automatically transition to call them special phases the abort phase is a special phase we only want to abort to that if we deliberately say so we don't want to just in sequence end up in the abort phase going to create a next phase in index and the cast of the current phas and it's we're just going to add one so so this is going to return the next phase of the current phase in in 32 format and then we can run our validation first so if the next phase index is greater than should never be greater than right cuz the Bo's the last one but we're building that in to check we might have something there later on and we're going to cast the abort phase so we want to know if it's equal to or greater than the bort phase and if it is then we've we've reached the end and we don't want to transition to the uh abort phase so we're going to so let's create a Setter now for our game phase uh we'll make that protect set G and we're going to pass in the if we're trying to go to the B phase means are at the end so we're probably coming out of post gameplay so we want to return to like the main menu or what so let's send it back to uh load game data and this is where we could do something different here we could have the end of the game go somewhere wher we have it go back to a Lobby or something like that maybe for now I just might turn it back to new game actually and if it's if it's not at the abort phase then we just want to set the phase to the next index we're just going to game phase State and we're going to cast that int that we calculated to whatever date it's uh up to so to set the game phase State we want to check we have authority to do that uh we probably should put that here too so nothing can start a next phase or something like that and then here we just want to check that the phase isn't already the phase that we're passing in because we don't want to go broadcasting the phase thing again are the phase delegate again if it hasn't changed that could result in some weird Behavior so we just want to check that the new game phase is not equal to face and if it isn't then we want update so gals new G now CU this is running on the server we need to call that on rep manually blueprints you don't need to do that but in C++ you do so I'm going to leave this part here we got the game phase set up and Ticking over so in the next phase we'll start implementing our delegates and registering our tasks so we can test our phase set up
Info
Channel: Rogue Entity
Views: 353
Rating: undefined out of 5
Keywords: UE4, UE5, UE5.1, Tutorial, Programming, C++, Game, Gaming, Game Design, Game Programming, Game Audio, Game Art, Game Testing Game Engine, Game Production, Game Industry, Unreal Engine, Game Development, RTS, Framework, Plugin, Game Phase, MatchState, Match State, Custom Match State, Delegates, rvalue, lvalue, What is a rvalue, What is a lvalue
Id: ipCHyJ2fmEM
Channel Id: undefined
Length: 26min 14sec (1574 seconds)
Published: Fri Jan 05 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.