UE4 - Using Blueprint Objects instead of Structs for efficient data storage and manipulation

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone my name is chris cook i'm a game designer working on this game in my spare time one of the features i've been using which i very rarely see anyone else use is objects inside blueprints so an object is the lightest clash you can basically make in a blueprint um actors and everything else all derived from it um but objects are really good for storing and manipulating data as well i've been using structs a lot i was using strokes a lot basically store data and kind of try and manage that data set up like a list of villages and i added this to a struct but then each villager would have their own strokes inside of like all their data and stuff and for anyone who's used strokes especially necessary strokes and blueprints you know how unmanageable it becomes and how difficult it becomes not only to access data but even more so to modify that data inside so much so that it became just unreal and it didn't become viable anymore for me to use so what i've started moving over to is using objects um so an object is something that you can add data to but one of the powerful things about an object is it can have functions inside as well to run its own data sorry when it's on uh yeah manipulation of data and and you can grab data from it and stuff so like a struct you can have as much data in the objects as you want you have as many variables in there like i said before you can then have functions built inside the object to control manage access that data which means that you don't have to have those functions dotted around in different blueprints trying to control it you can basically have it on that single object reference the objects and callers functions and it will manage that data for you so if i show you how i'm using it i'm using them to add modifiers to my villages and these modifiers are all event driven as well which is the powerful thing about the objects so that for example here um this settler here uh she has nowhere to live at the minute and that adds a modifier on this modifier which is i have nowhere to live which modifies our happiness by 10. this this is controlled inside an object so that object is basically added to her um and then every time we're trying to reference our happiness which is basically look through the objects and find out the final result of their happiness um but in here if i it's the instant build and we just build a house and then we assign it to it you can see now that that modifier has actually removed itself it's gone back to the base happiness of 50 and a new modifier has added itself on automatically which increases our happiness by five which is i have a house um and again that's event driven and what it's doing in the background is it's similar to like a stroke but it's listening out for a for an event in the world in this case if the residency changes if it is it basically just removes itself and we add another one back on afterwards so you can see now again back to the base 50 but then we had another modifier i have nowhere to live so it reduces that to 40. and i'm also using it first off like sickness modifiers as well so hopefully she'll get a cold because she has no clothes and no house and it's freezing cold there we go as i called um so now if we click her you can see that she has nowhere to live minus 10 but we had another modifier on top of that as well which is now i have a cold minus five um this one contains some more logic as well so when it's initially first added it also reduces that village's health and health isn't like the happiness where it's the best value and goes up and down based on the modifiers the health is a static value that you affect it and it stays like that until another action happens for example healing or something like that so after a while um that modifier i've got for the cold is actually running logic in the background and ella's event driven it's also listening up for a dispatcher as well to count up time uh and once she's healed enough that curl will disappear and again it'll just remove itself and the happiness modifier will go back up um yeah it's just it's really really powerful um so if i show you an object is so if you want to start off by basically creating an object the first thing you want to do is create an actor um create a new blueprint class but instead of like choosing an actor or a pawn or like this you want to open this here might be hidden and choose an object and again this is this is the base class so i just call this test good old test uh and show you this here um so in here you'll see almost look just like a normal blueprint like a normal actor except it's parent classes objects but probably the first thing you'll notice is when you're trying to add an event for example like begin player tick etc all that stuff's gone like that they're all contained within the actor that's that's called containing the actor class because this is derived from the parent of the actor class which is the object we don't have any access to any of that so stuff that i have to so i i've got around this by basically creating a new event and i've called it initialize and then when i create these objects i just immediately call the initialize event and that's almost like in beginplay so when it's constructed i call initialize event and i do any logic i need to in here and like before like i was saying um like this is similar to a struct what i meant is that in here we can have um you know or any kind of variables so just imagine you're destruct with like an instrument is alive etc these are all as variables that you would normally have types of inner struct but again as before you know if you wanted to have um an uh changes data on this structure if you wanted to say for example um get is the player alive you'd have to get this struct break it open grab that variable and check it and if you wanted to change that variable is live you would then have to do like set members in an array again it could be quite difficult uh in here you can just basically have you know set player is alive and have a boolean here um alive and then you can just quickly call this um event and this can do stuff like you know like this um you could do um kill player and then this could be basically a set is alive to be false but then also you know remove the amount of lives in here as well um and again if you're trying to use instruct you'd have to grab all this data and settle this data through a long lengthy process and each blueprint has to do with its own kind of um functions on this on this data as well so become really difficult to go through and manage uh and again this gets exponentially more difficult for some things the strokes are fine like the good quick quick way to start transfer data over blueprints and stuff but when you've got a lot of data like i do this becomes unmanageable and when i say a lot of data i mean for example you know if we look at all this all these variables i've gotten here these were bought before all you know this job would be a struct with all this information in here i had a bio of all this information but all this would be kept in the structure itself so it would have struck with instruction became incredibly difficult if i wanted to change like the job level or drop xp i'd have to grab this struct i'd have to open up grab the job stroke to open that up look at the job level set the member array in there and it was just yeah crazy um so yeah that's how you basically create an object class and i'll show you how i basically add them um so i have here this um so this is h mod stands for happiness mod um and you can basically ignore this part but basically you do this they do constrict objects from class and then you choose so this will be this will almost highlight everything because like before everything is derived from an object but what you want to do i should have got this bigger than the test because there we go so this is this basically is constructed this object that we create here and then again you can do stuff as well so you can expose these just like a normal blueprint and if i refresh these here you can you can set these on by default uh and then again because these that have um events uh like begin players like that when i also create them as well i will then call initialize and that's basically calling i can't begin play on there but as i said before light strokes as well these can also be date driven and event driven stuff oh yeah one more thing before i forget as well so one of the benefits but also downsides to objects is that they if they're not referenced by anything they will be removed by garbage collection so for example here i have a map you can have an array you can have it it's just a single variable it doesn't matter really how you hold it but it has to have a reference to this so if i were just if i was just to create this like this this doesn't go immediately because it's not referenced by anything i have to add it here and then it's stored somewhere and it'll be referenced and the power of that as well is that if i wanted to just basically remove if i remove this object from this map here and it's not referenced by anything it'll again it'll just be cleared by guy reflection and it'll be removed from the game so it's really light and really efficient um so yeah here what i'm doing here is constructing uh the objects that we talked about earlier but in this case um i've got this other one here this happiness mod base and i'm creating that initializing it and then in here so this one if what if i show you uh this one here so this is one that gets added to my villagers on begin play when they're sorry when their first build uh spawned in the game and this initializes it so basically i'm binding to an event and again this is something you can't do on strokes um i'm binding this object to an event on my villager so here as soon as it's added grab my villager basically because they find me to this event this settler resident is updated and like i said all i have to do is just add this object on and i just forget about it and then this keeps checking every time this residence is updated so in this case you know if he becomes homeless or he moves into a house or changes house this will trigger so again it's really light there's no tickers no background kind of churn it's just only if it ever changes residents i then check minus one means a homeless are you homeless if you are then i call this event which just removes so just just goes into the villager blueprint removes it from that array and again the gap section let's remove it from the game completely so again super light i can just basically just listen for events and i do the same um for residents as well so if you're a resident i just add this one um and this just listens out to if you're homeless and if you've if you're homeless it listens out to if you're not homeless and it just basically removes itself um and then i have similar ones for sickness as well so this one's um so as i said before they don't have access to tick or you know you can't do delay you can't be timers um but what i can do is on my villager i have a i have a timer which also triggers a dispatch um this is basically used for a you know it's a long time which basically ticks down a lot of stats so like you know happy that's not happiness hunger will start dropping down based on this just about uh this this um timer but i also call um this dispatcher and it's just basically piggybacks on there and it increases healing and once the healing's got to a certain amount can we remove it so if you get a cold it adds itself on and it just takes up over time and once that values go to a certain point again it just removes itself and it's all done in the background i just add this object on and i remove it when i when i don't need it anymore um but yeah in this cold one here you can have you know as many variables as you need you know you can you can really change this and um similar as well you can also have these randomized at the start so every time you get a coil for example you can have a different kind of severity and it could be quite as a vehicle it could be quite a mild cold uh and this can be chosen at runtime when you basically create this so it's all again kept in in a single object rather than having to have that data and those functions scattered around your blueprints all over the place um so this is an example how we might use a structure to hold information uh and also change that information as well so for example we have this custom event here and this is basically trying to grab the power-up level which is held inside the struct and it's structured just basic variables that you'd find in a struct and inside there is another structure with the power up and here we have the part name power level and here we're just trying to increase that level and you can see here we have to like break open this twice we have to get the value we have to set it and then set the members again and again a lot of places of failure you know any any one of these could break or change at some point um and then to get the vat to get the variable information we have to do this where again we have to get the um struct break it up and break it up and then you get the value and it just it's just a lot of work to just change your values inside a struct and i want to show you how you can basically use an object to do that kind of same system but a lot easier and again less points of failure for example you're having these functions inside the object itself so you can call um increased power level anywhere and it will just ruin that single function so you only have that one place where it could ever it could break um so i've actually created an example object already kind of similar to how i showed you before and then here i've got the variables that mimic the variables that we found in that struct and then here all we want to do is you know have our event create objects and then here we just construct our objects from class and we choose the example object that i just created outer just put itself and then promote this so it doesn't get taken by a cabbage collection object so here immediately we have an object which has the same variables as our struct you know for example here the power level we can easily just immediately set the defaults as well the difference is for example if we wanted to do this event here this function where we're basically increasing the power level um we can have function here which is just increase power level get this increase it um and that is basically the same as this so here all this we can just basically grab our object and just do increase power level and that's calling the same as that and we can even you know have it so it prints out the meaning level um and back in here we have this so we have this value you know and then we can always use this to trigger extra stuff um you know if we want to get the power up name we can have a think function here just get our name uh set it as pr as well and then we can just have the output and then we can up here just copy subjects just get our name and provides us this one thing i would suggest doing which is just good practices as well it's really just setting all these these to private um you know and then using unless you know there's only gonna be some one place and you're quite confident nothing's gonna change that you don't expect to it's always good to set it private um and then here we um we can't actually get the powerup name itself we have to go through this and this is really good especially if you want to set data as well it just means that it's all in a single place and if you ever need to do anything so for example when someone gets this power up and it doesn't have specifically when it gets power up level maybe when i always call another event you know it's always done in a single place um but yeah and then as before you know if you want to finish off and get rid of this strut you can just basically set it to null and then that will get rid of them um or you can even add these to an array and you can have you know hundreds of these these objects as well i use maps because then you have keys and easily find them as well um but yeah that's that's basically how you can use the structs for the same way you would use a i'm sorry using objects for the same reason you use destruct so yeah hopefully that explained objects um how i use them how you can use them um you can as similar to strokes as well you can send these other blueprints as well uh you can save these um using you know blueprints vanilla blueprint saving system super super lightweight they do have limitations as well but no different to strokes so if you are going to manage a lot of data in your in your game i would highly advise you to start using objects that honestly really really powerful um cool so yeah if you have any questions um give me a shout um you can write down this in the comment section below and if you can please like and subscribe as well hopefully more people will find this and we can start moving people over to this system which is yeah really really powerful bottom brilliant cheers guys you
Info
Channel: Meeki Games
Views: 14,613
Rating: undefined out of 5
Keywords: ue4, Unreal, Unreal Engine, Unreal Engine 4, Behaviour Tree, Behaviour Trees, Scripting, Blueprint, BP, Blueprints, Game, Gamedev, Game Design, Games Design, Development, Indie, Indie dev, Cel, City Builder, City Building, Project, Gaming, art style, click, RTS, builder, Banished, developer, dev diary, diary, Tutorial, Guide, Blueprint object, object class, OOP, struct, structure, ue4 object, ue4 struct, ue4 data, data management, blueprint struct, event driven, actor, dispatcher, variable, var, UE5
Id: HpUhfnHCENQ
Channel Id: undefined
Length: 18min 47sec (1127 seconds)
Published: Wed Dec 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.