﻿1
00:00:04,550 --> 00:00:11,000
‫In this lecture, we are going to be putting together a player controller that will receive information

2
00:00:11,000 --> 00:00:18,140
‫that the game has ended from the game mode and will create this restarting behavior that after 5 seconds

3
00:00:18,140 --> 00:00:21,050
‫reloads the level after the player has died.

4
00:00:21,050 --> 00:00:22,730
‫Let's dive in and see how it's done.

5
00:00:23,360 --> 00:00:30,710
‫So when the game is indeed over, we need to notify our player controller and we also need to have a

6
00:00:30,710 --> 00:00:37,190
‫player controller in our C++ so that we can implement the behavior of allowing us to restart the level

7
00:00:37,190 --> 00:00:38,000
‫and such.

8
00:00:38,210 --> 00:00:44,360
‫So the first thing to do is when this point is killed, first of all, we're just logging indiscriminately.

9
00:00:44,360 --> 00:00:48,200
‫We do want to check whether or not the game is over.

10
00:00:48,200 --> 00:00:50,390
‫Now, there are two scenarios.

11
00:00:50,390 --> 00:00:52,730
‫One is where we win and one is where we lose.

12
00:00:52,760 --> 00:00:55,580
‫The lose is the first one I'm going to tackle because it's easiest.

13
00:00:55,580 --> 00:00:58,220
‫If the pawn killed is the player you lose, that's it.

14
00:00:58,220 --> 00:01:04,130
‫You might choose to have multiple lives with different iterations of this game mode, but I'm not going

15
00:01:04,130 --> 00:01:04,850
‫to be doing that.

16
00:01:04,850 --> 00:01:06,170
‫I'm just going to have a single life.

17
00:01:06,170 --> 00:01:07,520
‫If you die, game over.

18
00:01:07,520 --> 00:01:08,900
‫You might want to restart.

19
00:01:09,320 --> 00:01:13,640
‫So how do we check if this pawn is a player controller?

20
00:01:13,670 --> 00:01:14,990
‫Well, that's pretty straightforward.

21
00:01:14,990 --> 00:01:22,700
‫We can just do a cast, so we're going to do a cast to a player controller and for the pawn killed.

22
00:01:22,700 --> 00:01:25,340
‫And then if this is not null.

23
00:01:25,340 --> 00:01:32,810
‫So let's take the pointer, a player controller pointer, call it the player controller and store the

24
00:01:32,810 --> 00:01:34,490
‫result of that pointer in here.

25
00:01:34,490 --> 00:01:42,890
‫And we're going to say basically if this is not null, so if the player controller is not a null pointer,

26
00:01:43,190 --> 00:01:47,540
‫then we know that it's the player that's died and that it's game over for the player.

27
00:01:47,630 --> 00:01:52,100
‫So what we want to do is call on that player controller method.

28
00:01:52,100 --> 00:01:57,500
‫We've already hinted at the fact that there is a game has ended method.

29
00:01:57,500 --> 00:01:58,460
‫Let's have a look at this.

30
00:01:58,460 --> 00:02:06,530
‫If we do a control P and have a look at the player controller and we're going to look for a game has

31
00:02:06,530 --> 00:02:12,950
‫ended and you can see sure enough there is a virtual method here called game has ended and you can see

32
00:02:12,950 --> 00:02:14,780
‫there is an end game focus.

33
00:02:14,780 --> 00:02:19,070
‫What actor should we focus on in the end game by default, this is null pointer and that's probably

34
00:02:19,070 --> 00:02:19,970
‫what we're going to use.

35
00:02:20,690 --> 00:02:22,910
‫And then we're going to say, is this the winner?

36
00:02:22,910 --> 00:02:28,340
‫Basically, you've got to let the player control and know whether or not they have won.

37
00:02:28,340 --> 00:02:31,760
‫And that's fairly straightforward to say in this case.

38
00:02:31,760 --> 00:02:33,050
‫No, they haven't.

39
00:02:33,140 --> 00:02:41,480
‫So we're going to do a play controller arrow game has ended, then I'm going to put null pointer for

40
00:02:41,480 --> 00:02:47,540
‫the end game focus because we don't really need that feature and then is winner.

41
00:02:47,540 --> 00:02:49,430
‫It's just simply going to be false.

42
00:02:49,430 --> 00:02:53,540
‫This is not the winning play controller because it's the one that just died.

43
00:02:54,370 --> 00:02:56,950
‫So it's time for a little bit of a challenge for you to implement.

44
00:02:56,950 --> 00:02:59,710
‫Game has ended in a play controller.

45
00:02:59,860 --> 00:03:06,940
‫That means we need to create a C++ player controller, create its blueprint subclass, spawn that blueprint

46
00:03:06,940 --> 00:03:12,530
‫subclass by default from our game mode and then you want to go ahead and override.

47
00:03:12,550 --> 00:03:17,350
‫The game has ended and put a log message in there to check that we're indeed getting.

48
00:03:17,350 --> 00:03:19,830
‫That game has ended at the right time.

49
00:03:19,840 --> 00:03:21,220
‫Pause the video and have a go.

50
00:03:21,250 --> 00:03:21,580
‫Okay.

51
00:03:21,580 --> 00:03:22,260
‫Welcome back.

52
00:03:22,270 --> 00:03:29,740
‫So step one, create that C++ player controller, create a new C++ class, then go and look for let's

53
00:03:29,740 --> 00:03:30,760
‫see, player controller.

54
00:03:30,760 --> 00:03:34,720
‫Next, we're going to call this the shooter player controller.

55
00:03:34,750 --> 00:03:36,010
‫Go ahead and create that class.

56
00:03:36,010 --> 00:03:44,230
‫Once that's done, we want to go over to our blueprints and create a blueprint class that is based off

57
00:03:44,230 --> 00:03:44,560
‫of it.

58
00:03:44,560 --> 00:03:50,680
‫So we want the shooter player controller as the base select that and we're going to call it beep underscore

59
00:03:50,710 --> 00:03:53,200
‫shooter player controller.

60
00:03:53,200 --> 00:03:57,580
‫This is not currently really needed, but later down the line, we're going to want to hook up some

61
00:03:57,580 --> 00:03:59,230
‫UI assets to this player controller.

62
00:03:59,230 --> 00:04:00,940
‫So we'll have it there ready.

63
00:04:01,150 --> 00:04:07,900
‫Then we're going to go to the beep, more game mode and dock that in because we want to change the default

64
00:04:07,900 --> 00:04:13,150
‫player controller class from the player controller to our beep underscore shooter player controller.

65
00:04:13,450 --> 00:04:14,050
‫Cool.

66
00:04:14,380 --> 00:04:18,280
‫Then we want to override our game has ended.

67
00:04:18,490 --> 00:04:21,430
‫So let's see if we go over to the player controller.

68
00:04:22,060 --> 00:04:24,550
‫We can see that this is in the public section.

69
00:04:24,550 --> 00:04:25,360
‫Here's the signature.

70
00:04:25,360 --> 00:04:25,990
‫Let's copy it.

71
00:04:25,990 --> 00:04:31,390
‫Go over into our shooter play controller H and create public.

72
00:04:32,170 --> 00:04:35,650
‫To that virtual void game has ended.

73
00:04:35,650 --> 00:04:36,190
‫Cool.

74
00:04:36,190 --> 00:04:40,210
‫And we've got an override already because that was clearly being overridden from somewhere to.

75
00:04:41,160 --> 00:04:45,330
‫And then what we can do is we can go ahead and implement it.

76
00:04:45,340 --> 00:04:48,780
‫Control shift p we want to call to super remember.

77
00:04:49,790 --> 00:04:53,060
‫And we want to do game has ended like so.

78
00:04:53,870 --> 00:05:01,770
‫And we want to pass in the end game focus and the B is winner and then we want to log.

79
00:05:01,790 --> 00:05:02,810
‫So you log.

80
00:05:02,900 --> 00:05:04,280
‫Use my macro there.

81
00:05:04,610 --> 00:05:07,240
‫We have finished.

82
00:05:07,250 --> 00:05:10,310
‫It's going to be the log message coming out at the end.

83
00:05:10,310 --> 00:05:12,880
‫So let's compile and see whether that's working.

84
00:05:12,890 --> 00:05:14,540
‫We're going to go to the output log.

85
00:05:14,690 --> 00:05:17,690
‫Hit play, go and get killed.

86
00:05:17,690 --> 00:05:23,480
‫Basically healthy is slowly going down and then we should see a message.

87
00:05:23,480 --> 00:05:24,530
‫Are we getting the message?

88
00:05:24,530 --> 00:05:24,920
‫No.

89
00:05:24,920 --> 00:05:25,880
‫So let's have a look.

90
00:05:25,880 --> 00:05:27,230
‫What's the player controller here?

91
00:05:27,230 --> 00:05:32,870
‫Beep underscore shooter player controller appears to be the correct one.

92
00:05:32,870 --> 00:05:35,570
‫We've got our override game has ended.

93
00:05:35,570 --> 00:05:37,250
‫Now here I spot a bug.

94
00:05:37,250 --> 00:05:42,170
‫Now that is something that some of you may have noticed and have been shouting at the screen about is

95
00:05:42,170 --> 00:05:47,900
‫that here we have got our player controller that we are casting to and I'm getting that confused with

96
00:05:47,900 --> 00:05:49,760
‫the player's actual --.

97
00:05:49,760 --> 00:05:57,260
‫So what we want to do here is we want to say get the controller of the -- that was killed.

98
00:05:57,260 --> 00:06:05,030
‫So -- killed dot get controller Aron so arrow get controller and then we want to cast that to the

99
00:06:05,030 --> 00:06:08,600
‫player controller and if that is null, okay, that should work.

100
00:06:08,600 --> 00:06:10,760
‫So let's go ahead and try that out.

101
00:06:10,820 --> 00:06:12,320
‫Go ahead and hit play.

102
00:06:12,800 --> 00:06:14,030
‫Get ourselves killed again.

103
00:06:15,700 --> 00:06:18,940
‫And this time we also don't get any log message.

104
00:06:18,940 --> 00:06:21,370
‫And this time it's for a subtle reason.

105
00:06:21,490 --> 00:06:24,550
‫That is because we're detaching from the controller.

106
00:06:24,640 --> 00:06:26,890
‫Before we call this -- kill.

107
00:06:26,890 --> 00:06:32,740
‫So when it tries to get the controlling -- that's actually null, there is no controlling -- anymore.

108
00:06:32,740 --> 00:06:38,470
‫So we need to do this notification just before we do the detaching from the controller.

109
00:06:38,620 --> 00:06:42,220
‫That includes moving up the line that gets hold of our game mode.

110
00:06:42,220 --> 00:06:43,600
‫I didn't think that would matter.

111
00:06:43,660 --> 00:06:47,200
‫But now that I actually think about it, yes, of course it does.

112
00:06:47,200 --> 00:06:50,170
‫So let's go over in to our level and play.

113
00:06:50,500 --> 00:06:51,970
‫Let's go and get shot at.

114
00:06:51,970 --> 00:06:56,940
‫And once that is done, you can see that we have finished gets printed as we want.

115
00:06:56,950 --> 00:06:59,020
‫So we had a few hiccups along the way.

116
00:06:59,020 --> 00:07:01,660
‫Not your fault if you didn't get that in the challenge.

117
00:07:01,660 --> 00:07:03,730
‫You've done everything else right up to that point.

118
00:07:03,730 --> 00:07:04,990
‫That is great.

119
00:07:04,990 --> 00:07:11,050
‫So hopefully maybe you had a go at debugging that, but don't worry if you got stuck on those things.

120
00:07:11,350 --> 00:07:17,890
‫The final thing I wanted to do here is to actually restart the game on a timer.

121
00:07:17,980 --> 00:07:24,340
‫Now, the way we can do this is fairly straightforward because the player controller actually has a

122
00:07:24,340 --> 00:07:25,960
‫restart method.

123
00:07:25,960 --> 00:07:30,220
‫So if we go and have a look at this, it should be a restart level.

124
00:07:30,220 --> 00:07:35,590
‫That's the one that we want to be calling and we want to do this on a timer.

125
00:07:35,590 --> 00:07:42,520
‫So we've used timers before to do repeating stuff, but we can also use it just to delay an action by

126
00:07:42,520 --> 00:07:44,050
‫a certain amount.

127
00:07:44,050 --> 00:07:50,170
‫So I'm going to go to the shooter player controller H and create a private property in here.

128
00:07:50,890 --> 00:07:56,740
‫Private can be you property which is edit anywhere.

129
00:07:58,620 --> 00:07:59,160
‫Float.

130
00:07:59,160 --> 00:08:02,940
‫That is going to be the restart delay.

131
00:08:03,060 --> 00:08:05,760
‫You can see why we need a blueprint base for this already.

132
00:08:05,790 --> 00:08:08,400
‫I'm going to give it a 5/2 delay.

133
00:08:08,610 --> 00:08:16,920
‫Then I'm going to go over into the C++ and we're going to want to do a get timer world timer manager.

134
00:08:17,520 --> 00:08:19,850
‫And then we can do on that.

135
00:08:19,860 --> 00:08:21,870
‫Then we need to include.

136
00:08:21,870 --> 00:08:27,120
‫So hash include and it's going to be the timer manager.

137
00:08:27,390 --> 00:08:33,210
‫H Then we should be able to use the DOT operator because the return type here is a reference and we're

138
00:08:33,210 --> 00:08:38,160
‫going to do a set timer and in here we need to pass in a timer handle.

139
00:08:38,160 --> 00:08:40,590
‫So in a private section let's go and create one.

140
00:08:40,590 --> 00:08:46,470
‫So it's going to be an F timer handle, I'll call it the restart timer like.

141
00:08:46,470 --> 00:08:51,230
‫So then that is going to be the handle that we pass into our set timer.

142
00:08:51,240 --> 00:08:57,810
‫The next thing we need on the fifth signature here is actually to have the object that we want to call

143
00:08:57,810 --> 00:08:59,130
‫on, which is just going to be this.

144
00:08:59,460 --> 00:09:05,280
‫And then there's going to be, I think should be just the method itself.

145
00:09:05,490 --> 00:09:08,280
‫So we can do that by doing ampersand.

146
00:09:08,280 --> 00:09:13,920
‫And then it's actually the method, the restart level method, which we want to call on that was defined

147
00:09:13,920 --> 00:09:16,200
‫on the A player controller.

148
00:09:16,200 --> 00:09:17,910
‫So a player controller.

149
00:09:19,300 --> 00:09:19,660
‫Cullen.

150
00:09:19,660 --> 00:09:27,340
‫Cullen restart level and then we just need to pass in the delay which we have already defined as the

151
00:09:27,340 --> 00:09:28,210
‫restart delay.

152
00:09:28,630 --> 00:09:35,830
‫So do that, put a semicolon on the end there and hopefully we should get ourselves restarting after

153
00:09:35,830 --> 00:09:36,800
‫5 seconds.

154
00:09:36,820 --> 00:09:41,650
‫Now going to make the testing a little bit easier by opening up our rifle and making it just a little

155
00:09:41,650 --> 00:09:42,520
‫bit more lethal.

156
00:09:42,520 --> 00:09:48,160
‫So I'm going to go to the defaults, do the damage at 50, so we'll get killed with two shots.

157
00:09:48,280 --> 00:09:49,900
‫Let's go and hit play.

158
00:09:50,750 --> 00:09:52,250
‫Get ourselves killed quickly.

159
00:09:53,260 --> 00:10:00,460
‫And then after 5 seconds, hopefully we should restart the level we restart and we're back in the level.

160
00:10:00,460 --> 00:10:03,130
‫So our timer is working as we expect.

161
00:10:03,640 --> 00:10:11,410
‫Now in later versions, you will find that instead of restarting, what you're going to see is an error

162
00:10:11,410 --> 00:10:17,740
‫message that looks like this and talks about travel failure and says something about UUID, PID, sandbox,

163
00:10:17,740 --> 00:10:18,550
‫blah blah blah.

164
00:10:18,580 --> 00:10:23,650
‫Well, the way we have to get around this when we're trying to restart and want to check whether our

165
00:10:23,650 --> 00:10:29,890
‫restart is working, is we go to our dot, dot, dot menu instead of the play menu and we have to play

166
00:10:29,890 --> 00:10:31,920
‫as a stand alone game.

167
00:10:31,930 --> 00:10:38,110
‫If, if you play as a standalone game, it takes a little bit longer to launch up, but the restarting

168
00:10:38,110 --> 00:10:41,620
‫will work as expected like so.

169
00:10:41,620 --> 00:10:43,600
‫And we see the level reloaded.

170
00:10:43,600 --> 00:10:46,570
‫Now, obviously there's not much indication that the this is going to happen.

171
00:10:46,570 --> 00:10:50,170
‫So we're going to look at UI in the next lectures.

172
00:10:50,170 --> 00:10:51,010
‫I'll see you there.

