Welcome back.
Now, in the last video, we've implemented a lot of things and save progress.
Whenever we call save progress, we're now saving eight additional values.
We're saving four on the player state and our four primary attributes.
Now we know that this is being called because our checkpoints are calling it.
If we go to our checkpoint in the private folder in checkpoint in on sphere overlap, we're executing
the save progress interface function.
So we know that this stuff is being saved.
We just have to load it now.
Loading it is going to be done in our character.
And I'd like to do it in Possessed by.
Because at this point we know we're going to have a valid attribute set and ability system component.
Now so far we're calling add character abilities and init ability actor info.
Let's think about how we're actually initializing our primary, secondary and vital attributes as well
as our abilities.
We can go and look at an ability actor info.
Let's take a look.
Here it is for the character.
We're getting our ability system component initializing it.
That's good.
We're casting to our ability system component.
We're setting our ability system component and attribute set subscribing to on as registered.
Taking our ability system component, registering a gameplay tag event to debuff.
We're getting our player controller and knitting the overlay and then initializing our default attributes
here.
So it's an innate ability actor info that we initialize our default attributes.
Now we're going to do this from disk provided that we have saved data.
So we're going to go back up to init ability actor info in possessed by.
And notice we also have on rep player state which is doing the same thing.
Now these eight variables that we're setting here are replicated.
But again we're saving to disk.
This is a single player solution.
In multiplayer we would be retrieving these from a database right.
So in init ability actor info I'd like to remove completely what we're doing when it comes to initializing
our primary attributes.
So down here where we're calling initialize default attributes I'm going to remove this now because
we're going to load it in from disk.
So we can go back to possessed by.
And now after init ability actor info.
Our primary attributes won't be set yet.
Now we're going to want to add character abilities from disk as well.
So this is another thing that we're going to want to change.
We'll have a to do let's say to do load in abilities from disk.
So we'll get to that when we figure out how to save our abilities.
But for now we want to initialize our attributes.
So let's make a function to initialize our attributes.
Let's actually make a function to just load in our info from disk.
Let's make a function here on or a character.
And this can be a protected function.
And we can call this load progress.
So let's generate the definition.
And I'm going to put this right up there by possessed by.
So going up to possessed by.
I'm going to put it right underneath.
That way we can see it and we're going to call load progress after initializing ability actor info here.
So we'll know that we have a valid ability system component at this point, and we can handle loading
our progress here.
So what is load progress going to do.
Well we're definitely going to want to retrieve our saved data from the game mode.
So we need to get the game mode.
I'm just going to search for a game mode and find where I'm getting it down here and save progress.
In fact, Save Progress also has some other things I want to do.
I want to retrieve in game save data, check to see if it's null and all that good stuff.
So I'm just going to copy this whole if statement and go back to load progress and paste it in here.
So the only thing I'm concerned with with our save data is the stats.
For now I'm going to start setting things on my player state.
So that means I need my player state.
I'm going to say if a or a player state.
Or a player state equals a cast to A or a player state.
We're going to cast get player State.
And we'll take our player state and we'll set those four variables first.
We're going to call set player level.
And I believe it's called set level.
And that's going to be on save data player level.
Next we'll take our player state and call set XP.
We'll use save data XP.
Well.
Next take our player state and call set.
Attribute points.
Do we not have a setter?
I don't think we do.
So we'll have to go and add one.
So let's go to public player or a player state.
Let's see if we don't have one.
We don't.
We have Add to but not set.
I'd like a setter for both.
So we'll have void set attribute points.
And 32 in points and a void set spell points and 32 end points.
Let's generate these.
And we'll set attribute points to end points.
And for set spell points, we'll set spell points to end points.
But what do we do?
Every time we set these we broadcast delegates.
Right.
That's important.
So we have to broadcast on attribute points change delegate and we'll broadcast attribute points.
And for spell points, we'll get on spell points.
Change delegate broadcast spell points.
So now we have setters we can use and back in our character.
Now we can set attribute points to save data attribute points.
And we can get our player state and set spell points to save data spell points.
So that takes care of the player state variables.
But that's the easy part, right?
What about our attributes.
Because attributes should be set using gameplay effects if we can help it.
I'm going to go back into the editor and I'm going to go into blueprints, ability, system data, and
open character class info.
Why am I doing this?
Because each of our character classes has a gameplay effect for its primary attributes.
And if we take a look at them, say, the primary attributes effect for the Elementalist, we'll see
that this is a gameplay effect with our primary attributes, and they each have scalable floats, and
we're using curve tables for that given class to set these values based on level.
But if we're loading in from disk, we don't want to set these based on level, because we have the
freedom to spend points on attributes, and we need to load in our load out whatever progress we've
been pouring into our primary attributes, the points that we've been choosing for ourselves, that's
what we want to apply.
So we need a new gameplay effect for primary attributes.
And I'd like to use set by color magnitudes that we can set when applying our primary attribute effect.
And I'd like to add that effect here to character class info.
We'll just have a primary attributes gameplay effect specific to loading in from disk.
So I'm going to add one of these to our character class info data asset.
So that's going to be in public ability system data character class info I'm going to add a new subclass
of you gameplay effect.
So here's one.
So I'm going to just copy it and go down into the data asset and add one way down here it's going to
be just above secondary attributes.
And I'm going to call this primary attributes underscore set by color.
That way it's specifically a set by color version of this.
And it's going to be in common class defaults.
It doesn't have to be specific to any character class because the character class doesn't matter.
We're going to set those four primary attributes by set by color based on what we've loaded in from
disk.
So now that character class info has this primary attribute set by color, we need to create a primary
attributes gameplay effect and change it to set by color.
Well, I can go to Ability System Aura effects and get my GE aura primary attributes.
Now this has strength, intelligence, resilience and vigor.
And these are set to default values here.
And really these could just be the starting values if we're loading in for the first time.
But if we're not loading in for the first time we should have another one with set by color magnitudes.
So I'm going to duplicate aura primary attributes.
But I'm going to call this one GE primary attributes underscore set by color.
And this will have the same four primary attributes, but they'll be set by color.
So I'm going to take the magnitude calculation type and change it to set by color, and choose the data
tag to be the attribute tag for this attribute.
So that's going to be attributes primary for this one.
It will be strength.
Next is intelligence I'm going to set magnitude calculation type to set by color.
Choosing intelligence.
Next is resilience.
We'll change this to set by color and the tag will be resilience.
And finally vigor.
We're going to change this to set by color and choose vigor.
So now we have a set by color version.
And we can set that on our character class info as soon as we compile and launch again.
Now that we have this.
So back in C plus plus we need a way to apply that and set it's set by color magnitudes, but only if
we're not loading in for the first time.
So how are we going to know if we've loaded in for the first time?
Well, that's something we could save.
It's something that we could have on our load screen save game, such as a boolean.
I could put this all the way at the top, actually just above player.
We'll put it right here.
We can have a bool called be first time load in and set it to true by default.
So the first time we load in we can set this to true.
And we can check this when loading in our stats.
And that way we'll know if we should use the default values or if we should load in from disk.
Now, if we've saved our progress then we need to set this to false.
So let's take care of that before we move on.
So when are we going to save our progress?
When we hit a checkpoint.
Right.
When we hit a checkpoint is when we save our progress.
So let's go to checkpoint CP.
And here we have execute save progress.
So if we go into character or a character into save progress implementation, here is where we know
that we're no longer fresh.
We've just saved for the first time.
We need to take our save data and take be first time load in and set it to false.
Now we can check this if we need to know if this is our first time loading in.
So back to load progress.
We can check here if this is our first time loading in right here.
We'll say if save data be first time load in, well then we can just do what we were doing before we
can apply our default attributes.
We can use that function that we just took out.
Initialize default attributes.
We can even add our character abilities as well.
And whatever we have set for these, for our initial attributes and abilities, that's what we'll set.
But that's only if it's a first time load in.
If it's not, we have the else case.
Then we need to load in from disk.
And that means we need to apply some gameplay effects to initialize our attributes.
And then of course we'll handle abilities shortly.
But how are we going to apply our primary attributes and our secondary and our vital.
Well, if we go to our ability system library we'll go to the cpp file.
Here's a function called initialize default attributes.
Here's a good example of how we can apply attributes.
We're not setting any set by color magnitudes here, but we are applying gameplay effects and we're
getting those gameplay effects from our data asset character class info.
We're getting the class default info, getting the primary, secondary, and vital attributes.
From that, we can create a Aura Ability system library function to apply set by color magnitudes that
we retrieve from a save game object.
So I'd like to create a function to do that.
And we'll do that in the next video.
So we're almost there.
We're almost ready to initialize our default attributes from disk.
We just need a function to do it.
So we'll do that next.
But before we wrap up though, let's compile so we can add that primary attribute gameplay effect with
set by colors to our data asset.
I'm just going to close down and relaunch the editor okay.
So back in the editor we can go to character class info.
And down in our common class defaults we have primary attributes set by color.
And we can use our set by color primary attributes gameplay effect we created here.
So this primary attribute set by color is just like our other primary attributes gameplay effects,
except it requires set by color magnitudes.
And that's what we're going to use to set these when loading in from disk.
So we'll create a function to do that in the next video.
So excellent job I'll see you soon.