WEBVTT 1 00:00:05.765 --> 00:00:09.636 Game Advanced Edition Alpha Type Version 2 2 00:00:09.636 --> 00:00:12.081 GCC Academy 3 00:00:27.728 --> 00:00:28.728 Hi 4 00:00:28.728 --> 00:00:32.203 I am Lee Youngho, in charge of the shooting game development lecture 5 00:00:32.203 --> 00:00:34.603 In this lesson, we will learn 6 00:00:34.603 --> 00:00:36.540 the second version of the Alpha type 7 00:00:36.540 --> 00:00:40.332 First, we will add the score 8 00:00:40.332 --> 00:00:45.025 Second, we will create the UI to display the score on the screen 9 00:00:45.025 --> 00:00:48.075 Finally, we will learn 10 00:00:48.075 --> 00:00:50.203 how to save and load the high score 11 00:00:50.540 --> 00:00:54.274 Adding the Score 12 00:00:56.180 --> 00:00:58.209 The second version of the Alpha type 13 00:00:59.422 --> 00:01:01.867 Let's start off with adding the score 14 00:01:03.540 --> 00:01:05.240 Come to Unity editor 15 00:01:05.240 --> 00:01:09.540 Let's create an object to manage the score 16 00:01:09.540 --> 00:01:12.040 In the Hierarchy, press + 17 00:01:12.040 --> 00:01:13.290 the object responsible for the score 18 00:01:13.290 --> 00:01:15.045 doesn't have to be visible 19 00:01:15.045 --> 00:01:18.645 So, let's create it as an empty GameObject 20 00:01:18.645 --> 00:01:21.545 press Create Empty 21 00:01:21.545 --> 00:01:24.840 Name it as ScoreManager 22 00:01:24.840 --> 00:01:28.340 You can locate it anywhere 23 00:01:28.340 --> 00:01:33.400 Next, we'll attach a script to this ScoreManager 24 00:01:33.400 --> 00:01:39.240 Let's go to our Scripts folder, click + button and select C# Script 25 00:01:39.240 --> 00:01:43.053 Name it as ScoreManager 26 00:01:48.240 --> 00:01:50.340 Let's attach the script we've made 27 00:01:50.340 --> 00:01:54.040 to the ScoreManager gameObject 28 00:01:54.040 --> 00:01:58.446 In the ScoreManager, we will handle tasks like increasing the score 29 00:01:58.446 --> 00:01:59.696 and other related operations right? 30 00:01:59.696 --> 00:02:03.520 Then when does this score increase 31 00:02:03.520 --> 00:02:06.620 and displayed on the screen? When should these tasks be done? 32 00:02:06.620 --> 00:02:08.070 It's when Enemy is destroyed 33 00:02:08.070 --> 00:02:10.400 So let's implement following these concept 34 00:02:10.400 --> 00:02:15.000 So first, let's add the necessary score 35 00:02:15.000 --> 00:02:17.200 and properties and so on 36 00:02:17.200 --> 00:02:20.279 to the ScoreManager all together 37 00:02:20.279 --> 00:02:24.345 First, let's add a necessary property to the ScoreManager 38 00:02:24.345 --> 00:02:27.000 Which is the current score 39 00:02:27.000 --> 00:02:31.000 To display the current score 40 00:02:31.000 --> 00:02:32.599 let's define a variable for the score 41 00:02:32.599 --> 00:02:37.249 We will define it as 42 00:02:37.249 --> 00:02:38.687 public int currentScore 43 00:02:42.565 --> 00:02:47.800 The currentScore will be added to the ScoreManager 44 00:02:47.800 --> 00:02:51.200 Next, when should the currentScore be increased? 45 00:02:51.200 --> 00:02:53.550 Should be when enemy dies 46 00:02:53.550 --> 00:02:56.691 So, when the player collides with an enemy 47 00:02:56.691 --> 00:03:00.841 or when the enemy gets hit by a bullet, the enemy will die 48 00:03:00.841 --> 00:03:04.388 At that point, let's implement the logic 49 00:03:04.388 --> 00:03:07.388 to increase the score 50 00:03:07.388 --> 00:03:12.253 So, for Player 51 00:03:12.253 --> 00:03:14.303 When Bullet and Player collides 52 00:03:14.303 --> 00:03:18.602 This calls a function, when colliding 53 00:03:21.000 --> 00:03:24.787 increase the score 54 00:03:26.240 --> 00:03:32.639 Let's implement this part in this line here 55 00:03:32.639 --> 00:03:35.889 Where is the CurrentScore right now? 56 00:03:35.889 --> 00:03:38.800 It's in ScoreManager 57 00:03:38.800 --> 00:03:44.119 We want to set the final value of currentScore in the ScoreManager 58 00:03:44.119 --> 00:03:46.136 Let's look at the structure of this concept 59 00:03:49.264 --> 00:03:52.764 Let's first see where it is structured 60 00:03:52.764 --> 00:03:55.720 First, what we ultimately want to do is 61 00:03:55.720 --> 00:03:58.476 the currentScore function 62 00:04:02.080 --> 00:04:05.180 If we look at who owns it 63 00:04:05.180 --> 00:04:09.199 it is owned by the ScoreManager component 64 00:04:09.199 --> 00:04:11.749 Let's say it's S.M 65 00:04:11.749 --> 00:04:15.299 So a component named S.M 66 00:04:15.299 --> 00:04:17.759 internally holds currentScore 67 00:04:17.759 --> 00:04:21.641 If it's a circle, scoreManager component 68 00:04:21.641 --> 00:04:25.257 holds this property like this 69 00:04:25.257 --> 00:04:28.757 Then, who owns ScoreManager component? 70 00:04:28.757 --> 00:04:32.960 It's the GameObject that owns 71 00:04:32.960 --> 00:04:37.880 this component and what's the name of the object? 72 00:04:37.880 --> 00:04:41.130 The GameObject is called ScoreManager 73 00:04:41.130 --> 00:04:46.399 This is what owns currentScore as a property 74 00:04:46.399 --> 00:04:49.814 The GameObject that holds the ScoreManager component 75 00:04:49.814 --> 00:04:52.039 is the ScoreManager GameObject itself 76 00:04:52.039 --> 00:04:55.639 So, for the first step, we need this one 77 00:04:55.639 --> 00:04:59.360 can get the second step's ScoreManager component 78 00:04:59.360 --> 00:05:02.260 Only then, in the third step, we can access 79 00:05:02.260 --> 00:05:05.011 this currentScore and that's the logic for this feature 80 00:05:08.039 --> 00:05:13.139 Then, when Enemy collide 81 00:05:13.139 --> 00:05:18.851 What do we need first in order to increase the score? 82 00:05:18.851 --> 00:05:24.825 From the scene, we need to find 83 00:05:24.825 --> 00:05:29.284 ScoreManager GameObject 84 00:05:29.284 --> 00:05:35.880 Then, we can get the ScoreManager component 85 00:05:35.880 --> 00:05:44.131 attached to this GameObject 86 00:05:44.131 --> 00:05:53.231 and thirdly, let's put increase currentScore 87 00:05:53.231 --> 00:05:58.320 We can understand this sequence of events through 1 to 3 steps 88 00:05:58.320 --> 00:06:02.200 So first, from the scene, let's get ScoreManager 89 00:06:02.200 --> 00:06:05.150 ScoreManager to gameObject 90 00:06:05.150 --> 00:06:08.359 I'll put it as smObject like this 91 00:06:08.359 --> 00:06:10.559 And how do we do this 92 00:06:10.559 --> 00:06:12.209 when looking for gameObject in Scene 93 00:06:12.209 --> 00:06:16.519 You can simply use Find function in gameObject 94 00:06:16.519 --> 00:06:19.269 Now, let's find gameObject 95 00:06:19.269 --> 00:06:22.076 that is named ScoreManager 96 00:06:25.279 --> 00:06:28.029 Then, since we found the GameObject 97 00:06:28.029 --> 00:06:32.440 We also can get the component attached to GameObject 98 00:06:32.440 --> 00:06:36.190 The name of this component is scoreManager component 99 00:06:36.190 --> 00:06:39.320 Let's leave it as sm 100 00:06:39.320 --> 00:06:43.799 Where is it? it's attached to sm Object 101 00:06:43.799 --> 00:06:45.949 To get the component in it 102 00:06:45.949 --> 00:06:48.749 you can use the .GetComponent function 103 00:06:48.749 --> 00:06:52.959 to access its properties or functionalities 104 00:06:52.959 --> 00:06:57.405 Get me the desired ScoreManager script 105 00:06:57.405 --> 00:07:00.055 Get me the desired component 106 00:07:00.055 --> 00:07:04.399 using this function, we can get the component 107 00:07:04.399 --> 00:07:06.799 After that, you can increase 108 00:07:06.799 --> 00:07:12.200 the currentScore in sm like this 109 00:07:12.200 --> 00:07:16.679 If we do this, the score will increase by 1, right? 110 00:07:16.679 --> 00:07:19.579 Then, let's check if the score is increasing correctly 111 00:07:19.579 --> 00:07:25.279 by displaying the current score on the screen 112 00:07:25.279 --> 00:07:30.535 Let's put "Current Score" in the print 113 00:07:30.535 --> 00:07:36.399 and try printing sm.currentScore like this 114 00:07:36.399 --> 00:07:39.916 Save and back to Unity 115 00:07:42.320 --> 00:07:44.480 and click play button 116 00:07:46.679 --> 00:07:49.729 So bang bang bang! 117 00:07:52.361 --> 00:07:54.074 That should be enough 118 00:07:54.074 --> 00:07:56.724 Let's check the printed output 119 00:07:56.724 --> 00:08:01.077 Go to the console window and we have score of 1, 2, 3, 4, 5, 6 120 00:08:01.077 --> 00:08:05.399 We can see that the score is increasing by 1 121 00:08:05.399 --> 00:08:09.844 This way, we've tried increasing the current score 122 00:08:10.131 --> 00:08:14.190 Creating the Score UI 123 00:08:15.256 --> 00:08:18.656 Now that we've created the current score 124 00:08:18.656 --> 00:08:21.156 let's create a UI to display 125 00:08:21.156 --> 00:08:23.640 this score to the user 126 00:08:23.640 --> 00:08:25.290 How are we going to build this? 127 00:08:25.290 --> 00:08:30.480 If this is the game screen, on the top left 128 00:08:30.480 --> 00:08:33.380 Let's create a structure that will 129 00:08:33.380 --> 00:08:35.320 display the current score here 130 00:08:35.320 --> 00:08:37.470 whenever Player destroys Enemy 131 00:08:37.470 --> 00:08:39.570 Each time Player defeats Enemy 132 00:08:39.570 --> 00:08:41.165 score will be displayed here 133 00:08:43.200 --> 00:08:45.425 Back to Unity again 134 00:08:48.040 --> 00:08:50.240 To display UI in Unity 135 00:08:50.240 --> 00:08:54.519 Expand Hierarchy using the + button 136 00:08:54.519 --> 00:08:57.119 Click the + button and open it 137 00:08:57.119 --> 00:09:00.040 There's UI in the drop down list 138 00:09:00.040 --> 00:09:02.990 In the UI, you will see Text 139 00:09:02.990 --> 00:09:04.390 and if you expand it, there's TextMeshPro 140 00:09:04.390 --> 00:09:06.040 So there's TextMeshPro 141 00:09:06.040 --> 00:09:08.790 And in the Legacy, choose Text 142 00:09:08.790 --> 00:09:12.720 It doesn't matter which one we use for now 143 00:09:12.720 --> 00:09:16.170 However, recently Unity recommends 144 00:09:16.170 --> 00:09:18.239 using TextMeshPro 145 00:09:18.239 --> 00:09:23.706 Whether it's 2D or 3D, TextMeshPro is recommended 146 00:09:23.706 --> 00:09:26.056 because it offers better performance 147 00:09:26.056 --> 00:09:28.408 and handles resolution more efficiently 148 00:09:28.408 --> 00:09:32.679 So, this time, we will use TextMeshPro 149 00:09:32.679 --> 00:09:37.379 Click on it, we can see TMP, which stands for TextMeshPro 150 00:09:37.379 --> 00:09:38.839 and also an Importer will appear 151 00:09:38.839 --> 00:09:41.989 We see a new button 152 00:09:41.989 --> 00:09:43.559 called Import TMP Essentials here 153 00:09:43.559 --> 00:09:44.759 So you get this window 154 00:09:44.759 --> 00:09:48.184 Let's click Import TMP Essentials 155 00:09:50.559 --> 00:09:54.000 Once you click it, it imports something right? Close this window now 156 00:09:54.000 --> 00:09:55.800 In the project window, 157 00:09:55.800 --> 00:09:59.050 We can see a new folder created 158 00:09:59.050 --> 00:10:01.446 called TextMeshPro here 159 00:10:04.826 --> 00:10:10.039 What is the structure of UI in Unity? 160 00:10:10.039 --> 00:10:12.012 Let's talk about it more 161 00:10:14.039 --> 00:10:20.119 In Unity, the UI elements are attached 162 00:10:20.119 --> 00:10:23.469 under a GameObject 163 00:10:23.469 --> 00:10:27.280 called Canvas by default 164 00:10:27.280 --> 00:10:32.130 and you know there is some kind of button for events 165 00:10:32.130 --> 00:10:34.560 that triggers inside the UI 166 00:10:34.560 --> 00:10:37.813 for us to handle such events, an object 167 00:10:37.813 --> 00:10:39.308 called the Event System 168 00:10:42.534 --> 00:10:45.337 is additionally and automatically created 169 00:10:45.337 --> 00:10:48.000 We have simply created a button here 170 00:10:48.000 --> 00:10:53.000 or in this case, we have created a TextMeshPro text 171 00:10:53.000 --> 00:10:56.000 When we create UI elements 172 00:10:56.000 --> 00:10:59.000 to handle events occurring 173 00:10:59.000 --> 00:11:01.713 in first canvas and in Event System 174 00:11:01.713 --> 00:11:03.802 these objects automatically added 175 00:11:03.802 --> 00:11:08.990 So they are registered as child objects under the Canvas 176 00:11:09.000 --> 00:11:13.515 to display the entire UI on the screen 177 00:11:13.515 --> 00:11:17.614 the Canvas is automatically created 178 00:11:17.614 --> 00:11:20.000 with a size that corresponds to the resolution 179 00:11:20.000 --> 00:11:23.614 which refers to the current monitor's resolution 180 00:11:23.614 --> 00:11:26.139 It refers to the resolution of the smartphone's display 181 00:11:26.139 --> 00:11:32.554 So, for example, if there is 182 00:11:32.554 --> 00:11:35.634 a resolution size like 1024 or 2048 183 00:11:35.634 --> 00:11:39.000 These numbers represent the resolution size 184 00:11:39.000 --> 00:11:42.000 when moving objects in Unity 185 00:11:42.000 --> 00:11:44.643 The units corresponds to meters 186 00:11:44.643 --> 00:11:48.000 But this unit, 1024, 2048 187 00:11:48.000 --> 00:11:51.000 that we use in this Canvas, UI 188 00:11:51.000 --> 00:11:53.485 we use pixel units 189 00:11:53.485 --> 00:11:57.000 A pixel is a small dot that determines 190 00:11:57.000 --> 00:11:59.564 the color displayed on the screen 191 00:11:59.564 --> 00:12:01.564 Let's draw a square, these dots 192 00:12:01.564 --> 00:12:06.000 Each of these dot squares has three elements 193 00:12:06.000 --> 00:12:11.148 R, G, and B, which represent the color values 194 00:12:11.148 --> 00:12:15.000 This single square is what we call a pixel 195 00:12:15.000 --> 00:12:16.247 How many of these are there? 196 00:12:16.247 --> 00:12:20.554 If 1024 pixels are arranged horizontally, that represents the pixel grid 197 00:12:20.554 --> 00:12:23.436 which can be considered as the coordinate system on the screen 198 00:12:23.436 --> 00:12:27.198 The space where objects are placed in Unity is 199 00:12:27.198 --> 00:12:28.337 the world space 200 00:12:28.337 --> 00:12:31.307 Screen and World are different 201 00:12:31.307 --> 00:12:33.782 in a virtual world, we use meters 202 00:12:33.782 --> 00:12:37.000 The units used for displaying objects on the screen's UI 203 00:12:37.000 --> 00:12:39.347 are based on resolution pixel units 204 00:12:42.307 --> 00:12:44.557 So, the size of the Canvas is adjusted 205 00:12:44.557 --> 00:12:49.000 to match the actual screen size 206 00:12:49.000 --> 00:12:53.089 So, since we are trying to display both the meter based 207 00:12:53.089 --> 00:12:56.535 units for objects in the virtual space and the pixel based 208 00:12:56.535 --> 00:12:59.337 screen coordinates for the Canvas 209 00:12:59.337 --> 00:13:02.475 at the same time in the scene view 210 00:13:02.475 --> 00:13:05.921 Our player is present right here 211 00:13:05.921 --> 00:13:08.772 when the Canvas elements are added 212 00:13:08.772 --> 00:13:10.257 If you look at this in details 213 00:13:10.257 --> 00:13:12.544 There is a white line drawn 214 00:13:12.544 --> 00:13:13.505 What is this? 215 00:13:13.505 --> 00:13:15.574 Let's double click on it to view it 216 00:13:15.574 --> 00:13:19.544 Let's double click the Canvas to view it 217 00:13:19.544 --> 00:13:22.119 Then how is it? 218 00:13:22.119 --> 00:13:24.376 As you can see, there is a rectangular border 219 00:13:24.376 --> 00:13:26.495 drawn around the outer edge 220 00:13:26.495 --> 00:13:29.713 What is the size of this? 221 00:13:29.713 --> 00:13:32.000 If we go to the right and check the Canvas 222 00:13:32.000 --> 00:13:36.366 we can see that the Rect Transform is set like this 223 00:13:36.366 --> 00:13:42.000 The width is set to 640, and the height is set to 960 224 00:13:42.000 --> 00:13:44.060 It is set to match 225 00:13:44.060 --> 00:13:48.752 the resolution size we defined for the shooting game 226 00:13:48.752 --> 00:13:52.000 But since it's in pixel units rather than meter units 227 00:13:52.000 --> 00:13:55.614 this screen is displayed using meter units 228 00:13:55.614 --> 00:13:59.228 Since Player is meter based 229 00:13:59.228 --> 00:14:01.554 It's set to this size 230 00:14:01.554 --> 00:14:04.000 Since we are trying to display it in a single space 231 00:14:04.000 --> 00:14:05.386 How is it for Canvas? 232 00:14:05.386 --> 00:14:08.782 It will be displayed in the scene as if it were 960 meters in size 233 00:14:08.782 --> 00:14:11.742 But in reality, the unit it uses is what? 234 00:14:11.742 --> 00:14:15.683 It is in pixel units, specifically 640 here 235 00:14:15.683 --> 00:14:18.594 Then the Text here 236 00:14:18.594 --> 00:14:21.475 is also in pixel based units 237 00:14:21.475 --> 00:14:24.000 If you look in the bottom left here 238 00:14:24.000 --> 00:14:26.485 we can see it in the game window 239 00:14:26.485 --> 00:14:29.386 These can also be grabbed and moved 240 00:14:29.386 --> 00:14:33.643 allowing us to position and display them 241 00:14:33.643 --> 00:14:36.564 if we were to add a Button 242 00:14:36.564 --> 00:14:42.000 it will also appear in the UI just like the TextMeshPro 243 00:14:42.000 --> 00:14:46.000 we can add it the same way 244 00:14:46.000 --> 00:14:49.346 the structure where we add elements one by one, like this 245 00:14:49.346 --> 00:14:50.746 For this project, we don't need the button 246 00:14:50.746 --> 00:14:52.951 Let's remove it by pressing Delete button 247 00:14:56.574 --> 00:15:00.267 So, UI elements are attached under the Canvas, like this 248 00:15:00.267 --> 00:15:04.346 Because these elements correspond to the screen size, they are placed accordingly 249 00:15:04.346 --> 00:15:07.406 And if you look at some of the other objects 250 00:15:07.406 --> 00:15:08.856 like ScoreManager 251 00:15:08.856 --> 00:15:10.495 or Background 252 00:15:10.495 --> 00:15:13.346 There is a Transform component attached 253 00:15:13.346 --> 00:15:16.505 So, the position, rotation, and size values are set like this 254 00:15:16.505 --> 00:15:18.000 If we look at Canvas first 255 00:15:18.000 --> 00:15:21.663 Which UI related elements are attached? 256 00:15:21.663 --> 00:15:24.416 It's the RectTransform that's attached 257 00:15:24.416 --> 00:15:28.158 Why? simply because Transform uses meter based units value 258 00:15:28.158 --> 00:15:31.000 This one uses pixel-based units 259 00:15:31.000 --> 00:15:34.000 Additionally, since various options need to be used for this 260 00:15:34.000 --> 00:15:36.900 these UI elements have 261 00:15:36.900 --> 00:15:39.000 a special RectTransform attached 262 00:15:41.485 --> 00:15:43.135 And these are all attached as children 263 00:15:43.135 --> 00:15:45.000 to be handled like this 264 00:15:45.000 --> 00:15:48.000 There, we added a Text UI element 265 00:15:48.000 --> 00:15:51.000 to the TextMeshPro 266 00:15:53.475 --> 00:15:55.158 Now, let's arrange it 267 00:15:55.158 --> 00:15:58.990 I will place it in the top-left corner like this 268 00:15:58.990 --> 00:16:01.416 Currently, I've placed it here 269 00:16:01.416 --> 00:16:03.376 and in this state, it's located here 270 00:16:03.376 --> 00:16:07.921 If we stretch it horizontally like this 271 00:16:07.921 --> 00:16:10.891 it will stay in the same position 272 00:16:10.891 --> 00:16:13.218 What happens if we change the resolution like this? 273 00:16:13.218 --> 00:16:16.000 The element that was here earlier will move to an unexpected position 274 00:16:16.000 --> 00:16:19.485 Also the size will change 275 00:16:19.485 --> 00:16:22.000 4K, then it gets too small 276 00:16:22.000 --> 00:16:24.663 The position changes, and it behaves like this 277 00:16:24.663 --> 00:16:27.663 If we switch it back to shooting, it will look like this 278 00:16:27.663 --> 00:16:31.505 So, when objects change their position 279 00:16:31.505 --> 00:16:35.000 according to resolution 280 00:16:35.000 --> 00:16:37.376 Displaying UI becomes difficult 281 00:16:37.376 --> 00:16:41.634 If we select the Text UI and go to the right 282 00:16:41.634 --> 00:16:44.851 we can see an option called Anchor Preset 283 00:16:44.851 --> 00:16:47.267 If we click this one 284 00:16:47.267 --> 00:16:50.307 we need to determine the reference point for alignment 285 00:16:50.307 --> 00:16:53.515 So we will select 286 00:16:53.515 --> 00:16:56.000 Top left 287 00:16:56.000 --> 00:16:58.634 because we want left and top to overlap 288 00:16:58.634 --> 00:17:01.366 Click this to select 289 00:17:03.624 --> 00:17:07.089 and then select its position at the top left 290 00:17:07.089 --> 00:17:08.990 changing it to top left 291 00:17:10.861 --> 00:17:14.317 we can move it like this 292 00:17:14.317 --> 00:17:21.228 or position it with W on keyboard 293 00:17:21.228 --> 00:17:24.000 I will place it at the top left like this 294 00:17:24.000 --> 00:17:27.000 This one is aligned 295 00:17:27.000 --> 00:17:30.901 to Left and Top like this 296 00:17:30.901 --> 00:17:33.386 Now, I'll change the size to something else 297 00:17:33.386 --> 00:17:35.436 and see how it looks 298 00:17:35.436 --> 00:17:38.327 Then, how is it? it became strange 299 00:17:38.327 --> 00:17:41.000 when we used a different value and why? 300 00:17:41.000 --> 00:17:43.495 What's the resolution for this now? 301 00:17:43.495 --> 00:17:45.396 This is the resolution, the whole thing in this window 302 00:17:45.396 --> 00:17:49.951 It's definitely positioned at Left Top continuously 303 00:17:49.951 --> 00:17:53.247 No matter how much we change the resolution or switch to Free Aspect 304 00:17:53.247 --> 00:17:56.000 even when the screen is set to full screen 305 00:17:56.000 --> 00:17:59.000 it will always stay in the top left position that we specified 306 00:18:02.554 --> 00:18:05.000 It will stay in the exact same top left position 307 00:18:05.000 --> 00:18:08.287 How about background? Depending on the resolution 308 00:18:08.287 --> 00:18:11.515 the background will need to be automatically adjusted 309 00:18:11.515 --> 00:18:13.307 or it would be necessary to create 310 00:18:13.307 --> 00:18:17.000 the texture at the required size from the beginning 311 00:18:19.000 --> 00:18:23.000 Anyway, we've arranged the UI like this 312 00:18:23.000 --> 00:18:26.000 Let's rename it to CurrentScore 313 00:18:29.376 --> 00:18:31.693 So, change it to CurrentScore 314 00:18:33.871 --> 00:18:36.980 The default width and height are set like this, right? 315 00:18:36.980 --> 00:18:40.280 The default size was 316 00:18:40.280 --> 00:18:42.485 probably 200 by 50 317 00:18:42.485 --> 00:18:46.624 So, we'll adjust the Width and Height to match like this 318 00:18:46.624 --> 00:18:48.544 and then go to bottom 319 00:18:48.544 --> 00:18:50.394 The text content is 320 00:18:50.394 --> 00:18:52.069 New Text right now 321 00:18:52.069 --> 00:18:55.386 Let's change it to current score 322 00:18:55.386 --> 00:18:57.218 Current Score 323 00:18:57.218 --> 00:18:59.495 and then put a space, followed by a colon 324 00:18:59.495 --> 00:19:01.138 I will make sure it is displayed correctly 325 00:19:03.000 --> 00:19:06.653 And if the text exceeds the space 326 00:19:06.653 --> 00:19:09.554 it will be displayed with a line break on the screen 327 00:19:09.554 --> 00:19:12.000 So we need to set it 328 00:19:12.000 --> 00:19:14.200 so it doesn't do a line break 329 00:19:14.200 --> 00:19:16.396 and keep the text to be added horizontally 330 00:19:16.396 --> 00:19:18.376 How can we do that? 331 00:19:18.376 --> 00:19:21.000 If you scroll down a bit 332 00:19:21.000 --> 00:19:23.000 you'll see the Wrapping Mode 333 00:19:23.000 --> 00:19:25.000 Wrapping means to cover 334 00:19:25.000 --> 00:19:27.168 This means that when it reaches the end of the size 335 00:19:27.168 --> 00:19:31.000 it will move to the next line 336 00:19:31.000 --> 00:19:35.000 So, if you set the Wrapping to Disabled 337 00:19:35.000 --> 00:19:36.703 the text will continue horizontally like this 338 00:19:36.703 --> 00:19:39.792 This works thanks to this property called Overflow 339 00:19:39.792 --> 00:19:43.000 What is Over? having more than enough, Flow, to run 340 00:19:43.000 --> 00:19:46.594 it means that even if the text exceeds this size 341 00:19:46.594 --> 00:19:49.139 it will still be fully displayed 342 00:19:49.139 --> 00:19:51.039 put Wrapping to Disabled 343 00:19:51.039 --> 00:19:53.347 You can display it like this 344 00:19:56.198 --> 00:20:00.772 For the current score, I'll exclude this and take a look 345 00:20:00.772 --> 00:20:02.861 The font size is currently set to 36 346 00:20:02.861 --> 00:20:04.842 Oh, but there's an issue here 347 00:20:04.842 --> 00:20:08.257 Korean text is not being processed here 348 00:20:08.257 --> 00:20:13.584 English texts or numbers were fine 349 00:20:13.584 --> 00:20:18.188 There is an issue for Korean text 350 00:20:18.188 --> 00:20:21.703 So, let's try to solve this issue 351 00:20:21.703 --> 00:20:24.000 Please open the Explorer 352 00:20:24.000 --> 00:20:29.723 We will search in the Explorer, but where should we go? 353 00:20:29.723 --> 00:20:32.604 Go to C drive first 354 00:20:32.604 --> 00:20:36.990 into the Windows folder 355 00:20:39.000 --> 00:20:41.000 After you find windows folder 356 00:20:41.000 --> 00:20:43.000 there is Fonts folder 357 00:20:43.000 --> 00:20:45.426 Windows folder and to Fonts folder 358 00:20:45.426 --> 00:20:51.267 Press F in your keyboard then it will take you to Fonts 359 00:20:51.267 --> 00:20:54.000 and then in there, search for Fonts 360 00:20:54.000 --> 00:21:01.000 on the top, there is a search box 361 00:21:01.000 --> 00:21:05.050 let's look for Nanum Gothic 362 00:21:08.574 --> 00:21:10.733 There we can access the font we want 363 00:21:14.000 --> 00:21:17.426 Nanum Gothic is displayed here 364 00:21:17.426 --> 00:21:20.000 So, what you can do here is 365 00:21:20.000 --> 00:21:22.535 you can set detailed view mode 366 00:21:22.535 --> 00:21:25.643 Anyways, we have Nanum Gothic here 367 00:21:25.643 --> 00:21:29.733 We will drag it and drop it in a proper place 368 00:21:29.733 --> 00:21:33.822 Where should we do that? Remember TextMeshPro? 369 00:21:33.822 --> 00:21:36.643 Under this folder, we can find Fonts folder 370 00:21:36.643 --> 00:21:41.346 Let's place the font we wanted 371 00:21:41.346 --> 00:21:44.317 From the file explorer, drag and drop Nanum Gothic 372 00:21:44.317 --> 00:21:45.436 into the fonts folder 373 00:21:45.436 --> 00:21:48.218 If you have a different font you want to use 374 00:21:48.218 --> 00:21:50.406 You can freely use that font 375 00:21:50.406 --> 00:21:52.673 I am just going to use Nanum Gothic 376 00:21:52.673 --> 00:21:54.950 So that's that 377 00:21:54.950 --> 00:21:56.614 Then, it's loading right now 378 00:21:56.614 --> 00:21:58.990 It's because this folder is using import feature 379 00:21:58.990 --> 00:22:01.545 So this part will take some time 380 00:22:04.901 --> 00:22:06.663 When the loading finishes 381 00:22:06.663 --> 00:22:09.604 we can see that the font is added into the program 382 00:22:09.604 --> 00:22:11.951 From Bold font 383 00:22:11.951 --> 00:22:13.476 Everything is added here 384 00:22:16.535 --> 00:22:19.000 Once Nanum Gothic is added 385 00:22:19.000 --> 00:22:21.485 we need to apply it 386 00:22:21.485 --> 00:22:23.683 to the font we intend to use 387 00:22:23.683 --> 00:22:27.564 To do that, we need to add some content 388 00:22:27.564 --> 00:22:29.317 provided by TextMeshPro 389 00:22:29.317 --> 00:22:33.079 There is something called TextMeshPro in Window 390 00:22:35.148 --> 00:22:38.386 There, we can find Font Asset Creator 391 00:22:38.386 --> 00:22:40.148 Even if it's registered like this 392 00:22:40.148 --> 00:22:42.386 you need to recreate it 393 00:22:42.386 --> 00:22:44.713 using the font provided by TextMeshPro 394 00:22:44.713 --> 00:22:48.000 So, click on the Font Asset Creator 395 00:22:48.000 --> 00:22:51.713 and the Font Asset Creator window will open 396 00:22:54.455 --> 00:22:56.267 To here, the font we found 397 00:22:56.267 --> 00:22:57.812 Nanum Gothic, drag and drop it 398 00:22:57.812 --> 00:22:59.317 to this Font part here 399 00:22:59.317 --> 00:23:01.627 called Source Font File 400 00:23:01.627 --> 00:23:03.456 Make sure to drag and drop it like this 401 00:23:09.564 --> 00:23:11.653 For the size, use Auto Sizing 402 00:23:11.653 --> 00:23:14.000 Let's use other values as default 403 00:23:14.000 --> 00:23:16.050 Padding 5 404 00:23:16.050 --> 00:23:18.733 Packing Method at Fast 405 00:23:18.733 --> 00:23:20.283 For Atlas Resolution 406 00:23:20.283 --> 00:23:22.346 Your default must be different 407 00:23:22.346 --> 00:23:26.475 But I will make it bigger by 4096x4096 408 00:23:26.495 --> 00:23:30.356 The Atlas is an image that combines all the individual images 409 00:23:30.356 --> 00:23:32.756 placing them all into a single texture of size 4096 410 00:23:32.756 --> 00:23:36.307 into one large image 411 00:23:36.307 --> 00:23:39.307 Make sure your values match mine 412 00:23:39.307 --> 00:23:42.198 and in the bottom of the list, we have Generate Font Atlas button 413 00:23:42.198 --> 00:23:44.713 Let's click it 414 00:23:44.713 --> 00:23:48.317 Then, the process of packing is included 415 00:23:51.643 --> 00:23:54.792 If you can see that Generation completed 416 00:23:54.792 --> 00:23:58.000 In the bottom of the window, there is Save button 417 00:23:58.000 --> 00:24:02.327 And the images or textures created here will also appear 418 00:24:02.327 --> 00:24:04.624 Let's click the save button 419 00:24:04.624 --> 00:24:07.000 Then, a dialog box will appear 420 00:24:07.000 --> 00:24:10.277 asking where to save this file 421 00:24:13.495 --> 00:24:15.345 Save this 422 00:24:15.345 --> 00:24:20.000 Let's just save wherever it directs us to by default 423 00:24:20.000 --> 00:24:23.200 In here, NANUMGOTHIC.SDF 424 00:24:23.200 --> 00:24:25.089 Like this, we completed our creation 425 00:24:28.138 --> 00:24:32.554 Now, select this NANUMGOTHIC.SDF 426 00:24:32.554 --> 00:24:36.366 and go to inspector window on the right 427 00:24:36.366 --> 00:24:41.000 If you look here, in the part below a property called Generation Settings 428 00:24:41.000 --> 00:24:45.455 You can see Atlas Population Mode 429 00:24:45.455 --> 00:24:47.505 This Atlas Population Mode is 430 00:24:47.505 --> 00:24:50.178 set to Static right now 431 00:24:50.178 --> 00:24:53.505 Let's switch it to Dynamic 432 00:24:53.515 --> 00:24:55.315 And let's change 433 00:24:55.315 --> 00:24:57.307 Sampling point size to 60 434 00:24:59.247 --> 00:25:02.841 Then an Apply button appears in the below 435 00:25:02.841 --> 00:25:05.391 Atlas Population Mode to Dynamic 436 00:25:05.391 --> 00:25:07.540 and Sampling Point size 437 00:25:07.540 --> 00:25:09.540 to 60, like this, we've made the change 438 00:25:09.540 --> 00:25:11.797 Click the Apply button 439 00:25:14.035 --> 00:25:16.282 Close this window 440 00:25:16.282 --> 00:25:19.411 Now, delete this in currentScore 441 00:25:23.114 --> 00:25:25.342 Even if I write in Korean...wait 442 00:25:25.342 --> 00:25:29.273 We haven't changed the Font Asset to one we wanted to use 443 00:25:29.273 --> 00:25:31.173 Now, let's drag and drop this 444 00:25:31.173 --> 00:25:33.312 into the Font Asset section 445 00:25:33.312 --> 00:25:35.599 If you grab it to drag and drop here like this 446 00:25:35.599 --> 00:25:38.956 ABCD, it works fine now 447 00:25:38.956 --> 00:25:43.688 So in this part, we can finally 448 00:25:43.688 --> 00:25:46.540 write in the text of Current Score 449 00:25:46.540 --> 00:25:51.035 By adding a working font 450 00:25:51.035 --> 00:25:52.540 we've managed to fix broken font 451 00:25:52.540 --> 00:25:57.233 Up to this point, we've added the font to TextMeshPro and applied it 452 00:25:57.233 --> 00:26:02.233 ensuring that Korean characters are now displayed correctly 453 00:26:02.233 --> 00:26:06.956 Now, let's work on setting up the currentScore so that the current score 454 00:26:06.956 --> 00:26:10.599 can be registered and displayed properly 455 00:26:10.599 --> 00:26:15.045 Let's go to ScoreManager in Visual Studio 456 00:26:15.045 --> 00:26:18.540 Bring TexMnshPro UP here 457 00:26:18.540 --> 00:26:21.540 we need to change the Text value here,whever? 458 00:26:21.540 --> 00:26:23.440 TextMeshPro under CurrntScore 459 00:26:23.440 --> 00:26:25.282 What is this GameOject? 460 00:26:25.282 --> 00:26:28.144 The one that says TextMeshPro with UI, right? 461 00:26:28.144 --> 00:26:30.540 We need to change the sentence written in this box 462 00:26:30.540 --> 00:26:33.114 So we need to be able to bring 463 00:26:33.114 --> 00:26:37.540 this component and fix the value inside that component 464 00:26:37.540 --> 00:26:40.797 So how do we do this? In here 465 00:26:40.797 --> 00:26:44.916 Let's register the current score UI 466 00:26:44.916 --> 00:26:53.956 Its name is public TextMeshProUGUI 467 00:26:53.956 --> 00:26:59.302 I will name it curScoreText 468 00:27:03.718 --> 00:27:07.540 As you can see, in Visual Studio, the namespaces TMP and TMPro 469 00:27:07.540 --> 00:27:12.577 are automatically included to use it 470 00:27:12.577 --> 00:27:15.540 Make sure to check if this one is registered under using 471 00:27:15.540 --> 00:27:18.540 If this isn't done properly, an error can occur 472 00:27:18.540 --> 00:27:22.540 So, please check this here 473 00:27:24.540 --> 00:27:28.890 If there's no problem, in this UI 474 00:27:28.890 --> 00:27:30.857 put current value 475 00:27:30.857 --> 00:27:33.282 into the value this function has 476 00:27:33.282 --> 00:27:35.540 So, where is the current score being set? 477 00:27:35.540 --> 00:27:37.837 Let's move on to the Enemy 478 00:27:37.837 --> 00:27:41.137 In Enemy.cs, in the OnCollisionEnter 479 00:27:41.137 --> 00:27:43.540 we were simply displaying 480 00:27:43.540 --> 00:27:45.827 the current score to the console 481 00:27:45.827 --> 00:27:48.377 This part here 482 00:27:48.377 --> 00:27:52.114 Let's change it to display the current score in the UI instead 483 00:27:52.114 --> 00:27:54.664 The curScoreText 484 00:27:54.664 --> 00:27:58.183 remember that we just added is in the sm 485 00:27:58.183 --> 00:28:02.283 Let's change the current score value 486 00:28:02.283 --> 00:28:04.213 in this TextMeshPro 487 00:28:04.213 --> 00:28:06.223 So, how do I access the current score value? 488 00:28:06.223 --> 00:28:08.322 there is something called dot text 489 00:28:08.322 --> 00:28:10.203 Here, text starts with a lowercase letter 490 00:28:10.203 --> 00:28:13.269 So, with the current score set like this 491 00:28:15.853 --> 00:28:18.095 what is the value? 492 00:28:18.095 --> 00:28:23.075 If you set it as sm.CurrentScore 493 00:28:23.075 --> 00:28:29.035 it will apply this value to the UI 494 00:28:29.035 --> 00:28:31.540 Let's save it now 495 00:28:31.540 --> 00:28:34.372 Back to Unity 496 00:28:34.372 --> 00:28:36.322 go to ScoreManager 497 00:28:36.322 --> 00:28:38.422 and select GameObject 498 00:28:38.422 --> 00:28:40.540 We would add in the Cur Score Text 499 00:28:40.540 --> 00:28:44.748 To maintain TextMeshPro 500 00:28:44.748 --> 00:28:47.806 if you drag and drop currentScore here 501 00:28:47.806 --> 00:28:51.312 it will be added like this 502 00:28:51.312 --> 00:28:54.540 Save it now, and play again 503 00:28:54.540 --> 00:28:56.382 So, current score 504 00:29:01.000 --> 00:29:11.563 we can see it changing for each enemy destroyed 505 00:29:11.563 --> 00:29:14.613 So, right now, since the current score 506 00:29:14.613 --> 00:29:17.680 isn't displayed at the start, it's a bit lacking 507 00:29:17.680 --> 00:29:21.280 Let's add a 0 or some number after 508 00:29:21.280 --> 00:29:24.051 he current score here to display it 509 00:29:24.051 --> 00:29:27.714 Starting from 0 points, and when you play again 510 00:29:37.840 --> 00:29:41.936 you should be able to confirm that the score is displayed correctly 511 00:29:42.346 --> 00:29:46.127 Saving and Loading the High Score 512 00:29:46.617 --> 00:29:51.567 So, this time, let's display the high score 513 00:29:51.567 --> 00:29:52.917 and after saving it 514 00:29:52.917 --> 00:29:56.400 load it back on 515 00:29:56.400 --> 00:30:00.050 Just like we displayed the current score here 516 00:30:00.050 --> 00:30:01.750 we'll display the high score 517 00:30:01.750 --> 00:30:05.720 in the same way right here 518 00:30:05.720 --> 00:30:09.199 To display the high score here, we first need to have the high score itself 519 00:30:09.199 --> 00:30:13.299 Let's first declare a property in the ScoreManager 520 00:30:13.299 --> 00:30:16.320 to display the high score 521 00:30:16.320 --> 00:30:19.320 So, let's move over to Visual Studio 522 00:30:19.320 --> 00:30:23.279 find our way to ScoreManager 523 00:30:23.279 --> 00:30:26.329 To display the high score here 524 00:30:26.329 --> 00:30:29.229 I shall copy this and place it like this? 525 00:30:29.229 --> 00:30:33.120 This will be bestScore instead of currentScore 526 00:30:33.120 --> 00:30:35.420 add a new function like this 527 00:30:35.420 --> 00:30:39.070 Not current, but best 528 00:30:39.070 --> 00:30:41.973 Like so 529 00:30:41.973 --> 00:30:43.423 We need an UI as well 530 00:30:43.423 --> 00:30:46.830 So, let's copy both 531 00:30:49.279 --> 00:30:50.681 and place them here 532 00:30:50.681 --> 00:30:56.481 This one shall be the Best Score UI, right? 533 00:30:56.481 --> 00:30:59.281 And then, change this curScore 534 00:30:59.281 --> 00:31:03.639 into bestScoreText 535 00:31:03.639 --> 00:31:10.189 Now, both the high score and the current score 536 00:31:10.189 --> 00:31:12.080 are set up and displayed 537 00:31:12.080 --> 00:31:14.680 To make it look better 538 00:31:14.680 --> 00:31:16.160 let's move it up and place it like this 539 00:31:16.160 --> 00:31:19.860 currentScore, bestScore 540 00:31:19.860 --> 00:31:21.960 To display both scores 541 00:31:21.960 --> 00:31:24.160 we've set up bestScore to remember the score 542 00:31:24.160 --> 00:31:27.310 the UI to show the high score 543 00:31:27.310 --> 00:31:28.475 and so on 544 00:31:31.479 --> 00:31:36.479 So, when should the high score be updated? 545 00:31:36.479 --> 00:31:39.679 The currentScore should increase 546 00:31:39.679 --> 00:31:43.160 when the Enemy is caught, right? 547 00:31:43.160 --> 00:31:45.710 Then how about the bestScore? 548 00:31:45.710 --> 00:31:49.159 The high score should be updated like this 549 00:31:52.943 --> 00:31:59.695 The condition for bestScore updates? 550 00:31:59.695 --> 00:32:01.745 What should the first one be? 551 00:32:01.745 --> 00:32:07.074 If the current score exceeds the high score 552 00:32:10.804 --> 00:32:15.504 If the current score is equal to or less, we don't need it to be updated 553 00:32:15.504 --> 00:32:18.781 should be updated only 554 00:32:18.781 --> 00:32:23.000 when current score exceeds the best score 555 00:32:23.000 --> 00:32:25.879 what are we going to do then? 556 00:32:28.360 --> 00:32:30.237 Update the best score 557 00:32:32.440 --> 00:32:41.320 and then? simply display the best score in the UI 558 00:32:41.320 --> 00:32:44.020 So, the high score should be updated 559 00:32:44.020 --> 00:32:47.639 when the current score exceeds the high score 560 00:32:47.639 --> 00:32:50.339 At that point, the high score should be updated 561 00:32:50.339 --> 00:32:53.447 and displayed on the UI, this is the way how it should work 562 00:32:53.447 --> 00:32:56.759 Where should this logic go? 563 00:32:56.759 --> 00:33:01.709 It should compare the current score with the high score 564 00:33:01.709 --> 00:33:04.759 when the enemy increases the current score 565 00:33:04.759 --> 00:33:07.659 I will add this logic below 566 00:33:07.659 --> 00:33:10.520 where the current score is displayed 567 00:33:10.520 --> 00:33:13.283 Press Ctrl and V to paste it 568 00:33:16.327 --> 00:33:19.927 Then, how can we tell when current score 569 00:33:19.927 --> 00:33:21.460 exceeds the best score at all? 570 00:33:21.460 --> 00:33:24.860 use function if, what's the current score? 571 00:33:24.860 --> 00:33:28.853 sm's currentScores 572 00:33:28.853 --> 00:33:31.703 How bigger is it than which? Than the best score? 573 00:33:31.703 --> 00:33:35.079 If it is greater than sm's bestScore 574 00:33:35.079 --> 00:33:39.640 this is the simple translation What would you like to do at this point? 575 00:33:39.640 --> 00:33:41.989 These are what we want 576 00:33:43.480 --> 00:33:47.280 Let's update the high score, but what value should we use to update it? 577 00:33:47.280 --> 00:33:48.839 With the current right? 578 00:33:48.839 --> 00:33:50.739 So, sm's bestScore should be updated 579 00:33:50.739 --> 00:33:54.418 with sm's currentScore like this 580 00:33:59.341 --> 00:34:02.291 Next, just like we displayed the current score 581 00:34:02.291 --> 00:34:06.519 we will also display the bestScore in the same way 582 00:34:06.519 --> 00:34:10.619 assign the high score to bestScoreText 583 00:34:10.619 --> 00:34:14.839 instead of the current score, like this 584 00:34:14.839 --> 00:34:18.563 Then, let's assign currentScore and bestScore accordingly 585 00:34:22.559 --> 00:34:26.559 So, update bestScore vlaue 586 00:34:26.559 --> 00:34:28.909 Next, let's process this value so that 587 00:34:28.909 --> 00:34:31.174 We will handle this value accordingly 588 00:34:33.880 --> 00:34:36.187 Save it and back to Unity 589 00:34:41.067 --> 00:34:44.167 Now what do we need to 590 00:34:44.167 --> 00:34:47.097 We need an UI elemnet in order 591 00:34:47.097 --> 00:34:48.997 Let me select currentScore 592 00:34:48.997 --> 00:34:52.526 and copy it by using Ctrl and D 593 00:34:52.526 --> 00:34:59.394 Let's rename it bestScore 594 00:34:59.394 --> 00:35:02.144 like this, bestScore 595 00:35:02.144 --> 00:35:06.925 set it to display the bestScore instead of the current score 596 00:35:06.935 --> 00:35:10.485 the position overlaps, so I will grab this and 597 00:35:10.485 --> 00:35:12.277 place it slightly in the lower position 598 00:35:12.277 --> 00:35:14.377 Then you can see that a current score and the best score 599 00:35:14.377 --> 00:35:16.929 are placed nicely like this 600 00:35:20.440 --> 00:35:25.266 Now, let's drag and drop bestScore 601 00:35:25.266 --> 00:35:28.661 inside the ScoreManager's bestScoreText 602 00:35:30.760 --> 00:35:34.153 Now, let's save the changes and run the game by clicking Play 603 00:35:50.839 --> 00:35:53.739 Now, you can see that the current score and the high score 604 00:35:53.739 --> 00:35:57.000 are being updated correctly 605 00:35:57.000 --> 00:36:00.800 Then, ultimately, what we want to do is 606 00:36:00.800 --> 00:36:05.050 not only just displaying current score 607 00:36:05.050 --> 00:36:07.160 but also save and load the program back on 608 00:36:07.160 --> 00:36:10.839 So now, let's take a look at the topic of saving 609 00:36:10.839 --> 00:36:13.439 In Unity, in order to save 610 00:36:13.439 --> 00:36:15.589 there's a library that they provide 611 00:36:15.589 --> 00:36:17.799 You can save in various ways depending on your purpose 612 00:36:17.799 --> 00:36:20.259 We can save it in different file formats 613 00:36:20.259 --> 00:36:22.909 json or other binary files 614 00:36:22.909 --> 00:36:25.759 In addition, you can save text files in various formats 615 00:36:25.759 --> 00:36:28.119 such as XML and others 616 00:36:28.119 --> 00:36:32.019 But here, let's use the PlayerPrefs object 617 00:36:32.019 --> 00:36:36.519 which helps easily save data in Unity 618 00:36:36.519 --> 00:36:38.686 There is no need to save 619 00:36:38.686 --> 00:36:40.519 the current score here 620 00:36:40.519 --> 00:36:45.720 I will make it so that only your highest score is recorded, like a ranking 621 00:36:45.720 --> 00:36:49.790 So, let's add the functionality to save the highest score 622 00:36:49.790 --> 00:36:57.959 below the section where we record the highest score 623 00:36:57.959 --> 00:37:00.209 So, what we're doing here 624 00:37:00.209 --> 00:37:03.218 is using something called PlayerPrefs 625 00:37:06.416 --> 00:37:09.566 if put a dot after PlayerPrefs 626 00:37:09.566 --> 00:37:12.966 Setint, which is integer value 627 00:37:12.966 --> 00:37:15.760 Since the score is an integer, it is currently represented as an int value 628 00:37:15.760 --> 00:37:17.310 So that's that 629 00:37:17.310 --> 00:37:20.720 This one is supposed to be a key, Value 630 00:37:20.720 --> 00:37:23.605 Here, you just need to put the key 631 00:37:23.605 --> 00:37:25.200 that will be used to save or load the data 632 00:37:25.200 --> 00:37:27.650 So here, we will put the key value 633 00:37:27.650 --> 00:37:30.040 Best Score in a string written in the text 634 00:37:30.040 --> 00:37:31.690 Next, we will assign the corresponding value 635 00:37:31.690 --> 00:37:36.479 which is sm's bestScore, to it 636 00:37:36.479 --> 00:37:40.663 Then, the value has been saved 637 00:37:40.663 --> 00:37:43.840 Then, this value needs to be loaded from somewhere 638 00:37:43.840 --> 00:37:47.280 We need to load it and display it on the UI 639 00:37:47.280 --> 00:37:50.380 To display this value at the beginning 640 00:37:50.380 --> 00:37:54.380 we will load the bestScore value 641 00:37:54.380 --> 00:37:56.280 in the Start part of the ScoreManager 642 00:37:56.280 --> 00:38:00.274 in the beginning, bring bestScore 643 00:38:00.274 --> 00:38:03.679 and show it on the UI 644 00:38:03.679 --> 00:38:06.679 So, what we want to do here is 645 00:38:06.679 --> 00:38:13.880 load the highest score, assign it to the bestScore variable 646 00:38:13.880 --> 00:38:18.799 Let's say I want to display it on the screen like this 647 00:38:18.799 --> 00:38:21.119 So what do we do first? 648 00:38:21.119 --> 00:38:24.266 We will need to call the bestScore 649 00:38:26.880 --> 00:38:36.679 and then display it on the UI as well 650 00:38:36.679 --> 00:38:41.029 to load the highest score 651 00:38:41.029 --> 00:38:44.679 We need to first retrieve it and store it in the bestScore variable 652 00:38:44.679 --> 00:38:45.679 because we are about to declare 653 00:38:45.679 --> 00:38:49.079 Starting with bestScore, Playerprefs 654 00:38:49.079 --> 00:38:51.279 It was set int back then 655 00:38:51.279 --> 00:38:54.640 This time, there should be GetInt 656 00:38:54.640 --> 00:38:57.690 So, here you will use Best Score with a space in between, like this, Best Score 657 00:38:57.690 --> 00:38:59.559 For key value, the name should be the same 658 00:38:59.559 --> 00:39:02.509 If you have nothing to load after this 659 00:39:02.509 --> 00:39:05.039 nothing at all, just put 0 for default value 660 00:39:05.039 --> 00:39:08.285 Like this, add in the default setting 661 00:39:08.285 --> 00:39:10.835 If you have nothing saved 662 00:39:10.835 --> 00:39:12.559 the Best Score will be 0 663 00:39:12.559 --> 00:39:18.039 If it exists, we will load the saved value and assign it 664 00:39:18.039 --> 00:39:21.159 Shall we display this value in the UI? 665 00:39:21.159 --> 00:39:28.512 You can then assign the bestScore 666 00:39:31.798 --> 00:39:34.743 to the bestScoreText like this 667 00:39:37.159 --> 00:39:39.509 Then save this part 668 00:39:39.509 --> 00:39:41.840 Let's check if it works well 669 00:39:41.840 --> 00:39:47.320 Go to Unity to play 670 00:39:47.320 --> 00:39:50.181 Current best score, we already have 17 points 671 00:40:01.760 --> 00:40:03.610 I played till 20 points 672 00:40:03.610 --> 00:40:06.310 17 points match was what I tested, which is the best score 673 00:40:06.310 --> 00:40:08.375 Let's run it to check again 674 00:40:14.039 --> 00:40:17.439 Now we see that the best score has been saved with 20 points 675 00:40:17.439 --> 00:40:20.440 We could see that loading works 676 00:40:20.440 --> 00:40:25.159 But now that I see it, the value is fine 677 00:40:25.159 --> 00:40:28.359 but there's a bit of a burden in the Enemy section 678 00:40:28.359 --> 00:40:32.759 In reality, it's directly manipulating the value of a specific property 679 00:40:32.759 --> 00:40:35.320 and others are modifying that value 680 00:40:35.320 --> 00:40:37.620 These kinds of things are actually not ideal 681 00:40:37.620 --> 00:40:39.159 in object oriented design 682 00:40:39.159 --> 00:40:44.840 So instead of directly manipulating these values 683 00:40:44.840 --> 00:40:49.432 it's more efficient to handle them through encapsulation 684 00:40:49.432 --> 00:40:52.200 by creating Get and Set functions to manage the process 685 00:40:52.200 --> 00:40:55.850 So, instead of directly accessing bestScore or setScore 686 00:40:55.850 --> 00:40:59.520 and manipulating currentScore directly 687 00:40:59.520 --> 00:41:02.039 we will access them through functions 688 00:41:02.039 --> 00:41:05.839 So, you will create Get and Set functions 689 00:41:05.839 --> 00:41:07.960 for currentScore here 690 00:41:07.960 --> 00:41:10.960 First, let's create the Set function 691 00:41:10.960 --> 00:41:13.919 I will name it public void SetScore 692 00:41:13.919 --> 00:41:18.840 and pass int value like this 693 00:41:18.840 --> 00:41:20.960 Next, I will create it 694 00:41:20.960 --> 00:41:24.710 This time, I will create a function called GetScore 695 00:41:24.710 --> 00:41:27.719 a function for returning the currentScore 696 00:41:27.719 --> 00:41:31.119 It will simply return the currentScore 697 00:41:31.119 --> 00:41:32.876 just like this 698 00:41:36.000 --> 00:41:39.950 If this is done what is the Enemy 699 00:41:39.950 --> 00:41:41.840 doing directly now? 700 00:41:41.840 --> 00:41:45.740 By bringing in the ScoreManager, increasing the value 701 00:41:45.740 --> 00:41:48.000 displaying it on the UI, and updating the highest score 702 00:41:48.000 --> 00:41:50.700 all of these tasks don't really need to be done by the Enemy 703 00:41:50.700 --> 00:41:53.400 The ScoreManager can handle all of these, instead 704 00:41:53.400 --> 00:41:56.520 So, there is this part where the current score is being increased 705 00:41:56.520 --> 00:41:59.456 Let's change this part to use Set instead 706 00:42:02.000 --> 00:42:04.721 So this part right here 707 00:42:04.721 --> 00:42:07.521 Let's cut out everything from displaying 708 00:42:07.521 --> 00:42:10.799 the current score up to the point 709 00:42:10.799 --> 00:42:13.943 where the current score is increased 710 00:42:13.943 --> 00:42:15.239 including steps 3 through the last part 711 00:42:15.239 --> 00:42:18.799 You will press Ctrl and X to cut it out 712 00:42:18.799 --> 00:42:21.679 So, where should you place it? 713 00:42:21.679 --> 00:42:24.559 You will place it in SetScore 714 00:42:24.559 --> 00:42:29.559 You will place it in SetScore within the ScoreManager 715 00:42:29.559 --> 00:42:32.509 After that, you will remove 716 00:42:32.509 --> 00:42:35.119 all the references related to sm 717 00:42:35.119 --> 00:42:38.019 Why? It's the ScoreManager, so it's itself 718 00:42:38.019 --> 00:42:41.039 Therefore, this one doesn't require sm 719 00:42:41.039 --> 00:42:44.639 A tip here is to select it by dragging 720 00:42:44.639 --> 00:42:46.119 then press Ctrl and F 721 00:42:46.119 --> 00:42:49.880 and the search function will appear 722 00:42:49.880 --> 00:42:52.162 If you open the dropdown here 723 00:42:52.162 --> 00:42:53.919 you will see the option to replace as well 724 00:42:53.919 --> 00:42:56.019 If you click on Next Find on the right 725 00:42:56.019 --> 00:42:59.520 which is Alt + R, and what happens? 726 00:42:59.520 --> 00:43:01.320 with sm 727 00:43:01.320 --> 00:43:06.239 we can change it to blank without any text 728 00:43:06.239 --> 00:43:13.359 Once you do this, you'll have successfully removed all instances of sm at once 729 00:43:13.359 --> 00:43:16.280 Exactly! You’ve moved everything into SetScore 730 00:43:16.280 --> 00:43:20.599 So, what should be done in the Enemy section? 731 00:43:20.599 --> 00:43:24.099 In the Enemy section, using the Get and Set functions 732 00:43:24.099 --> 00:43:28.119 this is how it works 733 00:43:28.119 --> 00:43:35.169 You're saying that we should use the Get or Set functions 734 00:43:35.169 --> 00:43:37.280 of the ScoreManager to set the value 735 00:43:37.280 --> 00:43:39.030 We can just increase the value by one 736 00:43:39.030 --> 00:43:42.760 So, to increase the value with SetScore 737 00:43:42.760 --> 00:43:45.445 in ScoreManager, you first need to have the value 738 00:43:45.445 --> 00:43:49.320 So, by getting the value from GetScore 739 00:43:49.320 --> 00:43:50.970 you can increment it by one and then pass it to SetScore 740 00:43:50.970 --> 00:43:54.840 which will set the new value in the current score 741 00:43:54.840 --> 00:43:57.520 So we should handle it this way and how does it differ? 742 00:43:57.520 --> 00:43:59.670 Enemy became a little lighter 743 00:43:59.670 --> 00:44:01.318 We will save it as is now 744 00:44:03.440 --> 00:44:07.200 Let's save it and then move to Unity 745 00:44:07.200 --> 00:44:09.223 and click play button 746 00:44:29.259 --> 00:44:31.809 Current score updates normally 747 00:44:31.809 --> 00:44:33.880 We can see the best score updates fine as well 748 00:44:33.880 --> 00:44:36.894 Let's save it and turn it off and on again to see if it actually works for sure 749 00:44:42.200 --> 00:44:47.960 the best score is being loaded correctly 750 00:44:47.960 --> 00:44:51.310 So, up to this point, we've covered 751 00:44:51.310 --> 00:44:54.119 the entire content of Alpha Type Part 1 and Part 2 752 00:44:54.119 --> 00:44:56.619 We have completed the Alpha Type content 753 00:44:56.619 --> 00:44:59.000 including saving and loading the values 754 00:44:59.000 --> 00:45:03.679 Next time, we will look into the Beta Type content 755 00:45:03.679 --> 00:45:07.000 Let's summarize the content we learned in this chapter 756 00:45:07.000 --> 00:45:09.900 First, we created the ScoreManager 757 00:45:09.900 --> 00:45:13.799 to add the score and display it on the UI 758 00:45:13.799 --> 00:45:16.699 Next, we learned how to use the PlayerPrefs class 759 00:45:16.699 --> 00:45:21.239 to save and load the highest score 760 00:45:21.239 --> 00:45:24.509 At this point, we learned how to use encapsulation in object oriented programming 761 00:45:24.509 --> 00:45:30.119 by accessing properties through Get and Set functions 762 00:45:30.119 --> 00:45:31.964 Nice work everyone! 763 00:45:32.506 --> 00:45:33.298 Add score Create score management object Click the [+] button in the hierarchy to create an Empty object and rename it to Score Manager 764 00:45:33.298 --> 00:45:34.129 Create a C# script in the [Assets - Scripts] path of the project window and rename it to Score Manager 765 00:45:34.129 --> 00:45:34.980 Add the ScoreManager script to the ScoreManager game object 766 00:45:34.980 --> 00:45:35.680 Displaying Current Score In Enemy.cs, with the logic in the OnCollisionEnter event function, when the enemy collides with another object, adds score 767 00:45:35.680 --> 00:45:36.387 Flow for Implementing Score Increase Find the ScoreManager object in the scene Get the ScoreManager component Increase and display the current score 768 00:45:36.387 --> 00:45:36.987 Create Score UI Create the current score UI and set the anchor Click the [+] button in the hierarchy window and select [UI - Text - TextMeshPro] 769 00:45:36.987 --> 00:45:37.537 When the TMP Import window appears, click the Import TMP Essentials button, and then rename the object to CurrentScore 770 00:45:37.537 --> 00:45:38.087 Select the Text (TMP) object, click the Anchor Preset in the Rect Transform of the Inspector window, and choose the top left alignment Text Component 771 00:45:38.087 --> 00:45:38.737 After modifying the Text component value of the CurrentScore object, enter 'Current Score:' in the Text Input field In Explorer, go to the C:WindowsFonts folder, 772 00:45:38.737 --> 00:45:39.237 search for Nanum Gothic font, select it, and add it to the TextMesh Pro - Fonts folder After opening [Window - TextMeshPro - Font Asset Creator], 773 00:45:39.237 --> 00:45:39.737 add Nanum Gothic font by dragging and dropping it to Source Font File and set Atlas Resolution to 4096 Click the [Generate Font Atlas] button, 774 00:45:39.737 --> 00:45:40.584 save it after completion, and when the file is created, select NANUGOTHIC.SDF and move it to the Inspector window Go to the Generation Settings category 775 00:45:40.584 --> 00:45:41.084 Change the Atlas Population Mode to Dynamic set the Sampling Point Size to 60, click the Apply button Afterward, check for correct text display 776 00:45:41.084 --> 00:45:42.209 Create Score UI Writing Script Register a member variable of type TextMeshProUGUI called curScoreText in ScoreManager.cs 777 00:45:42.209 --> 00:45:43.276 Add the code to display the current score UI in the OnCollisionEnter function of Enemy.cs 778 00:45:43.276 --> 00:45:44.429 Assign CurrentScore to CurScoreText in the ScoreManager game object in the hierarchy 779 00:45:44.429 --> 00:45:45.429 Save and Load best Score Display best Score In ScoreManager.cs, declare a UI for displaying the best score and a variable to store the best score 780 00:45:45.429 --> 00:45:46.429 implementing flow for the best score current score exceeds the best score updating the best score displaying best score on UI 781 00:45:46.429 --> 00:45:47.429 Implementing best score update requirements Select CurrentScore, duplicate it, rename it to BestScore, and then change the Text Input to best scores 782 00:45:47.429 --> 00:45:48.429 Place the BestScore object below the CurrentScore in the hierarchy Select the ScoreManager game object, assign BestScore to the Best Score Text field 783 00:45:48.429 --> 00:45:49.129 Save and Load best Score Using PlayerPrefs for saving PlayerPrefs.GetInt will return the saved value when you provide the key 784 00:45:49.129 --> 00:45:49.779 Without saved value, can specify the default value The PlayerPrefs stores objects in a key and value format Load and display in the start function 785 00:45:49.779 --> 00:45:50.429 Encapsulation Since the score increment logic is in the Enemy properties, we will handle it by creating Get and Set functions through encapsulation 786 00:45:50.429 --> 00:45:51.079 Create SetScore and GetScore functions in ScoreManager.cs Move the current score from Enemy.cs to the SetScore function in ScoreManager.cs 787 00:45:51.079 --> 00:45:51.779 Since the content from the Enemy class has been moved to ScoreManager, remove the code where it was previously referenced using the sm variable 788 00:45:51.779 --> 00:45:52.459 Modify Enemy.cs to call the Get and Set functions