Welcome back.
Now we know that we can load in information from disk, but that information is a little bit limited.
If we open our load menu and press play, we know that if our slot was just created, then its map is
set to first Dungeon.
And if we select that slot and press play, we go to the first dungeon.
Okay, well that's great, but we need to load in more information than that.
Now we know we need to load in all of our saved attribute values, at least the primaries and our spells,
any abilities that we have and whatever abilities we have equipped to whichever slots all of that stuff
definitely needs to be loaded in, right?
Of course.
But in addition to that, we need to know where to load in in any given map, because a map might have
different entrances and exits, it might have a starting point, but you may wish to have some kind
of staircase that goes down to another dungeon, and at which point you travel to the other map and
end up at a specific location in that map.
And if you come back, maybe you want to spawn in right at that entrance, as opposed to at the beginning
of the dungeon where you first spawned in.
So there needs to be a way to choose where we spawn, and by default we spawn at player starts, and
the game mode has the ability to choose a player start and player starts are a specific kind of actor
that can be identified.
In fact, they have a player start tag.
If we select our player start right here, we see the player start tag.
It's set to none, but we can use the player start tag to identify player starts if we want to.
So how do we discern what player start to choose?
Well, we can go back to C plus plus into our aura game mode base.
And because this is based on a game mode base, let's go to a game mode base and just take a look.
And if we search for choose.
There's a function called Choose Player Start and this is a blueprint native event.
It says return the best player start for this player to spawn from default implementation looks for
a random unoccupied spot.
Now it says that the player is the controller for whom we are choosing a player.
Start returns actor chosen as the player start.
Usually a player starts, so it returns an a actor.
It doesn't have to be.
It can be an actor.
But usually we choose a player start.
So because this is a blueprint native event, we can override its implementation.
And if we want to do that, we can choose what player start to spawn at.
Now which one are we going to choose?
Well, that's going to need to be something we decide of course.
So let's see how choose player Start works.
Let's learn a little bit about how we can use it and how we can choose a specific player.
Start.
Now it's a public function.
So we're going to override it in the public section.
We're going to say virtual a actor pointer choose player start implementation override.
We can go ahead and implement this function.
And we don't need to call super.
We want to choose the player start and return it.
So I'm going to get all actors of a specific class.
The player start class.
And from those player starts I'm going to find one with a given tag and return it.
That's what I'd like to do.
Before I bother with all that though, I'm going to see what happens if we return a null pointer.
What ends up happening?
If that's the case, does the whole game crash?
Does the world come crashing down?
Let's just find out.
So I'm just going to press play in this dungeon map and look at what happens.
Really, we don't get a player start.
We spawn in right here.
Right there in the ground.
So returning null for our player start is probably not the best idea.
We should probably always return at least something, right?
We need some kind of player start.
So what we can do when we get all actors of the player start class is we could find the first one and
just set that.
And if we don't find any player starts that have the tag we're looking for, we'll return that first
one.
So here's what we'll do is first we're going to call get all actors of class.
That's a you gameplay statics function.
It's called get all actors of class.
Now it requires a world context object.
I'm just going to call Get world here.
We can pass the world in itself as a world context object, and we need to pass in an actor class to
filter this by, I'm going to use a player start.
Static class.
Now that means I need to include the player start header file.
So we'll go ahead and do that.
Now this function also needs a t array of actors called out actors that it can fill in with actors.
So I'm going to make a T array of a actor pointers.
Called actors.
And we'll pass in our actors here.
And if actors dot num is greater than zero, then we have actors, but otherwise we need to return a
null pointer.
So we're going to return null pointer here at the end.
And if actors dot num is greater than zero, I'm going to first start off creating an a actor pointer
called Selected Actor.
And I'll start it off with actors of zero.
So the first one.
But then I want to loop over actors.
I'm going to say for a actor actor in actors, and I'd like to cast it to a player start.
So I'm going to say a player start pointer player start equals cast to a player start.
Actor.
And I'll go ahead and wrap this in an if statement.
And I'll check that player starts player start tag.
We can say if player start.
Player start tag and we can check to see if it equals a specific F name.
For now, I'm just going to hard code it to see how this works.
I'm going to say the tag the tag, and if that player start matches this tag then I'm going to set selected
actor equal to this player start.
And by the end of this for loop, at the very end of it, I'm going to return selected actor.
And of course, if we find a player start, there's no need to continue this for loop.
We can break out of the for loop.
So now we have choose player starts that is going to return the first player start.
We find if none of them have the tag and it'll return null.
If there are no player starts in the world, but if there is one with the tag, it'll return that one.
If there's multiple with the tag, it's going to return the first one it finds.
So we can test this out by running in debug mode.
Okay, so first thing I'm going to do is press play.
Now I see that we spawn at that player start.
If we take that player start and delete it and press play, well, we just spawn in.
We don't have a player start.
I'm going to control Z though and keep that player start, but I'm going to duplicate it and bring the
duplicate over to here.
And for this one I'm going to set its player start tag to the tag.
So right there in the details panel.
And if I press play I spawn it that one.
And if I have more than one with the tag it's just going to take one.
The first one it finds.
But we should never have more than one player start with the same tag, because that's ambiguous.
Unless you don't care and you want a random player, start from among those player starts that all have
the same tag, that would be fine too.
But now at least we know that if we specify a tag we'll spawn in at the player start that has that tag,
provided that there is one with that tag.
If we take this tag and set it back to none, then if we press play, it's just going to pick one.
So really no harm done.
But now we can control where we spawn in.
And this is pivotal to spawning in at checkpoints or places that we've saved, or even determining where
to spawn in to a level.
If we go into a dungeon entrance, for example, and we need to figure out how exactly we can know what
that tag should be when we spawn in because we're spawning into a new level.
So how are we going to know what the player start should be?
We're going to figure that out in the next video.
So until then I'm going to delete this player start.
And I'm going to remove these enemies from this world as we're just going to start working on saving
and loading.
And I'll see you in the next video.