1
00:00:04,070 --> 00:00:09,620
In the last lecture, we turned our audio player into a singleton so that when we changed our scene,

2
00:00:09,620 --> 00:00:11,660
the music would continue to play.

3
00:00:12,260 --> 00:00:17,690
And during that lecture, I also asked you to think about some other objects that may benefit from being

4
00:00:17,690 --> 00:00:18,530
a singleton.

5
00:00:19,240 --> 00:00:21,730
So hopefully you had a good think about that question.

6
00:00:21,730 --> 00:00:25,450
And there were a couple of different answers depending on the approach you're taking.

7
00:00:25,690 --> 00:00:31,270
One valid option is that nothing should be a singleton and there are better or different ways of approaching

8
00:00:31,270 --> 00:00:33,370
our code to make sure we don't use them.

9
00:00:33,370 --> 00:00:38,950
But assuming we do want add some singletons to make our life a little bit easier, the first candidate

10
00:00:38,950 --> 00:00:43,270
would be our level manager because we've got one of these in every single scene.

11
00:00:43,270 --> 00:00:48,510
They're all doing exactly the same thing and we only ever really want one of them at any given time.

12
00:00:48,520 --> 00:00:53,980
But since having multiple level managers in a scene is not really going to break anything, it's not

13
00:00:53,980 --> 00:00:57,250
essential that only one ever exists at a time.

14
00:00:57,280 --> 00:01:02,590
The only real benefit I can see from making this a singleton is if we make it a pure singleton and have

15
00:01:02,590 --> 00:01:03,850
global accessibility.

16
00:01:03,850 --> 00:01:09,580
So we only ever have one in our entire game because we can then stop worrying about this scene.

17
00:01:09,580 --> 00:01:12,070
Loaded delay in our hierarchy.

18
00:01:12,070 --> 00:01:17,080
Because if we change this in our main menu, it's not going to translate over into our game scene at

19
00:01:17,080 --> 00:01:17,680
the moment.

20
00:01:17,680 --> 00:01:22,210
So we could potentially change things in the wrong place and it will become a bit of a nightmare.

21
00:01:22,240 --> 00:01:28,540
But for now, the way I said we can get around this is just to remember or add a tooltip maybe to our

22
00:01:28,540 --> 00:01:35,950
script to tell us not to edit this in our same view and instead only change it on the prefab version.

23
00:01:35,950 --> 00:01:39,790
So as long as we haven't overridden it somewhere, it should update everywhere.

24
00:01:40,150 --> 00:01:44,770
Turning our level manager into a singleton would also create some other problems that we would need

25
00:01:44,770 --> 00:01:50,380
to solve, like how our canvas buttons are currently linked up to our level manager.

26
00:01:50,380 --> 00:01:56,050
So if we start moving that between scenes, we're going to have to have a script attached to our canvases

27
00:01:56,050 --> 00:02:01,900
to allow our buttons to find the level manager that's in the scene at a given time and then hook themselves

28
00:02:01,900 --> 00:02:02,320
up.

29
00:02:02,320 --> 00:02:05,350
So it's going to create more work than we really want to do.

30
00:02:05,350 --> 00:02:10,210
So let's leave our level manager alone because it is working perfectly fine as is.

31
00:02:10,330 --> 00:02:15,910
But the other candidate for a singleton, which I think we will pursue, is going to be our scorekeeper

32
00:02:15,910 --> 00:02:21,730
because we currently have a scorekeeper in our game scene for tracking our actual score during play

33
00:02:22,060 --> 00:02:25,570
and our game overseeing for displaying the score at the end.

34
00:02:25,600 --> 00:02:30,790
Our scorekeeper needs a way of transferring that score from one scene to another, so it would make

35
00:02:30,790 --> 00:02:33,700
sense if the same object got carried across.

36
00:02:33,700 --> 00:02:38,500
And we also want to make sure we don't end up with more than one scorekeeper in a scene.

37
00:02:38,500 --> 00:02:43,690
If we ended up with two or three scorekeepers in our game scene, then every time we scored points,

38
00:02:43,690 --> 00:02:45,610
we'd be scoring triple the points.

39
00:02:45,940 --> 00:02:49,210
So our scorekeeper is going to make a good single turn, I think.

40
00:02:49,210 --> 00:02:54,610
But before we go ahead and set up our script, let's just do a little bit of extra work on our canvas

41
00:02:54,610 --> 00:02:57,580
so that we can find our score, text and update it.

42
00:02:57,580 --> 00:03:00,820
So over on our canvas we're going to add a new script.

43
00:03:00,820 --> 00:03:06,850
So over in our script folder, let's right click create a new C-sharp script, and I think we'll call

44
00:03:06,850 --> 00:03:09,580
this one the UI game over.

45
00:03:10,630 --> 00:03:14,260
Let's track that onto the canvas and then open it up.

46
00:03:14,650 --> 00:03:18,760
And if you fancy a bit of a mini challenge, then go ahead and write this script completely on your

47
00:03:18,760 --> 00:03:22,120
own and I'll give you a moment to pause the video if you want to do that.

48
00:03:23,520 --> 00:03:23,880
Okay.

49
00:03:23,880 --> 00:03:26,400
So if you did this as a mini challenge, very well done.

50
00:03:26,400 --> 00:03:29,660
Or if you want to follow along, that's absolutely fine as well.

51
00:03:29,670 --> 00:03:33,630
So let's first of all get rid of our update method because we're not going to need it.

52
00:03:33,870 --> 00:03:35,220
We will need to start.

53
00:03:35,220 --> 00:03:40,680
But let's clear off our comment and we're going to want to connect this script up to the text mesh pro

54
00:03:40,680 --> 00:03:41,970
element on the canvas.

55
00:03:41,970 --> 00:03:47,250
So the top of the script, we're going to include a new using statement and we're going to be using

56
00:03:47,280 --> 00:03:48,510
TM Pro.

57
00:03:48,510 --> 00:03:54,840
Then let's create a serialized field for our text mesh, pro-EU Gooey Element and call this the score

58
00:03:54,840 --> 00:03:55,500
text.

59
00:03:55,920 --> 00:04:00,030
Let's also grab a reference to our scorekeeper and call this the scorekeeper.

60
00:04:01,210 --> 00:04:09,610
And then in a wake, let's set our scorekeeper to find objective type scorekeeper.

61
00:04:10,870 --> 00:04:15,790
Finally, let's set our score text in start so we can say score text.

62
00:04:16,209 --> 00:04:19,870
Text is equal to our scorekeeper.

63
00:04:20,500 --> 00:04:21,790
Don't get score.

64
00:04:22,570 --> 00:04:26,690
Now this is returning an integer, so we're going to need to turn it into text.

65
00:04:26,710 --> 00:04:31,690
We can do that like we did in our game scene by just adding the two string method.

66
00:04:31,900 --> 00:04:35,380
But if you remember back over on our canvas, we also have this.

67
00:04:35,380 --> 00:04:38,050
You scored part of the scoring message.

68
00:04:38,790 --> 00:04:44,400
So we can actually do away with this two string method if we want, because when we start concatenating

69
00:04:44,400 --> 00:04:48,410
strings and integers, the whole thing will get treated as a string.

70
00:04:48,420 --> 00:04:51,450
So let's add our little message of you scored.

71
00:04:52,180 --> 00:04:56,380
And to place our score on a new line, we can just use the new line character.

72
00:04:56,410 --> 00:05:01,440
So let's save this up and jump back over into unity over on our canvas.

73
00:05:01,450 --> 00:05:05,800
Let's take our UI, game over script and drag over the score text.

74
00:05:06,160 --> 00:05:09,970
And if we hit play now, we should have a message of you scored zero.

75
00:05:10,420 --> 00:05:12,070
So that seems to be working.

76
00:05:12,070 --> 00:05:16,810
And the next step is going to be to convert our scorekeeper into a singleton.

77
00:05:16,840 --> 00:05:19,330
And this is going to be your challenge.

78
00:05:19,600 --> 00:05:23,470
I want you to turn our scorekeeper into a singleton.

79
00:05:23,470 --> 00:05:28,270
So if you feel up to taking on that challenge without any further advice, then go ahead and pause the

80
00:05:28,270 --> 00:05:28,990
video now.

81
00:05:29,260 --> 00:05:34,960
But if you want a hint, then take a look at what we did in our audio player for reference, because

82
00:05:34,960 --> 00:05:37,060
this is going to come in very handy for you.

83
00:05:37,090 --> 00:05:39,910
So pause the video now and give that a go.

84
00:05:45,560 --> 00:05:46,040
Okay.

85
00:05:46,040 --> 00:05:46,880
Welcome back.

86
00:05:46,910 --> 00:05:52,700
So to set this up as a singleton, let's take a look at what we did for our audio player.

87
00:05:53,090 --> 00:05:59,540
We had a static audio player instance and then in a wake we were calling our managed singleton method.

88
00:05:59,660 --> 00:06:03,170
This method was checking whether our instance was null.

89
00:06:03,170 --> 00:06:07,070
So if we weren't the first object to come along, then we were going to get destroyed.

90
00:06:07,160 --> 00:06:12,620
Otherwise, if we were the first ones to come along, then we're going to set the instance to this version

91
00:06:12,620 --> 00:06:13,730
of our audio player.

92
00:06:13,850 --> 00:06:16,220
So let's actually copy all of this.

93
00:06:16,220 --> 00:06:22,940
So our static variable, our awake method and our manage singleton method, and then over in our scorekeeper,

94
00:06:22,940 --> 00:06:28,910
let's just copy and paste that into our code and pretty much all of it can stay as it is.

95
00:06:28,910 --> 00:06:34,280
The only thing we're getting an error on is when we try and set our instance to this, because we're

96
00:06:34,280 --> 00:06:38,900
trying to set a scorekeeper into an audio player, which definitely isn't going to work.

97
00:06:39,140 --> 00:06:44,090
So instead for our scorekeeper we need a static scorekeeper instance.

98
00:06:44,420 --> 00:06:49,220
This will then get rid of our red error and everything should work as expected.

99
00:06:49,220 --> 00:06:52,850
So let's save up our script and jump back into unity.

100
00:06:53,330 --> 00:06:58,940
And if we go ahead and hit play, we should find that our score initially gets set to zero, which it

101
00:06:58,940 --> 00:06:59,540
does.

102
00:06:59,780 --> 00:07:02,450
And when we play again, our score is zero.

103
00:07:02,450 --> 00:07:06,170
But if we rack up some score before we die, so let's just get a couple of points.

104
00:07:06,170 --> 00:07:08,300
100 is fine before we die.

105
00:07:09,890 --> 00:07:13,370
This hundred now gets carried over to our score.

106
00:07:13,790 --> 00:07:20,690
But we've now got a secondary problem that if we play again, we start off with a score of 100.

107
00:07:21,020 --> 00:07:26,780
So our next step is to work out when and where we want to call our reset score method.

108
00:07:27,230 --> 00:07:33,020
Well, if we head over to our script and open up our level manager, it would be a good idea to reset

109
00:07:33,020 --> 00:07:35,870
our score whenever we load our main gain.

110
00:07:36,080 --> 00:07:40,220
So this script is going to require a scorekeeper called scorekeeper.

111
00:07:41,120 --> 00:07:44,060
And then in awake we need to find this scorekeeper.

112
00:07:44,060 --> 00:07:50,510
So avoid awake scorekeeper equals find objective type scorekeeper.

113
00:07:51,740 --> 00:07:56,570
And I'm sure all of this finding stuff in awake over and over again is really starting to tempt you

114
00:07:56,570 --> 00:08:01,220
into that public and globally accessible singleton pattern that we looked at last time.

115
00:08:01,220 --> 00:08:07,730
But with that set up, then let's go into our load game and before we load the scene we want to say

116
00:08:07,730 --> 00:08:10,640
scorekeeper dot reset score.

117
00:08:11,000 --> 00:08:14,930
So whenever we load into our main game, our score will now be reset.

118
00:08:15,290 --> 00:08:20,150
So let's save all of our scripts and jump back into Unity one last time for some testing.

119
00:08:20,390 --> 00:08:24,860
Let's go ahead and hit play and we're on the game over screen at the moment.

120
00:08:24,860 --> 00:08:26,300
So our score is zero.

121
00:08:26,510 --> 00:08:31,340
But if we play again and rack up some points, we don't need to rack up many.

122
00:08:31,340 --> 00:08:34,280
We really just need the minimum amount of 50.

123
00:08:34,909 --> 00:08:40,190
Our score is transferred over, but if we play again, our score gets reset.

124
00:08:41,210 --> 00:08:44,059
And we thought, I think our game is pretty much there.

125
00:08:44,059 --> 00:08:47,780
We have a nice gameplay loop which we created with our different menus.

126
00:08:47,780 --> 00:08:53,240
Our score is nicely transitioning across from our different scenes and being reset at the right time.

127
00:08:53,270 --> 00:08:59,210
Our audio player is playing our music consistently through our levels, and really the only thing left

128
00:08:59,210 --> 00:09:01,220
to do is to add some more content.

129
00:09:01,220 --> 00:09:07,700
So more waves, more enemies, more explosions, playtest our game and finally build our game so that

130
00:09:07,700 --> 00:09:09,110
other people can play it.

131
00:09:09,290 --> 00:09:14,750
So congratulations on getting everything working and we'll talk about some play testing and balancing

132
00:09:14,750 --> 00:09:15,770
in the next lecture.

133
00:09:15,770 --> 00:09:16,940
So I'll see you there.

