﻿1
00:00:04,270 --> 00:00:05,200
‫Hello and welcome.

2
00:00:05,200 --> 00:00:10,060
‫This lecture we are going to be displaying a loose screen and we're going to be doing it entirely from

3
00:00:10,060 --> 00:00:13,870
‫within C++ to spawn that widget.

4
00:00:13,870 --> 00:00:15,490
‫Let's dive in and see how it's done.

5
00:00:16,150 --> 00:00:21,640
‫So we'd like to display some UI when our player dies to tell them what's going on that they've lost

6
00:00:21,640 --> 00:00:23,260
‫and that the level is about to reset.

7
00:00:23,260 --> 00:00:25,240
‫So it doesn't come as a surprise to them.

8
00:00:25,240 --> 00:00:31,990
‫So we're going to need to create some UI, a UI widget, a UMG, unreal motion graphics widget.

9
00:00:32,350 --> 00:00:35,830
‫So let's do that first of all, by creating a folder to store UI.

10
00:00:35,830 --> 00:00:41,470
‫And I already know we're going to have two items of UI, so I think I'll have a UI folder here and then

11
00:00:41,470 --> 00:00:47,200
‫let's go in here and right click and then go, you should have done this before, but let's I'll walk

12
00:00:47,200 --> 00:00:47,800
‫you through.

13
00:00:48,070 --> 00:00:52,600
‫We're going to go to the user interface section, then select the widget blueprint and the prefix we're

14
00:00:52,600 --> 00:00:57,130
‫going to use is WP underscore and then it's going to be lose screen.

15
00:00:57,430 --> 00:01:02,770
‫Now you can do some base classes for this sort of stuff in C++, but we're not going to cover this in

16
00:01:02,770 --> 00:01:03,520
‫this section.

17
00:01:03,520 --> 00:01:07,480
‫It's generally not necessary to do that, and it's much easier to do this stuff in Blueprint.

18
00:01:07,480 --> 00:01:13,000
‫There's not much advantage to doing it in C++ unless you're a UI was going to get super complicated

19
00:01:13,000 --> 00:01:15,850
‫and you wanted to put some of that UI logic into C++.

20
00:01:15,850 --> 00:01:20,560
‫In that case, this isn't the case, so we can just go ahead and use the blueprints.

21
00:01:20,560 --> 00:01:22,510
‫After all, UI is a visual thing.

22
00:01:22,510 --> 00:01:28,870
‫It makes sense to use a visual tool to put it together now because you already know about how to create

23
00:01:28,870 --> 00:01:29,500
‫widgets.

24
00:01:29,500 --> 00:01:32,860
‫Then I'm going to give this as a challenge to you to set up a lose screen.

25
00:01:32,860 --> 00:01:37,180
‫We want to add some text explaining that the player has lost and that we're about to restart.

26
00:01:37,240 --> 00:01:42,040
‫Want to position that text probably centrally, make it visible, make sure it's visible in the game.

27
00:01:42,040 --> 00:01:45,610
‫And yet, like I said, explain that there will be a restart coming up.

28
00:01:45,730 --> 00:01:50,500
‫And then after you've attempted this challenge, we're going to look at how we can spawn this from C++.

29
00:01:50,500 --> 00:01:53,020
‫You've seen maybe how to do this in Blueprint before.

30
00:01:53,020 --> 00:01:55,690
‫We're going to see how we can do it from within C++.

31
00:01:55,690 --> 00:01:57,070
‫So pause the video and have a go.

32
00:01:57,160 --> 00:01:58,420
‫Okay, welcome back.

33
00:01:58,600 --> 00:02:03,340
‫So I'm going to go and create, first of all, a bit of text.

34
00:02:03,340 --> 00:02:09,400
‫So I want to look for in the palette to the left, going to look for the text item and bring that in.

35
00:02:10,090 --> 00:02:17,270
‫I'm going to change it to you lose pretty straightforward and unimaginative dialogue writing here and

36
00:02:17,290 --> 00:02:22,300
‫we're going to change the color and opacity and or appearance to red to make it super clear that they've

37
00:02:22,300 --> 00:02:22,900
‫lost.

38
00:02:22,900 --> 00:02:28,090
‫And just rub it in a little bit more and I'm going to expand our font and change the size to be bigger.

39
00:02:28,090 --> 00:02:35,320
‫And then I'm going to expand the box around our text and I'm going to center our text.

40
00:02:35,320 --> 00:02:38,080
‫So going down to justification, I'm going to center a line at the text.

41
00:02:38,080 --> 00:02:44,400
‫And if I expand out, let's see if there's somewhere else where I can do center aligned within note

42
00:02:44,440 --> 00:02:44,890
‫there isn't.

43
00:02:44,890 --> 00:02:52,720
‫So I'm just going to go and make the box size roughly appropriate and then I'm going to go up to my

44
00:02:52,720 --> 00:02:55,150
‫alignment and my anchors and stuff like that.

45
00:02:55,450 --> 00:03:02,080
‫And I'm going to select the dropdown for anchors and select the preset for anchoring to the middle,

46
00:03:02,080 --> 00:03:03,370
‫because that's what I want to do.

47
00:03:03,790 --> 00:03:12,430
‫I want to set my alignment to be 0.5 and 0.5, which basically means that we are aligning to the center

48
00:03:12,430 --> 00:03:14,530
‫of the object rather than the top left corner.

49
00:03:14,770 --> 00:03:16,690
‫I'm just going to do the anchor again.

50
00:03:16,690 --> 00:03:16,930
‫Okay.

51
00:03:16,930 --> 00:03:19,060
‫That doesn't that wasn't very helpful.

52
00:03:19,390 --> 00:03:24,520
‫And then the position X why I think if I just set position next to zero and zero because I've set my

53
00:03:24,520 --> 00:03:29,260
‫anchors up like that, then my lose position is going to be somewhere in the middle and I'm just going

54
00:03:29,260 --> 00:03:31,300
‫to move it up ever so slightly.

55
00:03:31,300 --> 00:03:38,200
‫Keep my position X at zero, position Y -50, because I want to add in some secondary texts saying in

56
00:03:38,200 --> 00:03:43,090
‫fact, it might be easier just to duplicate the other text here because it's got all the set up that

57
00:03:43,090 --> 00:03:43,930
‫I already need.

58
00:03:43,930 --> 00:03:46,060
‫I just want to make it a little bit smaller.

59
00:03:46,060 --> 00:03:54,160
‫Position zero again and I'm going to say level will restart in 5 seconds and I'm going to make that

60
00:03:54,160 --> 00:03:55,270
‫font size much smaller.

61
00:03:55,270 --> 00:04:00,460
‫So it's less in your face, something like this, and then just move it down a little bit, a little

62
00:04:00,460 --> 00:04:05,950
‫notch and keep resetting that position X to zero and 100% happy with the positioning.

63
00:04:05,950 --> 00:04:08,560
‫I'm just going to move it up a little notch more.

64
00:04:08,560 --> 00:04:14,050
‫If I hold shift down, then I can lock it to the axis I'm moving with so that it's more or less central

65
00:04:14,050 --> 00:04:14,560
‫like so.

66
00:04:14,590 --> 00:04:15,640
‫Okay, so I'm happy with that.

67
00:04:15,640 --> 00:04:18,940
‫Now we need to go ahead and try and spawn the thing.

68
00:04:18,970 --> 00:04:19,870
‫How are we going to do that?

69
00:04:19,870 --> 00:04:25,210
‫Well, first of all, we're going to need to know what widget class we're supposed to be spawning,

70
00:04:25,210 --> 00:04:27,520
‫and we need to know where we're going to be doing it from now.

71
00:04:27,520 --> 00:04:31,870
‫As I've already said, I think a good place to do this is from the player controller itself.

72
00:04:32,200 --> 00:04:37,660
‫And we're going to need to know in the player controller what class, what widget class are we trying

73
00:04:37,660 --> 00:04:38,030
‫to spawn?

74
00:04:38,030 --> 00:04:42,670
‫Now, I know it's a blueprint class, but we need it still to be a class that we're trying to spawn.

75
00:04:43,000 --> 00:04:48,880
‫So the way we're going to do this is to create a new property up here that's going to be edit anywhere

76
00:04:48,880 --> 00:04:55,990
‫and we are going to want this to be a subclass of because this is always a good way of making sure we

77
00:04:55,990 --> 00:04:57,250
‫get a new class.

78
00:04:57,250 --> 00:05:04,270
‫Basically, you could use the type you class if you wanted to, but that doesn't restrict what kind

79
00:05:04,270 --> 00:05:05,350
‫of class we can use.

80
00:05:05,350 --> 00:05:09,790
‫And here we want to restrict it to only being you use a widgets.

81
00:05:09,790 --> 00:05:17,210
‫If you go over to your blueprint, you can see if we go to somewhere in here, you can find there you

82
00:05:17,260 --> 00:05:17,390
‫go.

83
00:05:17,410 --> 00:05:22,930
‫Parent class is use a widget which we know when you put the prefix on it becomes a you use a widget.

84
00:05:23,050 --> 00:05:26,680
‫So this is a subclass of.

85
00:05:27,490 --> 00:05:34,360
‫And then we use our angle brackets is going to be a you use a widget and I'm actually going to forward

86
00:05:34,360 --> 00:05:40,150
‫declare that one here rather than do any includes so class you use a widget and then we're going to

87
00:05:40,150 --> 00:05:46,630
‫call this the lose screen class just to keep it really obvious what's going on there.

88
00:05:47,020 --> 00:05:54,400
‫Now I'm going to go ahead and compile at this stage while we do the next stuff because compiling when

89
00:05:54,400 --> 00:05:56,710
‫changing a header file takes just that a little bit longer.

90
00:05:56,710 --> 00:06:02,860
‫Now actually the compile will fail at this stage because we haven't included the UMG module.

91
00:06:02,860 --> 00:06:03,820
‫We don't know how to do that.

92
00:06:03,820 --> 00:06:09,010
‫Don't worry about the compilation at this stage and at around 9 minutes into the video, we will fix

93
00:06:09,010 --> 00:06:09,760
‫this error.

94
00:06:10,060 --> 00:06:14,560
‫Now over in the C++, what we're going to want to do is actually spawn that widget up.

95
00:06:14,560 --> 00:06:17,290
‫So we're going to want to do it maybe even before the time.

96
00:06:17,290 --> 00:06:20,320
‫It doesn't really matter because the timer doesn't wait.

97
00:06:20,320 --> 00:06:24,820
‫It just sets the time and then goes straight on to the next line of code so we won't be waiting 5 seconds

98
00:06:24,820 --> 00:06:29,110
‫if we did this at straight, if we spawn the UI straight afterwards, didn't really matter what order

99
00:06:29,110 --> 00:06:29,860
‫we do this in.

100
00:06:30,220 --> 00:06:36,520
‫So what we're going to want to do is use a function called create widget which isn't currently available.

101
00:06:36,520 --> 00:06:38,980
‫So we need to hash include something first.

102
00:06:38,980 --> 00:06:45,850
‫And what we're going to include is blueprint forward slash user widget and that is the class that we

103
00:06:45,850 --> 00:06:50,260
‫need to access this create widget function.

104
00:06:50,740 --> 00:06:53,620
‫And we're going to basically say create widget.

105
00:06:53,620 --> 00:06:58,270
‫It needs to be, well, actually, let's see what we need to provide it.

106
00:06:58,270 --> 00:07:00,910
‫I'm going to F 12 to its implementation.

107
00:07:00,910 --> 00:07:07,330
‫You can see it's a bit complicated to see, but we do have a template parameter up here which is the

108
00:07:07,330 --> 00:07:11,080
‫basically by default the you use a widget, so we probably don't have to provide that.

109
00:07:11,590 --> 00:07:19,390
‫And then there is the owning object and the class that we need to create and then a widget name which

110
00:07:19,390 --> 00:07:23,830
‫we don't necessarily need to provide and then it returns as the pointer to the widget.

111
00:07:24,040 --> 00:07:29,200
‫So what I'm actually going to do is in here, we're going to give it an owner object.

112
00:07:29,200 --> 00:07:31,560
‫Now only certain things can own the widget.

113
00:07:31,580 --> 00:07:36,310
‫One of those things is actually the player controller, so we can just pass in this.

114
00:07:36,310 --> 00:07:40,750
‫Then the next thing is we want to pass in the RT subclass of you use a widget.

115
00:07:40,750 --> 00:07:46,540
‫Well, fortunately we have already configured that up in the header file so we can just go ahead and

116
00:07:46,540 --> 00:07:52,150
‫pass that in and I'll stop my indentation from trying to fix itself up while I haven't put a semicolon

117
00:07:52,150 --> 00:07:55,420
‫on the end of the line and then let's go and have a look at what else.

118
00:07:55,420 --> 00:07:56,050
‫Well, that's it.

119
00:07:56,050 --> 00:07:58,540
‫It just returns the widget at this point.

120
00:07:58,540 --> 00:08:06,910
‫So what we can do is have a pointer to you, use a widget star and this is going to be our lose screen.

121
00:08:06,910 --> 00:08:09,310
‫So we had the lose screen class.

122
00:08:09,310 --> 00:08:13,000
‫After we've created the widget, it becomes an actual loose screen.

123
00:08:13,000 --> 00:08:16,060
‫Next thing we need to do is make this UI visible.

124
00:08:16,060 --> 00:08:20,020
‫We do that by adding it to the viewport in unreal parlance.

125
00:08:20,020 --> 00:08:25,510
‫But first, because we add to the viewport by calling a function on the blue screen, we need to make

126
00:08:25,510 --> 00:08:27,100
‫sure that it is not null pointer.

127
00:08:27,100 --> 00:08:32,410
‫So if lose screen is not equal to null pointer, why could it be null pointer?

128
00:08:32,410 --> 00:08:36,760
‫By the way, little challenge to you see if you can figure out why we might end up with a null pointer

129
00:08:36,760 --> 00:08:37,210
‫here.

130
00:08:37,600 --> 00:08:41,200
‫Well, one reason is maybe we forgot to set the lose screen class.

131
00:08:41,200 --> 00:08:46,180
‫And if that is the case and we don't have a valid blue screen class set, then create widget is just

132
00:08:46,180 --> 00:08:47,860
‫going to return null pointer for us.

133
00:08:47,860 --> 00:08:54,340
‫And we don't want that to happen and we don't want to certainly be calling a function on a null pointer.

134
00:08:54,340 --> 00:08:56,500
‫So we're going to do lose screen arrow.

135
00:08:56,740 --> 00:09:01,270
‫And then what we want here is a function called add to viewport.

136
00:09:02,060 --> 00:09:07,820
‫Which is simply going to do just that, go and add it to the screen so that we can see that loose screen.

137
00:09:08,090 --> 00:09:14,780
‫Now, I'm going to go ahead and compile that, too, and go over into one reel and open up our blueprint

138
00:09:14,780 --> 00:09:17,330
‫for the player controller.

139
00:09:17,330 --> 00:09:19,100
‫So shooter player controller here.

140
00:09:19,550 --> 00:09:25,520
‫And we should be able to see somewhere in here a variable that hasn't yet popped up.

141
00:09:25,640 --> 00:09:27,110
‫Maybe I had some build errors.

142
00:09:27,110 --> 00:09:28,850
‫Let's go and have a look at the message log.

143
00:09:29,180 --> 00:09:36,140
‫Yes, we can see a few build errors in here, namely these weird ones about external symbols missing.

144
00:09:36,140 --> 00:09:41,780
‫If we have a little look saying stuff about you, use a widget not being available now if you cast your

145
00:09:41,780 --> 00:09:49,520
‫mind back to a few lectures previously, we know that these kinds of errors tend to be when we are missing

146
00:09:49,520 --> 00:09:50,840
‫a module dependency.

147
00:09:50,840 --> 00:09:57,770
‫So if we go and open up our simple shooter dot build dot CSS and I'm just going to close down the terminal

148
00:09:57,770 --> 00:10:04,370
‫for a bit more added space, then you can see what we need to do is add a new public dependency here.

149
00:10:04,580 --> 00:10:12,140
‫So to the end of this, we're going to add a public dependency for UMG, so a new comma.

150
00:10:12,140 --> 00:10:20,600
‫And then in quotes, we're going to put UMG and that basically allows us to make use of the include

151
00:10:20,600 --> 00:10:24,380
‫that we had here, the blueprint forward slash user widget.

152
00:10:24,680 --> 00:10:28,700
‫All of that stuff is in a separate module to the standard stuff that's included.

153
00:10:28,700 --> 00:10:32,690
‫So we do need to go and tell Unreal that we want to use that module in our C++.

154
00:10:32,690 --> 00:10:34,640
‫Let's go ahead and build and see if it works.

155
00:10:34,640 --> 00:10:36,410
‫Now that looks successful.

156
00:10:36,410 --> 00:10:42,500
‫If we go over in to the editor and go back to our shooter play controller, some reason I don't think

157
00:10:42,500 --> 00:10:46,340
‫it had properly reloaded, so I've had to hit compile here in the editor.

158
00:10:46,340 --> 00:10:48,430
‫We go back now to the shooter player controller.

159
00:10:48,430 --> 00:10:50,630
‫At last you can see that lose screen class.

160
00:10:50,850 --> 00:10:57,830
‫We can click the drop down there and go and select AWP, underscore lose screen there, compile, save

161
00:10:57,830 --> 00:11:00,140
‫and let's go and get ourselves killed.

162
00:11:00,140 --> 00:11:01,900
‫We'll get shot at a couple of times.

163
00:11:01,910 --> 00:11:03,380
‫Bang, bang.

164
00:11:03,380 --> 00:11:04,250
‫And there you go.

165
00:11:04,250 --> 00:11:09,320
‫Our Lou screen has popped up telling us what's happening that level's about to restart in 5 seconds.

166
00:11:09,320 --> 00:11:10,220
‫And it did.

167
00:11:10,220 --> 00:11:11,270
‫It does.

168
00:11:11,270 --> 00:11:20,030
‫So now you know not only how you can create UMG graphics, but also how you can spawn these from C++

169
00:11:20,030 --> 00:11:22,070
‫rather than from Blueprint.

170
00:11:22,070 --> 00:11:26,960
‫Next lecture, we're going to have a less pessimistic outlook on things and try and see if we can also

171
00:11:26,960 --> 00:11:30,680
‫create some win conditions for this game.

172
00:11:30,680 --> 00:11:31,550
‫I'll see you there.

