WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:03.493 [MUSIC PLAYING] 00:00:16.410 --> 00:00:17.410 COLTON OGDEN: All right. 00:00:17.410 --> 00:00:18.850 Welcome back to GD50. 00:00:18.850 --> 00:00:19.930 This is Lecture 8. 00:00:19.930 --> 00:00:22.900 Today we're going to be diving into the world of Unity 00:00:22.900 --> 00:00:25.030 for the first time, which I'm excited about. 00:00:25.030 --> 00:00:28.450 Going to be a whirlwind tour, but I'll try to cover as much as possible. 00:00:28.450 --> 00:00:34.690 Transitioning away from 2D and away from Lua and LOVE 2D into 3D and C# 00:00:34.690 --> 00:00:35.700 in the context of Unity. 00:00:35.700 --> 00:00:37.700 Today we'll be talking about Helicopter Game 3D. 00:00:37.700 --> 00:00:42.220 So Helicopter Game is a 2D game that was really famous in the 2000s. 00:00:42.220 --> 00:00:44.570 It was a web game. 00:00:44.570 --> 00:00:46.542 I was sponsored on a bunch of websites. 00:00:46.542 --> 00:00:48.250 Addictinggames.com still has it on there, 00:00:48.250 --> 00:00:49.625 and a few other websites have it. 00:00:49.625 --> 00:00:50.697 It was a flash game. 00:00:50.697 --> 00:00:52.030 But I remember playing it a lot. 00:00:52.030 --> 00:00:54.940 It was the old precursor to Flappy Bird, which 00:00:54.940 --> 00:00:56.470 was mentioned on the Wikipedia page. 00:00:56.470 --> 00:00:58.040 There's a reference to it there. 00:00:58.040 --> 00:00:59.470 And this is what the game play looked like. 00:00:59.470 --> 00:01:01.928 It was very similar to Flappy Bird-- a little bit different 00:01:01.928 --> 00:01:04.750 in that, instead of trying to avoid pipes, you're in a cave, 00:01:04.750 --> 00:01:08.080 and you're trying to avoid the ceiling and the ground of the level. 00:01:08.080 --> 00:01:10.180 And there were these little obstacles that would spawn in the middle, 00:01:10.180 --> 00:01:10.560 as well. 00:01:10.560 --> 00:01:11.851 So you'd have to navigate that. 00:01:11.851 --> 00:01:15.710 But it was the same exact mechanic-- the sort of like, click to go up. 00:01:15.710 --> 00:01:17.710 And then, when you didn't click, your helicopter 00:01:17.710 --> 00:01:20.890 would just sink down via gravity. 00:01:20.890 --> 00:01:25.240 Today we'll be talking about a bunch of brand new topics, things like Unity, 00:01:25.240 --> 00:01:28.150 first and foremost-- the ecosystem with which we'll be doing 00:01:28.150 --> 00:01:29.980 a lot of the things we'll be doing. 00:01:29.980 --> 00:01:32.410 C# is the primary language we'll be using. 00:01:32.410 --> 00:01:36.100 So we're going to take a step away from dynamic languages and move towards 00:01:36.100 --> 00:01:38.200 statically-typed languages-- 00:01:38.200 --> 00:01:40.899 languages like C#, and Java, and the like. 00:01:40.899 --> 00:01:42.940 Blender is a program we'll look at briefly today, 00:01:42.940 --> 00:01:45.220 just because, in the context of 3D development, 00:01:45.220 --> 00:01:48.053 you're going to want to have a tool that will let you create models. 00:01:48.053 --> 00:01:51.027 And so the 3D software that I like to advocate for the most, especially 00:01:51.027 --> 00:01:53.860 for folks that are just starting out, is Blender, because it's free, 00:01:53.860 --> 00:01:56.290 and open source, and it has much the same feature 00:01:56.290 --> 00:02:00.070 set as any commercial software, like 3D Studio Max, and Cinema 4D, 00:02:00.070 --> 00:02:01.329 and the like. 00:02:01.329 --> 00:02:04.120 We'll talk about what components are-- entities and components, how 00:02:04.120 --> 00:02:08.470 they relate in this model that Unity has adopted for all of its programming. 00:02:08.470 --> 00:02:11.740 Components are little pieces of behavior that you can then 00:02:11.740 --> 00:02:16.330 combine to form a whole, that will then drive the behavior of whatever object 00:02:16.330 --> 00:02:18.250 in your scene you want, rather than having 00:02:18.250 --> 00:02:23.920 to customize its behavior via a long chain of inheritance and instantiation. 00:02:23.920 --> 00:02:26.660 Colliders and triggers are important in 3D-- 00:02:26.660 --> 00:02:27.391 and 2D. 00:02:27.391 --> 00:02:29.140 But today we'll be talking about colliders 00:02:29.140 --> 00:02:30.848 and triggers-- things like the helicopter 00:02:30.848 --> 00:02:34.930 colliding with coins, and buildings, and other planes that are flying. 00:02:34.930 --> 00:02:37.365 Each of those has to have a collider. 00:02:37.365 --> 00:02:40.240 And certain things have to be considered triggers in order to trigger 00:02:40.240 --> 00:02:43.060 certain behavior with other entities. 00:02:43.060 --> 00:02:46.090 Prefabs and spawning-- prefabs is a huge concept in Unity. 00:02:46.090 --> 00:02:48.910 So prefabs are basically prefabricated objects 00:02:48.910 --> 00:02:52.570 that you can customize as you want to-- lay them out in the editor, 00:02:52.570 --> 00:02:55.310 rather than having to necessarily code all the details. 00:02:55.310 --> 00:02:58.330 And then you can instantiate them in the actual scene, 00:02:58.330 --> 00:03:02.330 via code programmatically, in a way that fits the model you're striving for. 00:03:02.330 --> 00:03:05.080 Texture scrolling is something we'll look at briefly, because it's 00:03:05.080 --> 00:03:09.899 the way that we accomplish the infinite scrolling aesthetic or behavior. 00:03:09.899 --> 00:03:12.190 And we'll look at how we can do that in a different way 00:03:12.190 --> 00:03:14.410 than we've done before, using u-v coordinates, 00:03:14.410 --> 00:03:17.530 and specifically looking at materials, and modifying 00:03:17.530 --> 00:03:20.050 certain attributes of those materials. 00:03:20.050 --> 00:03:23.350 And lastly, to tie everything together as we've done before, 00:03:23.350 --> 00:03:26.370 we'll look at audio-- things like audio listeners and audio sources-- 00:03:26.370 --> 00:03:28.203 what the difference is between them, and how 00:03:28.203 --> 00:03:30.070 to add them easily to our game project. 00:03:30.070 --> 00:03:32.110 But first, a demo-- if there would be anybody 00:03:32.110 --> 00:03:35.230 willing to come up and take a look and play the 3D helicopter game that I 00:03:35.230 --> 00:03:37.656 put together, that would be awesome. 00:03:37.656 --> 00:03:40.332 Anybody? 00:03:40.332 --> 00:03:41.230 Steven? 00:03:41.230 --> 00:03:42.840 Awesome. 00:03:42.840 --> 00:03:44.070 Thank you so much. 00:03:44.070 --> 00:03:46.580 Let me go ahead and actually get it-- 00:03:46.580 --> 00:03:48.990 so I've pre-built it. 00:03:48.990 --> 00:03:52.800 So let me go ahead and. 00:03:52.800 --> 00:03:55.710 So the nice thing about Unity is, it exports to multiple platforms. 00:03:55.710 --> 00:03:57.690 And right out of the gate, you can get just a-- 00:03:57.690 --> 00:03:59.400 I didn't put an icon for it. 00:03:59.400 --> 00:04:02.970 But you can create just a native application very easily. 00:04:02.970 --> 00:04:05.190 And so whenever you're ready, go ahead and hit Play, 00:04:05.190 --> 00:04:08.462 and Up and Down will move your helicopter. 00:04:12.080 --> 00:04:14.300 So this is the 3D helicopter game. 00:04:14.300 --> 00:04:18.405 And I don't think we have sound live, but there should be audio. 00:04:18.405 --> 00:04:20.816 Oh, I might have actually-- here we go. 00:04:20.816 --> 00:04:21.841 [MUSIC PLAYING] 00:04:21.841 --> 00:04:22.340 There we go. 00:04:22.340 --> 00:04:23.567 That was my bad. 00:04:23.567 --> 00:04:24.650 So there is music playing. 00:04:24.650 --> 00:04:25.566 There's sound effects. 00:04:25.566 --> 00:04:27.800 So notice that we have a 3D model. 00:04:27.800 --> 00:04:30.470 This is what's called a 2.5D game. 00:04:30.470 --> 00:04:33.170 So even though everything is in 3D-- 00:04:33.170 --> 00:04:34.940 the models and so forth-- 00:04:34.940 --> 00:04:38.390 the actual axes upon which we're bound are just two. 00:04:38.390 --> 00:04:40.949 We're just bound to, I believe, the x and the y. 00:04:40.949 --> 00:04:41.990 Could be the z and the x. 00:04:41.990 --> 00:04:42.980 I don't recall offhand. 00:04:42.980 --> 00:04:45.800 But we're bound to just simply two axes of movement. 00:04:45.800 --> 00:04:48.290 But all the models, as we can see by the camera, 00:04:48.290 --> 00:04:50.586 are in 3D, including our helicopter. 00:04:50.586 --> 00:04:51.960 So we have a few things going on. 00:04:51.960 --> 00:04:54.140 We have skyscrapers that are scrolling by. 00:04:54.140 --> 00:04:58.910 We have coins that are also going by at the same speed as the skyscrapers. 00:04:58.910 --> 00:05:02.420 We have a background that is infinitely scrolling. 00:05:02.420 --> 00:05:07.250 We have, of course, our helicopter which has a rotating set of blades. 00:05:07.250 --> 00:05:10.865 And when we collide with a coin, notice that we get a little-- 00:05:10.865 --> 00:05:13.490 it might be hard to see in house, but we have a little particle 00:05:13.490 --> 00:05:15.592 effect that plays. 00:05:15.592 --> 00:05:17.300 There's airplanes that are flying up top, 00:05:17.300 --> 00:05:20.090 so we're instantiating those, as well, to fly past us 00:05:20.090 --> 00:05:22.800 to provide another layer of obstacle. 00:05:22.800 --> 00:05:26.930 And if we collide with an airplane, notice that we get de-spawned, 00:05:26.930 --> 00:05:29.785 and then we trigger another particle effect to imitate an explosion. 00:05:29.785 --> 00:05:32.160 And then, notice we also have a couple of other elements. 00:05:32.160 --> 00:05:32.870 We have a GUI. 00:05:32.870 --> 00:05:36.050 We have two GUI elements-- a coin total at the top right, 00:05:36.050 --> 00:05:38.660 and then a game over here in the middle of the screen, which 00:05:38.660 --> 00:05:41.930 only shows up once we have died. 00:05:41.930 --> 00:05:45.380 And the explosive behavior-- if you want to collide with a building, 00:05:45.380 --> 00:05:46.190 you'll see that. 00:05:46.190 --> 00:05:48.273 It also triggers when you collide with a building. 00:05:48.273 --> 00:05:52.990 So there's two things looking for these explosions-- the airplanes up top, 00:05:52.990 --> 00:05:53.990 and the buildings below. 00:05:53.990 --> 00:05:55.640 Those are our two obstacles. 00:05:55.640 --> 00:05:59.000 But when they collide with the coins, we should increment our coin total, 00:05:59.000 --> 00:06:01.130 and then display a different particle effect. 00:06:01.130 --> 00:06:02.849 And then this goes on ad infinitum. 00:06:02.849 --> 00:06:04.140 You can press Space to restart. 00:06:04.140 --> 00:06:06.950 So we have keyboard input that's based on what 00:06:06.950 --> 00:06:09.090 we press, different things happen. 00:06:09.090 --> 00:06:11.780 And so that's effectively the demo that I've put together today. 00:06:11.780 --> 00:06:12.530 So thanks, Steven. 00:06:12.530 --> 00:06:14.113 I appreciate you coming up to demo it. 00:06:17.670 --> 00:06:19.140 So that's the 3D helicopter game. 00:06:19.140 --> 00:06:24.610 It's got most of the same mechanics as the web version from before-- 00:06:24.610 --> 00:06:29.225 I would say, maybe even more features just to illustrate a few new concepts. 00:06:29.225 --> 00:06:31.350 But that's effectively what we're going with today. 00:06:31.350 --> 00:06:37.590 We're just a pretty simple, Flappy Bird esque differently-themed game, 00:06:37.590 --> 00:06:38.850 based on the same principles. 00:06:38.850 --> 00:06:40.950 Fly forever, avoid obstacles. 00:06:40.950 --> 00:06:43.920 And in this case, even get little collectibles. 00:06:43.920 --> 00:06:46.710 And so notice that there are also effectively two states 00:06:46.710 --> 00:06:50.310 in our game, which are just the playing state, and then the game over state. 00:06:50.310 --> 00:06:52.210 The two are almost effectively the same. 00:06:52.210 --> 00:06:56.130 The only real difference is that one doesn't have the helicopter present, 00:06:56.130 --> 00:07:00.210 and displays a different GUI element in the middle of the screen. 00:07:00.210 --> 00:07:02.880 If you haven't downloaded Unity already, there's two links here. 00:07:02.880 --> 00:07:06.610 So the top link is just the catchall download link. 00:07:06.610 --> 00:07:08.430 And then the second link is the beta link. 00:07:08.430 --> 00:07:10.430 So we're actually using the beta in this course, 00:07:10.430 --> 00:07:12.510 because Unity has started transitioning away 00:07:12.510 --> 00:07:15.450 from a numerical system for their releases, 00:07:15.450 --> 00:07:17.490 and is now going yearly with their releases. 00:07:17.490 --> 00:07:22.090 So the last long-term release candidate was 2017's version. 00:07:22.090 --> 00:07:25.050 But now that we're almost halfway through 2018, 00:07:25.050 --> 00:07:27.330 the newest beta is the 2018 version. 00:07:27.330 --> 00:07:28.829 It has a bunch of new features. 00:07:28.829 --> 00:07:30.120 So go ahead and check that out. 00:07:30.120 --> 00:07:33.270 And everything's been well tested, and runs very well-- 00:07:33.270 --> 00:07:36.060 very smoothly on Windows and Mac-- 00:07:36.060 --> 00:07:37.750 with the new beta. 00:07:37.750 --> 00:07:40.034 So what is Unity? 00:07:40.034 --> 00:07:43.200 The difference between what we've done so far and what we're doing today is, 00:07:43.200 --> 00:07:46.430 now we're actually using a full-fledged game engine-- 00:07:46.430 --> 00:07:47.190 this system. 00:07:47.190 --> 00:07:49.650 It's got a built in editor and all this awesome, cool 00:07:49.650 --> 00:07:52.460 functionality that we really didn't get with Love2D before. 00:07:52.460 --> 00:07:54.540 What we were doing before was using a framework, 00:07:54.540 --> 00:07:56.880 and just implementing everything purely in code. 00:07:56.880 --> 00:08:00.210 And as we'll see today, everything that you want to do that's customizable 00:08:00.210 --> 00:08:01.530 effectively is-- 00:08:01.530 --> 00:08:03.690 or can be-- done via code. 00:08:03.690 --> 00:08:06.810 But there are a lot of more efficient and more user-friendly 00:08:06.810 --> 00:08:09.960 ways to accomplish the same thing, which we'll take a look at. 00:08:09.960 --> 00:08:12.990 So Unity has a tremendous market share right now. 00:08:12.990 --> 00:08:13.560 I forget. 00:08:13.560 --> 00:08:19.670 I think in 2016 it had like 43% of all games released were done in Unity. 00:08:19.670 --> 00:08:21.420 I don't know what the current numbers are. 00:08:21.420 --> 00:08:22.295 I couldn't find them. 00:08:22.295 --> 00:08:25.290 But there are other engines that are also very well used-- 00:08:25.290 --> 00:08:26.345 Unreal being among them. 00:08:26.345 --> 00:08:28.470 And Unreal actually may have more market share now, 00:08:28.470 --> 00:08:30.510 because of games like Fortnite, and because it's 00:08:30.510 --> 00:08:35.720 been improved a lot over the last couple of years, and really marketed well. 00:08:35.720 --> 00:08:38.010 But Godot, CryEngine-- there are a lot of game engines 00:08:38.010 --> 00:08:39.718 that are similar to this that provide you 00:08:39.718 --> 00:08:42.840 this all-encompassing way of dealing with your game scene 00:08:42.840 --> 00:08:44.220 and with all your game data. 00:08:44.220 --> 00:08:48.570 But Unity is a very easy engine to start getting used to, 00:08:48.570 --> 00:08:51.195 and cranking things out, and being productive with, 00:08:51.195 --> 00:08:54.030 without the tremendous learning curve that some 00:08:54.030 --> 00:08:56.220 of the other engines like Unreal might have. 00:08:56.220 --> 00:08:58.930 Unreal does have a more user-friendly way of doing things. 00:08:58.930 --> 00:09:02.760 But if you want to get down into the nitty gritty with Unreal, 00:09:02.760 --> 00:09:05.737 you're coding in semi-arcane C++. 00:09:05.737 --> 00:09:08.820 So for folks who aren't used to it and aren't used to 3D game development, 00:09:08.820 --> 00:09:11.812 it can be kind of a large board to get onto. 00:09:11.812 --> 00:09:13.770 The nice thing about Unity, aside from the fact 00:09:13.770 --> 00:09:16.311 that it's fairly easy to get started with, is that it's free. 00:09:16.311 --> 00:09:19.350 And you can use it completely with all of its features 00:09:19.350 --> 00:09:26.280 until you start making over $100,000 in gross revenue releasing Unity products. 00:09:26.280 --> 00:09:27.900 And then there are other tiers. 00:09:27.900 --> 00:09:30.540 The next tier above that is if you start making $200,000, 00:09:30.540 --> 00:09:33.232 and you get new features with these other tiers. 00:09:33.232 --> 00:09:35.190 But if you want to just start up a new company, 00:09:35.190 --> 00:09:38.179 and use Unity, and take something to market-- 00:09:38.179 --> 00:09:39.220 completely free to do so. 00:09:39.220 --> 00:09:41.850 And once you get over $100,000, that's a good problem to have. 00:09:41.850 --> 00:09:44.850 It's not necessarily too much to ask to start 00:09:44.850 --> 00:09:48.300 paying Unity to use it as a means of getting 00:09:48.300 --> 00:09:49.970 onto the market in the first place. 00:09:49.970 --> 00:09:55.120 And especially in mobile and VR, Unity's sort of like the forefront. 00:09:55.120 --> 00:09:56.910 It's got even higher percentage. 00:09:56.910 --> 00:10:00.330 It's like 60-something or 70% market share on mobile. 00:10:00.330 --> 00:10:05.774 And then VR-- from the beginning, it's marketed itself very strongly 00:10:05.774 --> 00:10:06.690 towards the use of VR. 00:10:06.690 --> 00:10:10.260 And we'll actually use VR in the next lecture. 00:10:10.260 --> 00:10:14.850 And the way in which we will accomplish all of the programmatic aspect 00:10:14.850 --> 00:10:17.160 of this-- getting things actually implemented in code-- 00:10:17.160 --> 00:10:20.400 is via C#, which is very different than what we've used so far, 00:10:20.400 --> 00:10:23.010 which we've used Lua, which is a dynamic scripting language, 00:10:23.010 --> 00:10:25.980 very much like JavaScript. 00:10:25.980 --> 00:10:30.270 So C# is very similar to Java, in which things actually have types. 00:10:30.270 --> 00:10:34.674 And so here's a couple of screenshots of what the Unity editor looks like. 00:10:34.674 --> 00:10:36.840 So the nice thing about the Unity editor, actually-- 00:10:36.840 --> 00:10:38.670 which we can see right off the gate here-- 00:10:38.670 --> 00:10:40.380 is that it's very customizable. 00:10:40.380 --> 00:10:43.050 So on the top, that's the default view. 00:10:43.050 --> 00:10:46.340 You have a bottom panel that shows you all your resources, 00:10:46.340 --> 00:10:49.530 all your assets, things like scripts, and shaders, and models, 00:10:49.530 --> 00:10:50.934 and textures, and sounds. 00:10:50.934 --> 00:10:53.850 You have a nice file browser there on the left-hand side, which allows 00:10:53.850 --> 00:10:55.350 you to easily navigate your project. 00:10:55.350 --> 00:10:58.612 You don't have to go looking through your Windows or Mac computer, using 00:10:58.612 --> 00:11:00.570 your finder, or whatnot, or your File Explorer, 00:11:00.570 --> 00:11:02.278 and actually look through all your files. 00:11:02.278 --> 00:11:05.310 You get a nice view there, so that you stay integrated 00:11:05.310 --> 00:11:08.419 within the Unity ecosystem right there. 00:11:08.419 --> 00:11:11.460 On the right-hand side, you can see all the behavior for whatever objects 00:11:11.460 --> 00:11:12.690 you might have in your scene. 00:11:12.690 --> 00:11:14.310 You get a nice big scene view. 00:11:14.310 --> 00:11:17.500 So rather than having to run your game live, and look 00:11:17.500 --> 00:11:19.250 at the behavior that way, you can actually 00:11:19.250 --> 00:11:22.370 see in advance what your scene looks like, and analyze 00:11:22.370 --> 00:11:25.220 your game objects that way, and their appearances, 00:11:25.220 --> 00:11:27.080 and whatever you want to do with them. 00:11:27.080 --> 00:11:29.000 And lay them out perfectly, rather than have 00:11:29.000 --> 00:11:31.607 to programmatically figure things out. 00:11:31.607 --> 00:11:33.440 And on the left-hand side there, you can see 00:11:33.440 --> 00:11:35.052 a full list of all the game objects. 00:11:35.052 --> 00:11:36.760 And then on the bottom right screen shot, 00:11:36.760 --> 00:11:39.550 you can see that the editor is heavily customizable. 00:11:39.550 --> 00:11:41.300 So you can lay things out however you want 00:11:41.300 --> 00:11:43.310 to to fit your style of development. 00:11:43.310 --> 00:11:47.737 I often like to have a panel on top, which shows me my scene view, 00:11:47.737 --> 00:11:50.570 but then have a panel right below that, that shows me the game view. 00:11:50.570 --> 00:11:54.470 So if I'm actually running a game and seeing it happen live, 00:11:54.470 --> 00:11:58.310 I can also see it in the scene, and rotate around in this god mode 00:11:58.310 --> 00:12:00.380 that you can get in a lot of games. 00:12:00.380 --> 00:12:03.700 And actually analyze and see things that way, 00:12:03.700 --> 00:12:05.800 and analyze their behavior frame by frame, 00:12:05.800 --> 00:12:08.930 even if I want to, in a way that's not possible with however 00:12:08.930 --> 00:12:13.010 I might have coded the camera in the actual game itself. 00:12:13.010 --> 00:12:14.810 So C#. 00:12:14.810 --> 00:12:17.334 So has anybody in here used a static language, 00:12:17.334 --> 00:12:19.250 or is familiar with statically-typed languages 00:12:19.250 --> 00:12:21.360 versus dynamically-typed languages? 00:12:21.360 --> 00:12:23.270 [INAUDIBLE], Steven. 00:12:23.270 --> 00:12:27.610 So what languages have you guys used, just out of curiosity? 00:12:27.610 --> 00:12:28.110 Steven. 00:12:28.110 --> 00:12:29.320 STEVEN: Java, C, C++. 00:12:29.320 --> 00:12:30.445 COLTON OGDEN: Java, C, C++. 00:12:30.445 --> 00:12:31.165 Donny? 00:12:31.165 --> 00:12:31.690 DONNY: [INAUDIBLE] 00:12:31.690 --> 00:12:32.320 COLTON OGDEN: C and C++. 00:12:32.320 --> 00:12:32.820 OK. 00:12:32.820 --> 00:12:35.940 So to you guys, this will be pretty similar. 00:12:35.940 --> 00:12:38.516 So C# is very similar to Java. 00:12:38.516 --> 00:12:40.140 Almost looks identical at first glance. 00:12:40.140 --> 00:12:42.830 There are some features that are different. 00:12:42.830 --> 00:12:49.100 But it was Microsoft's initiative to compete with Java. 00:12:49.100 --> 00:12:51.200 It's a Microsoft language, first and foremost. 00:12:51.200 --> 00:12:55.805 But there are ways to run C# code on other platforms, 00:12:55.805 --> 00:12:57.680 primarily with the use of what's called Mono. 00:12:57.680 --> 00:13:01.760 So Mono is an open source implementation of what's called the CLR-- 00:13:01.760 --> 00:13:03.740 the common language runtime-- 00:13:03.740 --> 00:13:09.980 which is how Microsoft allows several of its languages, like F#, and C#, 00:13:09.980 --> 00:13:12.320 and Visual C++, Visual Basic. 00:13:12.320 --> 00:13:15.080 They all compile to this intermediary format, 00:13:15.080 --> 00:13:17.450 like how Java compiles to bytecode. 00:13:17.450 --> 00:13:21.520 And you can run any of those languages' code-- 00:13:21.520 --> 00:13:24.880 their version of the bytecode-- with the CLR. 00:13:24.880 --> 00:13:27.440 Mono-- what Mono is, and what Unity relies on 00:13:27.440 --> 00:13:30.830 to allow its use across multiple operating systems, 00:13:30.830 --> 00:13:33.950 is a CLR that's not just Windows specific. 00:13:33.950 --> 00:13:37.380 It actually runs on Mac and on Linux machines, as well. 00:13:37.380 --> 00:13:43.580 And you'll actually see evidence of its existence via the nomenclature used 00:13:43.580 --> 00:13:45.229 for Mono behavior. 00:13:45.229 --> 00:13:47.270 So within Unity, there's this thing called a Mono 00:13:47.270 --> 00:13:49.230 behavior, which we'll take a look at. 00:13:49.230 --> 00:13:53.360 From the beginning, actually, Unity was developed for Mac platforms 00:13:53.360 --> 00:13:54.920 exclusively. 00:13:54.920 --> 00:14:00.020 But in 2012 or 2011 they ended up making it usable across all major desktop 00:14:00.020 --> 00:14:02.150 operating systems. 00:14:02.150 --> 00:14:04.760 But C#-- suffice to say, very similar Java. 00:14:04.760 --> 00:14:05.850 We'll look at its syntax. 00:14:05.850 --> 00:14:09.770 But it's different from Lua in that, with Lua, you could just say, 00:14:09.770 --> 00:14:14.150 oh, x equals 10, or object equals-- and then create 00:14:14.150 --> 00:14:16.220 a table with whatever you want. 00:14:16.220 --> 00:14:20.015 C# is a lot less flexible in this sense, in that you have to actually tell it 00:14:20.015 --> 00:14:23.460 in advance what each data type is that you're trying to make. 00:14:23.460 --> 00:14:26.720 So you can't just create a table or a integer. 00:14:26.720 --> 00:14:31.820 You actually have to say, int my_int, or x equals, and then 10, 00:14:31.820 --> 00:14:33.020 and then semi-colon. 00:14:33.020 --> 00:14:37.430 So there's also more syntax to be conscious of. 00:14:37.430 --> 00:14:41.150 And so really quickly, I can show you just what some C# looks like. 00:14:41.150 --> 00:14:43.590 We'll take a look at this again going forward. 00:14:43.590 --> 00:14:46.620 But as you can see here, we have public. 00:14:46.620 --> 00:14:49.160 So that's another thing about C#. 00:14:49.160 --> 00:14:51.740 In Java, if you're familiar with Java, they're 00:14:51.740 --> 00:14:54.270 object-oriented programming languages. 00:14:54.270 --> 00:14:59.000 And as such, there are objects that are public and private, 00:14:59.000 --> 00:15:04.130 and you have access specifiers for different variables and classes 00:15:04.130 --> 00:15:06.590 that will tell other variables and classes whether or not 00:15:06.590 --> 00:15:08.270 they can communicate effectively. 00:15:08.270 --> 00:15:12.230 So public class just means effectively anybody can see this class. 00:15:12.230 --> 00:15:15.590 Other classes can see this. 00:15:15.590 --> 00:15:17.880 But then you have-- 00:15:17.880 --> 00:15:21.204 see if I have one of these that has a private variable. 00:15:21.204 --> 00:15:22.370 I know there's at least one. 00:15:22.370 --> 00:15:23.120 Here we go. 00:15:23.120 --> 00:15:25.220 So private, Text, text here, for example. 00:15:25.220 --> 00:15:27.980 So first of all, notice that these are variable declarations 00:15:27.980 --> 00:15:29.960 like we've seen before. 00:15:29.960 --> 00:15:32.450 We're saying, this is a variable that I'm going to use. 00:15:32.450 --> 00:15:34.940 In this case, public GameObject helicopter. 00:15:34.940 --> 00:15:36.470 So I'm just defining it. 00:15:36.470 --> 00:15:37.880 Or I'm declaring it. 00:15:37.880 --> 00:15:38.920 I'm not defining it. 00:15:38.920 --> 00:15:40.220 It doesn't equal anything yet. 00:15:40.220 --> 00:15:43.730 But I'm saying, this is going to exist, right? 00:15:43.730 --> 00:15:50.510 You can say equals something, and then define it on the same line. 00:15:50.510 --> 00:15:55.730 But in this case, we are just declaring in advance what different variables 00:15:55.730 --> 00:15:57.742 we're going to need later on. 00:15:57.742 --> 00:15:58.700 Like for example, here. 00:15:58.700 --> 00:16:00.134 We see, in our start method. 00:16:00.134 --> 00:16:03.050 And we'll go over what all these methods are and how they're relevant. 00:16:03.050 --> 00:16:05.690 But we can see here, text equals-- 00:16:05.690 --> 00:16:08.880 and then we're calling some function called GetComponent. 00:16:08.880 --> 00:16:10.760 And then we have some funky syntax here-- 00:16:10.760 --> 00:16:12.800 less than, Text, greater than-- 00:16:12.800 --> 00:16:15.500 and then function call syntax-- 00:16:15.500 --> 00:16:16.740 two parentheses. 00:16:16.740 --> 00:16:19.880 So we can see that there's a lot more syntax. 00:16:19.880 --> 00:16:22.070 But all of the same principles still hold true. 00:16:22.070 --> 00:16:25.330 It's still much the same way to think about programming. 00:16:25.330 --> 00:16:28.250 It's just, there's a little bit more to stay conscious of. 00:16:28.250 --> 00:16:32.490 And we trade off this dynamism for more performance. 00:16:32.490 --> 00:16:35.870 So that's ultimately what it comes down to-- static versus dynamic languages, 00:16:35.870 --> 00:16:39.930 you're trading flexibility for performance, in this case. 00:16:39.930 --> 00:16:42.320 Though C# obviously is a lot faster than Lua. 00:16:42.320 --> 00:16:44.250 We can do a lot more with it. 00:16:44.250 --> 00:16:47.280 And actually, Unity isn't itself programmed in C#. 00:16:47.280 --> 00:16:50.390 Unity itself is programmed in C++. 00:16:50.390 --> 00:16:58.320 But it allows us to program any behavior that we want to with C#. 00:16:58.320 --> 00:16:58.820 All right. 00:16:58.820 --> 00:17:04.760 So that's a look at C# so we can see also what I was alluding to up here. 00:17:04.760 --> 00:17:08.400 We have our private, public, and we do things with them. 00:17:08.400 --> 00:17:12.290 And then, depending on what we've declared public or private, 00:17:12.290 --> 00:17:14.089 these things also transfer into the editor. 00:17:14.089 --> 00:17:16.649 We'll see how all of that comes together soon. 00:17:16.649 --> 00:17:19.190 But suffice to say, that's a look at C#-- what it looks like. 00:17:19.190 --> 00:17:21.356 And we'll use it, and we'll get comfortable with it. 00:17:21.356 --> 00:17:25.940 But it's a little bit different than what we've done thus far. 00:17:25.940 --> 00:17:29.450 Away from programming, we'll a very brief look at what Blender is. 00:17:29.450 --> 00:17:31.820 So I have it installed here. 00:17:31.820 --> 00:17:33.800 And this isn't required for the course. 00:17:33.800 --> 00:17:36.410 I will provide you with all the models and all the assets 00:17:36.410 --> 00:17:39.320 that you need to get working. 00:17:39.320 --> 00:17:40.730 But this is what Blender is. 00:17:40.730 --> 00:17:46.790 So Blender almost looks, at first glance, very similar to Unity. 00:17:46.790 --> 00:17:50.300 The big difference is, this is meant to create new assets. 00:17:50.300 --> 00:17:53.540 And technically, Blender does have a built-in game engine, 00:17:53.540 --> 00:17:55.850 but it's not used for that purpose very much. 00:17:55.850 --> 00:18:00.257 But the sole purpose that we would be using it in this course 00:18:00.257 --> 00:18:01.840 would be just to create new 3D models. 00:18:01.840 --> 00:18:06.500 So as you can see here, I can click on these vertices, and move them around. 00:18:06.500 --> 00:18:12.050 And I'm not a guru by any stretch of the imagination when it comes to Blender. 00:18:12.050 --> 00:18:15.230 But the helicopter, and jet, and skyscrapers, 00:18:15.230 --> 00:18:18.200 and those kind of simple models, I made all of those in Blender. 00:18:18.200 --> 00:18:21.229 And those are bundled with the project, if you 00:18:21.229 --> 00:18:23.270 want to take a look at how those are implemented. 00:18:23.270 --> 00:18:25.750 And you can download Blender at the-- 00:18:25.750 --> 00:18:27.500 I forget what the exact link is, actually. 00:18:27.500 --> 00:18:28.740 Let's take a look. 00:18:28.740 --> 00:18:30.610 Blender dot org. 00:18:33.780 --> 00:18:36.120 And then, if we just go down here, download Blender, 00:18:36.120 --> 00:18:39.720 2.79 looks like the most recent version. 00:18:39.720 --> 00:18:42.000 Blender 2.8-- I guess it's in development. 00:18:42.000 --> 00:18:45.220 But there's nothing concrete about that on the front page. 00:18:45.220 --> 00:18:45.720 But yeah. 00:18:45.720 --> 00:18:48.660 If you want to model 3D assets, and you're curious, 00:18:48.660 --> 00:18:51.240 and you want a free piece of really awesome software, 00:18:51.240 --> 00:18:53.040 can't recommend Blender enough. 00:18:53.040 --> 00:18:57.300 But like I said, I'm going to spend too much time on it, because it's not 00:18:57.300 --> 00:18:59.640 something that will actually be required in the course 00:18:59.640 --> 00:19:02.000 to implement 3D models, to create 3D models, 00:19:02.000 --> 00:19:07.040 since I'll be providing all of that to you in the project in the GitHub repo. 00:19:07.040 --> 00:19:10.450 And so here is a screenshot of basically what we just saw. 00:19:10.450 --> 00:19:13.740 So the fundamental part of Unity. 00:19:13.740 --> 00:19:17.550 So first of all, let's take a look at the Unity editor. 00:19:17.550 --> 00:19:20.820 So we can see here much of what we saw in the screenshots. 00:19:20.820 --> 00:19:24.030 But here, I am live looking at my scene, right? 00:19:24.030 --> 00:19:25.380 I have a helicopter. 00:19:25.380 --> 00:19:27.780 I have this background back here. 00:19:27.780 --> 00:19:28.650 I have a camera-- 00:19:28.650 --> 00:19:30.060 that's right here. 00:19:30.060 --> 00:19:32.180 You can see that it's a camera, because it's got the little camera icon. 00:19:32.180 --> 00:19:34.500 But it's effectively just an invisible game object. 00:19:34.500 --> 00:19:38.670 It's not actually going to be rendered to the screen ever. 00:19:38.670 --> 00:19:42.204 And notice that there are no skyscrapers, no coins, no jets, 00:19:42.204 --> 00:19:43.120 or anything like that. 00:19:43.120 --> 00:19:45.090 Those are all instantiated dynamically. 00:19:45.090 --> 00:19:47.135 But this is the beginning of our scene. 00:19:47.135 --> 00:19:48.510 And it's all laid out in advance. 00:19:48.510 --> 00:19:50.426 And we can see here with this camera preview-- 00:19:50.426 --> 00:19:53.190 which is kind of hard to see because it's really small-- 00:19:53.190 --> 00:19:56.550 but here's a larger view of what it looks like. 00:19:56.550 --> 00:19:59.192 And then we've got a GUI element here, we've got coins here. 00:19:59.192 --> 00:20:00.150 We have our helicopter. 00:20:00.150 --> 00:20:04.950 But all of this is a marked difference from what we've gotten 00:20:04.950 --> 00:20:07.700 used to, which is, program everything, and sort of load it, 00:20:07.700 --> 00:20:09.660 and, oh, did I put this in the right position? 00:20:09.660 --> 00:20:09.780 No. 00:20:09.780 --> 00:20:10.280 I didn't. 00:20:10.280 --> 00:20:10.920 So I got to. 00:20:10.920 --> 00:20:13.720 If I wanted to come over here and just move 00:20:13.720 --> 00:20:15.840 the helicopter a little bit which-- 00:20:15.840 --> 00:20:16.540 like that. 00:20:16.540 --> 00:20:17.040 Whoops. 00:20:17.040 --> 00:20:17.873 I just triggered it. 00:20:17.873 --> 00:20:20.670 If you click on something, by the way, it 00:20:20.670 --> 00:20:23.532 will play any particle systems that are associated with it. 00:20:23.532 --> 00:20:25.740 So you can actually get a preview for those, as well. 00:20:25.740 --> 00:20:27.840 But I can easily just move it here, to the right, 00:20:27.840 --> 00:20:30.600 or to the left, before the game actually starts. 00:20:30.600 --> 00:20:33.760 And if I click on the camera, we can see it there. 00:20:33.760 --> 00:20:37.780 It's a little bit shifted to the left, as opposed to what it was before. 00:20:37.780 --> 00:20:41.560 But if I just press Command-Z couple of times, take it back to normal. 00:20:41.560 --> 00:20:44.500 So game object is an important concept. 00:20:44.500 --> 00:20:49.500 So a game object is basically everything in Unity. 00:20:49.500 --> 00:20:51.840 So the camera is a game object. 00:20:51.840 --> 00:20:54.090 The helicopter, which is right here, is a game object. 00:20:54.090 --> 00:20:57.180 Everything, by the way, that you want to see in your scene in Unity 00:20:57.180 --> 00:20:59.760 is on this left-hand hierarchy right here. 00:20:59.760 --> 00:21:02.760 So helicopter, the game object. 00:21:02.760 --> 00:21:05.220 There's got to be a light source in a 3D scene in order 00:21:05.220 --> 00:21:06.720 for you to actually see things. 00:21:06.720 --> 00:21:09.330 So directional light-- that's a game object. 00:21:09.330 --> 00:21:12.360 Background skyscraper spawner-- we don't see it anywhere. 00:21:12.360 --> 00:21:13.650 But that's also a game object. 00:21:13.650 --> 00:21:15.960 It's just an invisible one. 00:21:15.960 --> 00:21:17.010 A coin spawner. 00:21:17.010 --> 00:21:20.550 There's something called a canvas, which if we double-click that, 00:21:20.550 --> 00:21:26.670 we can see we have this obscenely large GUI here that, paradoxically, 00:21:26.670 --> 00:21:29.850 isn't on top of our scene. 00:21:29.850 --> 00:21:33.210 Unity does a very interesting thing with all of its GUI elements, 00:21:33.210 --> 00:21:40.080 in that it basically maps the canvas to one pixel 00:21:40.080 --> 00:21:44.460 being equal to one Unity unit, which is usually equivalent to a meter. 00:21:44.460 --> 00:21:48.720 And it draws this in a different draw call than it 00:21:48.720 --> 00:21:52.710 draws all of the actual 3D stuff-- 00:21:52.710 --> 00:21:55.710 all the stuff that's down here, basically-- in World Space. 00:21:55.710 --> 00:21:59.760 So when you create a canvas and you see it's gigantic, 00:21:59.760 --> 00:22:01.330 that's just Unity's way of doing GUI. 00:22:01.330 --> 00:22:03.180 It's strange. 00:22:03.180 --> 00:22:05.490 But apparently they do it for performance reasons, 00:22:05.490 --> 00:22:08.700 because they don't have to calculate like fractional points of where 00:22:08.700 --> 00:22:13.530 the UI is supposed to be in World Space, which can get really small. 00:22:13.530 --> 00:22:18.100 But the canvas is a game object. 00:22:18.100 --> 00:22:21.309 Notice that helicopter has children. 00:22:21.309 --> 00:22:24.350 It's got blades, a body, and then a blades collider, which actually could 00:22:24.350 --> 00:22:26.390 have been part of the blades object. 00:22:26.390 --> 00:22:30.420 Canvas itself has two children-- coin text and game over. 00:22:30.420 --> 00:22:34.590 And those are the text on the top right, and "game over" in the center. 00:22:34.590 --> 00:22:38.430 So those are just two text objects, which 00:22:38.430 --> 00:22:43.200 are labels, that we can just populate with whatever text data we want. 00:22:43.200 --> 00:22:45.210 The event system is an object. 00:22:45.210 --> 00:22:49.110 That just gets added to your scene automatically when you add a canvas. 00:22:49.110 --> 00:22:52.590 Airplane spawner, explosion particles, and explosion sound. 00:22:52.590 --> 00:22:54.780 So we have all these different objects. 00:22:54.780 --> 00:22:58.359 They're all part of our scene, and they all do different things. 00:22:58.359 --> 00:23:00.150 But at the core, they're just game objects. 00:23:00.150 --> 00:23:03.600 That's the core-- like the bottom type. 00:23:03.600 --> 00:23:04.382 Yes? 00:23:04.382 --> 00:23:07.274 AUDIENCE: So I would imagine you're not actually using 00:23:07.274 --> 00:23:11.130 a helicopter [INAUDIBLE]. 00:23:11.130 --> 00:23:12.972 COLTON OGDEN: Correct. 00:23:12.972 --> 00:23:16.924 AUDIENCE: So should you actually reset the position 00:23:16.924 --> 00:23:20.890 of the background [INAUDIBLE]? 00:23:20.890 --> 00:23:25.420 COLTON OGDEN: So the question was, since we are maintaining 00:23:25.420 --> 00:23:28.255 a consistent position with the-- 00:23:28.255 --> 00:23:30.720 I'm going to try and scroll in, there we go. 00:23:30.720 --> 00:23:32.726 The nice about Unity 2 is, if you right click, 00:23:32.726 --> 00:23:34.600 you can use W-A-S-D to move around the scene, 00:23:34.600 --> 00:23:37.420 which is super easy and convenient. 00:23:37.420 --> 00:23:40.570 But the helicopter here stays in one spot. 00:23:40.570 --> 00:23:43.630 And the camera always stays in one spot forever. 00:23:43.630 --> 00:23:50.890 So do we move the background image, like we 00:23:50.890 --> 00:23:54.070 do in our Love2D implementation of Flappy Bird, 00:23:54.070 --> 00:23:55.930 where we reset its position? 00:23:55.930 --> 00:23:57.610 And the answer is-- 00:23:57.610 --> 00:24:03.170 I will play it right now in scene view, and let you decide for yourself. 00:24:03.170 --> 00:24:04.940 So let's go to Window. 00:24:04.940 --> 00:24:06.322 I'm gonna go to Layouts. 00:24:06.322 --> 00:24:08.280 So I like the two by three, like I said before, 00:24:08.280 --> 00:24:14.080 so you can see the scene and the game running live at the same time. 00:24:14.080 --> 00:24:16.870 I'm going to move my camera in the scene so that I'm 00:24:16.870 --> 00:24:21.680 looking at this from back here. 00:24:21.680 --> 00:24:26.460 And then I'm going to play the game. 00:24:26.460 --> 00:24:29.750 [MUSIC PLAYING] 00:24:29.750 --> 00:24:32.770 But so. 00:24:32.770 --> 00:24:37.090 Here's where we-- I'm just going to hold it still. 00:24:37.090 --> 00:24:40.570 So what do we think is happening? 00:24:40.570 --> 00:24:42.280 Does it look like our thing is moving? 00:24:42.280 --> 00:24:43.238 Or is it staying still? 00:24:46.720 --> 00:24:48.910 It is staying still. 00:24:48.910 --> 00:24:52.940 Any guesses as to how we're achieving this? 00:24:52.940 --> 00:24:54.670 Changing the texture. 00:24:54.670 --> 00:24:58.120 We are scrolling its texture. 00:24:58.120 --> 00:25:01.540 So when you take a texture and apply it to a 3D surface, 00:25:01.540 --> 00:25:08.880 you map the texture coordinates to the 3D coordinates of the object 00:25:08.880 --> 00:25:09.880 that you want to render. 00:25:09.880 --> 00:25:11.134 It's called UV Mapping. 00:25:11.134 --> 00:25:14.050 They call it UV, because usually, when you're dealing with 3D objects, 00:25:14.050 --> 00:25:15.340 you have your x, y, z. 00:25:15.340 --> 00:25:18.670 And then you want to think of your texture separately from the 3D objects. 00:25:18.670 --> 00:25:21.520 So you use u, v instead of x, y, since you already have x, y, z 00:25:21.520 --> 00:25:22.810 allocated for your 3D object. 00:25:27.840 --> 00:25:32.500 Basically, there's an offset part of the texture-- 00:25:32.500 --> 00:25:34.340 the material that holds the texture-- 00:25:34.340 --> 00:25:39.040 there's an offset field that will reposition the UV mapping 00:25:39.040 --> 00:25:43.160 of that texture onto the 3D surface. 00:25:43.160 --> 00:25:47.680 And when you offset it, it will just sort of wrap itself around, 00:25:47.680 --> 00:25:49.070 if that makes any sense. 00:25:49.070 --> 00:25:51.054 So what we do is we-- 00:25:51.054 --> 00:25:53.540 and I can actually show you in the code where this is. 00:25:53.540 --> 00:25:55.990 This is going to be mentioned at the end of the lecture. 00:25:55.990 --> 00:26:01.300 But we have the scrolling background component here. 00:26:01.300 --> 00:26:06.070 And there's this thing on each material called a texture offset, 00:26:06.070 --> 00:26:10.240 which basically shifts the UV mapping of your texture to your 3D object. 00:26:10.240 --> 00:26:14.740 And so, by setting that texture offset to some value offset, 00:26:14.740 --> 00:26:17.740 which is very similar to what we've done before. 00:26:17.740 --> 00:26:21.370 Notice that offset is just scroll speed times time-- 00:26:21.370 --> 00:26:23.424 Time.time, in this case. 00:26:23.424 --> 00:26:26.340 And I don't mean to overwhelm with, necessarily, all the details here. 00:26:26.340 --> 00:26:29.980 But the bigger picture is that we're taking time-- 00:26:29.980 --> 00:26:33.430 the amount of time since the beginning of the game is started-- 00:26:33.430 --> 00:26:36.460 and we have some scroll speed that we've pre-determined. 00:26:36.460 --> 00:26:40.180 And we can just scroll the texture offset here. 00:26:40.180 --> 00:26:41.770 We're just placing it here at the x. 00:26:41.770 --> 00:26:44.290 So this new Vector2, offset 0-- 00:26:44.290 --> 00:26:46.320 just think of these two as an x and y-- 00:26:46.320 --> 00:26:47.830 a vector 2, vector 3. 00:26:47.830 --> 00:26:50.060 Vectors are just combinations of numbers. 00:26:50.060 --> 00:26:52.720 So 1, 2, 3, 4-- however many you want. 00:26:52.720 --> 00:26:55.240 A Vector 2 offset in 0. 00:26:55.240 --> 00:26:57.370 So we don't want to scroll on the y-axis. 00:26:57.370 --> 00:26:59.020 We just want to scroll left to right. 00:26:59.020 --> 00:27:03.100 So we're going to apply no texture offset to our y-axis, 00:27:03.100 --> 00:27:06.700 but we want to apply a texture offset to our x-axis. 00:27:06.700 --> 00:27:09.220 So that's what their offset there is. 00:27:09.220 --> 00:27:11.140 And I included it also here-- 00:27:11.140 --> 00:27:13.960 notice there's a Bump Map texture offset. 00:27:13.960 --> 00:27:16.050 There's no Bump Map actually on our texture. 00:27:16.050 --> 00:27:17.650 So a Bump Map is effectively-- 00:27:17.650 --> 00:27:21.730 I can maybe find a good Google image for it, 00:27:21.730 --> 00:27:23.360 if you're not familiar with a Bump Map. 00:27:25.915 --> 00:27:26.665 Let me go in here. 00:27:30.050 --> 00:27:35.240 I'm going to hope that there's no shady images on Google Images, but a Bump 00:27:35.240 --> 00:27:37.010 Map-- 00:27:37.010 --> 00:27:37.710 can we see it? 00:27:37.710 --> 00:27:41.110 Well, it's kind of hard to tell. 00:27:41.110 --> 00:27:46.640 But in a lot of 3D games, you'll see like bumpiness and shininess 00:27:46.640 --> 00:27:47.960 on surfaces. 00:27:47.960 --> 00:27:51.050 And that's accomplished the majority of the time using Bump Mapping. 00:27:51.050 --> 00:27:55.010 Because obviously, if you were to model every single tiny little bump or model 00:27:55.010 --> 00:27:59.390 in a surface, it would get extremely difficult to render large objects. 00:27:59.390 --> 00:28:02.990 Because you're looking at thousands of polygons for a surface 00:28:02.990 --> 00:28:06.440 that was actually this detailed in a game. 00:28:06.440 --> 00:28:09.290 So what you do is, you take what's called a Bump Map, 00:28:09.290 --> 00:28:11.570 and the Bump Map gets-- 00:28:11.570 --> 00:28:18.350 during lighting, it will effectively skew the surface normals of a 3D mesh. 00:28:18.350 --> 00:28:23.840 So effectively, it will pretend as if your 3D mesh has a bunch of bumps in it 00:28:23.840 --> 00:28:26.390 for the lighting. 00:28:26.390 --> 00:28:27.350 Only for the lighting. 00:28:27.350 --> 00:28:32.540 And so when it gets lit, and it gets shaded, it looks as if it's bumpy, 00:28:32.540 --> 00:28:35.030 but you're still dealing with a completely flat, completely 00:28:35.030 --> 00:28:39.650 simple cubic mesh in this case, or whatever mesh you want. 00:28:39.650 --> 00:28:43.027 And so the long story short, here, if you 00:28:43.027 --> 00:28:45.860 wanted to include a Bump Map on whatever surface you want to scroll, 00:28:45.860 --> 00:28:47.720 or if you want to edit the Bump Map, this 00:28:47.720 --> 00:28:52.110 is here just because you can also manipulate the Bump Map texture offset. 00:28:52.110 --> 00:28:58.130 It's an included field in a material. 00:28:58.130 --> 00:29:02.770 So any questions as to how this works at large? 00:29:02.770 --> 00:29:06.230 We still have a lot to cover before we go into a lot of the specifics. 00:29:06.230 --> 00:29:11.310 But conceptually, do we understand how this sort of works? 00:29:11.310 --> 00:29:12.480 OK? 00:29:12.480 --> 00:29:12.980 Cool. 00:29:12.980 --> 00:29:14.271 So let's go back to the slides. 00:29:18.390 --> 00:29:18.890 Right. 00:29:18.890 --> 00:29:20.473 So we were talking about game objects. 00:29:20.473 --> 00:29:25.890 So all of those things that we saw before were just game objects. 00:29:25.890 --> 00:29:32.120 So let's go back to the default layout, and then we can look back at our scene. 00:29:32.120 --> 00:29:33.380 So this is our scene. 00:29:33.380 --> 00:29:36.120 All of those things were all of our game objects. 00:29:36.120 --> 00:29:38.300 Those are ultimately containers. 00:29:38.300 --> 00:29:39.990 I talked about this in a prior lecture. 00:29:39.990 --> 00:29:43.820 But this is the beginning of an entity component system, in which case, 00:29:43.820 --> 00:29:45.600 these game objects are our entities. 00:29:45.600 --> 00:29:47.510 They are the entity class-- 00:29:47.510 --> 00:29:50.240 container class-- for what drives behavior. 00:29:50.240 --> 00:29:55.610 And the thing that allows us to actually get interesting behavior out 00:29:55.610 --> 00:29:59.400 of this sort of abstraction is the use of components. 00:29:59.400 --> 00:30:01.130 And we'll talk about that. 00:30:01.130 --> 00:30:05.150 So components are all of the things on the right-hand side, 00:30:05.150 --> 00:30:07.740 by default of the Unity editor. 00:30:07.740 --> 00:30:09.894 So if we're looking at our camera, for example, 00:30:09.894 --> 00:30:12.060 and we take a look at all these things on the right, 00:30:12.060 --> 00:30:14.660 we can see that we have something called a transform, 00:30:14.660 --> 00:30:16.550 we have something called a camera. 00:30:16.550 --> 00:30:19.060 A GUI layer deprecated, so that's by default. 00:30:19.060 --> 00:30:21.750 It was imported from a prior version of Unity, 00:30:21.750 --> 00:30:23.635 so you could actually delete this. 00:30:23.635 --> 00:30:26.110 A flare layer, which we're not using. 00:30:26.110 --> 00:30:29.210 An audio listener-- I believe that comes with all cameras by default, 00:30:29.210 --> 00:30:30.910 though, in case you do want to use it. 00:30:30.910 --> 00:30:33.410 An audio listener and an audio source. 00:30:33.410 --> 00:30:37.120 So all of these different pieces are components. 00:30:37.120 --> 00:30:40.670 They are what drive the behavior of this game object. 00:30:40.670 --> 00:30:43.840 We can create just a brand new, empty game object-- oops, 00:30:43.840 --> 00:30:45.380 I created it as a child. 00:30:45.380 --> 00:30:48.720 We can create a brand new, empty game object here. 00:30:48.720 --> 00:30:51.380 It's just a game object in our scene. 00:30:51.380 --> 00:30:55.430 And it's right where our mouse is. 00:30:55.430 --> 00:30:56.810 Well, it's right here. 00:30:56.810 --> 00:30:59.100 And it does nothing. 00:30:59.100 --> 00:31:01.130 It has one component. 00:31:01.130 --> 00:31:03.704 And that component is the transform. 00:31:03.704 --> 00:31:05.120 Anybody guess what a transform is? 00:31:08.850 --> 00:31:09.350 Yeah. 00:31:09.350 --> 00:31:11.810 AUDIENCE: Is that position, rotation, scale, et cetera? 00:31:11.810 --> 00:31:12.560 COLTON OGDEN: Yes. 00:31:12.560 --> 00:31:16.580 It is the position, rotation, and scale of a game object. 00:31:16.580 --> 00:31:20.120 Something that was before put into six fields-- 00:31:20.120 --> 00:31:22.940 or in this case, nine fields, potentially, or maybe 00:31:22.940 --> 00:31:29.570 three fields with children, is now an object that we can modify at will. 00:31:29.570 --> 00:31:32.960 Well, it's a component that we can modify at will. 00:31:32.960 --> 00:31:36.380 So if I do this-- notice, I'm just scrolling the x. 00:31:36.380 --> 00:31:40.520 It's just moving that transform, which is just the position of that object. 00:31:40.520 --> 00:31:44.150 And Unity knows to look at the transform component, 00:31:44.150 --> 00:31:47.720 and render our object based upon where its transform lies, 00:31:47.720 --> 00:31:51.320 rather than us having to manually set all these things, which we still 00:31:51.320 --> 00:31:52.760 can do in the code. 00:31:52.760 --> 00:31:55.460 We can just modify them in the Unity editor 00:31:55.460 --> 00:31:57.500 directly via a graphical interface. 00:31:57.500 --> 00:32:01.260 It's just an interesting, helpful layer of abstraction. 00:32:01.260 --> 00:32:05.344 So a transform is a component-- a camera, in this case. 00:32:05.344 --> 00:32:06.260 It's just a component. 00:32:06.260 --> 00:32:09.900 We can attach this to anything we want to, and it becomes a camera. 00:32:09.900 --> 00:32:13.340 And then we can set it to be either the default camera or not. 00:32:13.340 --> 00:32:15.550 The camera has a bunch of different things. 00:32:15.550 --> 00:32:18.710 And I can't claim to know all of the fields of every object 00:32:18.710 --> 00:32:21.320 in Unity, because there's just a tremendous number of things. 00:32:21.320 --> 00:32:24.830 But clear flags, background, culling mask-- 00:32:24.830 --> 00:32:29.490 all these things that are relevant to how the camera does its job-- 00:32:29.490 --> 00:32:31.550 they are all things that we have complete access 00:32:31.550 --> 00:32:32.716 to here in the Unity editor. 00:32:32.716 --> 00:32:36.564 We don't even need to touch code, really, for a lot of things. 00:32:36.564 --> 00:32:38.480 An interesting fun thing we can take a look at 00:32:38.480 --> 00:32:43.590 is if we go to Layouts-- go back to two by three, and take a look at our game 00:32:43.590 --> 00:32:44.090 again. 00:32:44.090 --> 00:32:51.140 So we have our camera currently looking at the screen here. 00:32:51.140 --> 00:32:52.570 It's just always in one spot. 00:32:52.570 --> 00:32:55.790 And it has a way of projecting the scene. 00:32:55.790 --> 00:32:57.080 It can do one of two things. 00:32:57.080 --> 00:33:03.020 It can be perspective projection or orthographic projection. 00:33:03.020 --> 00:33:08.760 Does anybody know what the difference is between the two, at least visually? 00:33:08.760 --> 00:33:11.520 So perspective projection-- what that does 00:33:11.520 --> 00:33:15.570 is it models how real cameras, real lenses, the human eye, et cetera, 00:33:15.570 --> 00:33:17.790 behave in real life. 00:33:17.790 --> 00:33:19.350 Things distort a little bit. 00:33:19.350 --> 00:33:22.290 And so you see things, depending on where you're looking at them, 00:33:22.290 --> 00:33:27.150 they look wider or skewed, and not completely geometrical, 00:33:27.150 --> 00:33:31.320 like you would if you were just to draw them at a certain distance. 00:33:31.320 --> 00:33:34.359 Things have vanishing points, et cetera. 00:33:34.359 --> 00:33:36.150 Orthographic-- things look a lot different. 00:33:36.150 --> 00:33:40.230 So notice instantly, so we can see here, perspective 00:33:40.230 --> 00:33:44.550 doesn't really change a whole lot visually with our helicopter. 00:33:44.550 --> 00:33:46.980 Things do change a little bit with the background, 00:33:46.980 --> 00:33:50.420 because the view angle is different between the two-- 00:33:50.420 --> 00:33:52.440 the perspective and the orthographic camera. 00:33:52.440 --> 00:33:55.790 But if we make this a little bit larger. 00:33:55.790 --> 00:33:59.210 So I'm going to increase the size like that. 00:34:02.550 --> 00:34:05.251 And I play. 00:34:05.251 --> 00:34:06.250 One thing we'll notice-- 00:34:06.250 --> 00:34:10.150 what's the first thing that folks are noticing? 00:34:10.150 --> 00:34:14.620 You can actually see the difference between the top and the bottom. 00:34:14.620 --> 00:34:16.770 Whoop. 00:34:16.770 --> 00:34:20.840 How, in particular, I'll put your attention towards the buildings. 00:34:20.840 --> 00:34:22.209 How do the buildings differ? 00:34:22.209 --> 00:34:23.889 AUDIENCE: You can't see the side. 00:34:23.889 --> 00:34:27.590 COLTON OGDEN: You can't see the side anymore. 00:34:27.590 --> 00:34:30.790 The lens sort of curves a bit. 00:34:30.790 --> 00:34:34.880 And so I'm not entirely familiar with all the math involved. 00:34:34.880 --> 00:34:38.500 But at the end of the day, what it boils down to is, with a perspective camera, 00:34:38.500 --> 00:34:40.300 you can actually gauge things as distance 00:34:40.300 --> 00:34:42.091 relative to each other a little bit better. 00:34:42.091 --> 00:34:45.170 With a orthographic camera, everything is completely flat, 00:34:45.170 --> 00:34:47.739 and no matter how far away from you it is 00:34:47.739 --> 00:34:51.040 on the access that's completely perpendicular to you, 00:34:51.040 --> 00:34:53.090 it's going to look the exact same. 00:34:53.090 --> 00:34:55.570 So these buildings are always going to look the exact same, no matter how far 00:34:55.570 --> 00:34:57.611 away they are, no matter which position they are. 00:34:57.611 --> 00:35:00.700 Because everything is just looked at completely flat. 00:35:00.700 --> 00:35:06.230 And the view matrix is calculated in a different way. 00:35:06.230 --> 00:35:09.010 And so, just with a simple button, you can 00:35:09.010 --> 00:35:12.131 change how your game looks completely. 00:35:12.131 --> 00:35:13.630 You've probably seen a lot of games. 00:35:13.630 --> 00:35:17.320 I believe Crossy Road does everything with a orthographic camera, 00:35:17.320 --> 00:35:18.970 versus a perspective camera. 00:35:18.970 --> 00:35:21.430 It has a very distinctive look, especially 00:35:21.430 --> 00:35:23.920 once you skew things a little bit. 00:35:23.920 --> 00:35:26.492 But that's just one thing that you can change just 00:35:26.492 --> 00:35:28.450 without having to touch a single line of code-- 00:35:28.450 --> 00:35:32.114 how your game looks via just the camera's implementation. 00:35:32.114 --> 00:35:33.655 Let's take things back to how it was. 00:35:36.066 --> 00:35:38.190 And there's a lot of things like the field of view. 00:35:38.190 --> 00:35:40.064 So if you want to see more of the game world. 00:35:40.064 --> 00:35:42.730 So things like in Quake and other shooters, 00:35:42.730 --> 00:35:46.210 you can change this view, usually in your menu settings, 00:35:46.210 --> 00:35:49.180 just so you can see more around you. 00:35:49.180 --> 00:35:51.490 And it looks a little like a fisheye lens a little bit, 00:35:51.490 --> 00:35:52.615 depending on how you do it. 00:35:52.615 --> 00:35:55.761 And that's just more distortion of the perspective projection. 00:35:58.640 --> 00:35:59.140 Yeah. 00:35:59.140 --> 00:36:00.760 All of these things, they all have-- 00:36:00.760 --> 00:36:03.260 I don't know necessarily what every single one of them does, 00:36:03.260 --> 00:36:05.669 just because there's just a lot involved. 00:36:05.669 --> 00:36:07.960 And generally, you don't have to mess with it too much. 00:36:07.960 --> 00:36:11.290 It just ultimately depends on what you are trying to accomplish in your game. 00:36:11.290 --> 00:36:14.212 And you'll end up finding specific areas of the editor 00:36:14.212 --> 00:36:16.420 and specific areas of the code base and documentation 00:36:16.420 --> 00:36:18.190 that you dive deeply into. 00:36:18.190 --> 00:36:23.500 But this essentially is what a component affords you the ability to do. 00:36:23.500 --> 00:36:26.680 When you create a component and you attach it to a game object, 00:36:26.680 --> 00:36:29.770 you can easily not only combine different things 00:36:29.770 --> 00:36:33.640 to create this emergent new behavior and combination 00:36:33.640 --> 00:36:36.130 of behaviors for your game objects. 00:36:36.130 --> 00:36:40.990 But Unity allows you, via different ways of programming the components, 00:36:40.990 --> 00:36:45.100 to modify them, depending on how customizable you want them to be, 00:36:45.100 --> 00:36:46.660 in the editor itself. 00:36:46.660 --> 00:36:49.639 So you don't have to touch any of this in code. 00:36:49.639 --> 00:36:51.430 You can just go into the editor and quickly 00:36:51.430 --> 00:36:55.870 whip things up because of the way that you've modeled all your components. 00:36:55.870 --> 00:36:58.060 And so we see other things like the audio listener. 00:36:58.060 --> 00:37:01.300 An audio listener is something that will literally listen for audio, 00:37:01.300 --> 00:37:04.360 and play it back like a microphone to the game player. 00:37:04.360 --> 00:37:07.030 And then an audio source is an actual source of audio. 00:37:07.030 --> 00:37:09.670 And so it will play that audio at the location 00:37:09.670 --> 00:37:11.530 of whatever that game object is. 00:37:11.530 --> 00:37:13.300 So we've combined all these things. 00:37:13.300 --> 00:37:17.320 So now we have a camera that is projecting everything 00:37:17.320 --> 00:37:19.990 with perspective projection. 00:37:19.990 --> 00:37:24.090 And it's an audio listener, so it's going to listen for audio in our scene. 00:37:24.090 --> 00:37:29.440 And it's also going to play an audio source and listen to itself. 00:37:29.440 --> 00:37:30.750 And that's just the beginning. 00:37:30.750 --> 00:37:32.896 We have a whole bunch of other components 00:37:32.896 --> 00:37:35.020 here, which we can take a look just really quickly. 00:37:35.020 --> 00:37:39.902 So the directional light has a light component. 00:37:39.902 --> 00:37:41.860 And so a light, you can do all kinds of things. 00:37:41.860 --> 00:37:44.660 You can make a spotlight, directional light, point light. 00:37:44.660 --> 00:37:46.787 All these look a little bit differently. 00:37:46.787 --> 00:37:48.370 You can make it have a specific color. 00:37:48.370 --> 00:37:53.650 So maybe if you wanted a really dark scene, you could have a dark light. 00:37:53.650 --> 00:37:57.820 Or you could even emulate dawn or dusk with an orange light. 00:37:57.820 --> 00:38:01.126 That's sort of how you'd go about doing that. 00:38:01.126 --> 00:38:04.000 You can bake your lighting, which means that you just pre-compute it, 00:38:04.000 --> 00:38:06.000 so that you don't have to render it in real time 00:38:06.000 --> 00:38:07.619 when you actually play it on hardware. 00:38:07.619 --> 00:38:09.910 A lot of different things, a lot of different settings. 00:38:09.910 --> 00:38:11.890 We don't have time necessarily to go into all of them. 00:38:11.890 --> 00:38:13.750 But looking through all of these, you can 00:38:13.750 --> 00:38:17.980 see all these game objects are just combinations of these components. 00:38:17.980 --> 00:38:24.070 And those combinations of components are responsible for the behavior 00:38:24.070 --> 00:38:25.540 that we get in our game. 00:38:25.540 --> 00:38:29.500 That's the ultimate essence of what Unity is, and how it does what it does. 00:38:29.500 --> 00:38:32.480 And to illustrate the difference, we've talked about this before. 00:38:32.480 --> 00:38:35.442 This is an inheritance chain, where Monster 00:38:35.442 --> 00:38:38.650 inherits from Creature, which then goes to Goblin, Goblin Chief, Elite Goblin 00:38:38.650 --> 00:38:39.250 Chief. 00:38:39.250 --> 00:38:42.850 In Unity, you could create a game object, 00:38:42.850 --> 00:38:47.330 and then give it a creature component, a goblin component, a patrol component-- 00:38:47.330 --> 00:38:47.830 right? 00:38:47.830 --> 00:38:52.110 So maybe you want different things to patrol. 00:38:52.110 --> 00:38:53.860 In Unity, it would be kind of complicated. 00:38:53.860 --> 00:38:57.760 But you could create basically a pathway, 00:38:57.760 --> 00:39:02.030 and then have your entity follow that pathway at a specific time. 00:39:02.030 --> 00:39:04.030 And then, depending on how you've programmed it, 00:39:04.030 --> 00:39:07.670 you could specify all these different characteristics in the editor. 00:39:07.670 --> 00:39:09.520 So you could just say on the editor, OK, I 00:39:09.520 --> 00:39:12.100 want you to go patrol from this range to this range. 00:39:12.100 --> 00:39:15.610 And I want you to do it with this length of time, pause for this long-- 00:39:15.610 --> 00:39:16.110 right? 00:39:16.110 --> 00:39:18.318 And then you can give that to anything in your scene. 00:39:18.318 --> 00:39:21.040 You could make a camera patrol if you wanted to, 00:39:21.040 --> 00:39:24.540 and then have that be demo code for the beginning of your game. 00:39:24.540 --> 00:39:26.520 The flexibility is just insane. 00:39:26.520 --> 00:39:27.341 Elite component. 00:39:27.341 --> 00:39:27.840 Right? 00:39:27.840 --> 00:39:31.410 If you want, maybe, certain enemies or certain objects, if they're elite, 00:39:31.410 --> 00:39:32.410 maybe they shine bright. 00:39:32.410 --> 00:39:34.451 And maybe they drop more experience or something. 00:39:34.451 --> 00:39:38.130 A chief component maybe has better weaponry than a non-chief component. 00:39:38.130 --> 00:39:41.190 And then a toxic component, maybe, is an enemy that, when it dies, 00:39:41.190 --> 00:39:46.410 it sprays toxic gas or toxic liquid all over the place. 00:39:46.410 --> 00:39:48.000 But the flexibility is there. 00:39:48.000 --> 00:39:52.470 You can ascribe any component to any object to get any sort of behavior 00:39:52.470 --> 00:39:53.240 that you want to. 00:39:53.240 --> 00:39:56.139 It's on you, of course, to implement all these components, right? 00:39:56.139 --> 00:39:57.930 You're not going to get all these for free. 00:39:57.930 --> 00:39:59.388 You're going to get a lot for free. 00:39:59.388 --> 00:40:04.360 Unity gives you a ton of components-- really good components. 00:40:04.360 --> 00:40:07.886 But you're ultimately going to need to program your game logic. 00:40:07.886 --> 00:40:10.260 And so you'll have to implement all these things-- elite, 00:40:10.260 --> 00:40:12.660 goblin, what it means to be all these things. 00:40:12.660 --> 00:40:15.690 But thankfully, it's not terribly painful. 00:40:15.690 --> 00:40:19.800 The way at which we go about doing all of this-- and by the way, 00:40:19.800 --> 00:40:23.100 are there any questions so far as to how Unity's model works, 00:40:23.100 --> 00:40:25.350 the difference between composition versus inheritance, 00:40:25.350 --> 00:40:28.830 anything we've talked about this far? 00:40:28.830 --> 00:40:30.510 All right. 00:40:30.510 --> 00:40:35.250 The way at which we actually go about making our own components, 00:40:35.250 --> 00:40:38.655 which is probably what you'll spend the most of your time doing, 00:40:38.655 --> 00:40:41.280 at least in the beginning, when you're bootstrapping your game, 00:40:41.280 --> 00:40:45.900 is programming what's called a MonoBehaviour. 00:40:45.900 --> 00:40:48.610 And so we talked about Mono before. 00:40:48.610 --> 00:40:52.980 So Mono is the open source implementation of the CLR. 00:40:52.980 --> 00:40:54.271 And MonoBehaviour, I imagine-- 00:40:54.271 --> 00:40:56.520 I tried to look this up and see where it derives from. 00:40:56.520 --> 00:41:03.120 I imagine it's because it was originally a Mac exclusive project, Unity. 00:41:03.120 --> 00:41:05.910 And so because everything was implemented in Mono, 00:41:05.910 --> 00:41:11.070 and because this is way it's scripted, MonoBehaviour became the name. 00:41:11.070 --> 00:41:14.640 But a MonoBehaviour is what a component is. 00:41:14.640 --> 00:41:16.340 They are effectively one and the same. 00:41:16.340 --> 00:41:18.048 The difference being that a MonoBehaviour 00:41:18.048 --> 00:41:19.620 is how it's illustrated in code. 00:41:19.620 --> 00:41:23.700 In C#, if you want to program something to be a component that you can then 00:41:23.700 --> 00:41:28.380 attach to a game object, it needs to be inherited from MonoBehaviour. 00:41:31.620 --> 00:41:37.260 So if we go to coin spawner, here. 00:41:37.260 --> 00:41:40.080 And you can see the difference between what's built in to Unity 00:41:40.080 --> 00:41:42.660 and what's your own via-- 00:41:42.660 --> 00:41:44.230 it'll say script here. 00:41:44.230 --> 00:41:46.950 So in this case, I have a coin spawner object, right? 00:41:46.950 --> 00:41:51.090 It's just an empty object, at least in terms of what it displays. 00:41:51.090 --> 00:41:53.410 It's got a transform, which is irrelevant. 00:41:53.410 --> 00:41:56.610 It could be literally anywhere in our entire scene. 00:41:56.610 --> 00:42:00.240 The only difference between this and the empty game 00:42:00.240 --> 00:42:04.260 object that we saw before is that it has a coin spawner. 00:42:04.260 --> 00:42:10.590 And this coin spawner has this thing here. 00:42:10.590 --> 00:42:14.700 All components that you add would have this script field here, 00:42:14.700 --> 00:42:17.070 just to show you that that's the script that it's 00:42:17.070 --> 00:42:19.560 getting it's code behavior from. 00:42:19.560 --> 00:42:25.350 But also, we have this field here called prefabs, which has a size of 1. 00:42:25.350 --> 00:42:29.850 And it's actually calculated based on how many elements 00:42:29.850 --> 00:42:32.610 the list that it's responsible for has. 00:42:32.610 --> 00:42:35.110 And we have one element, as it says, here. 00:42:35.110 --> 00:42:38.667 And it's got a coin pre-fab, which is here. 00:42:38.667 --> 00:42:40.000 And notice that I clicked on it. 00:42:40.000 --> 00:42:42.435 It took me right to it in my assets. 00:42:42.435 --> 00:42:45.060 And so prefabs and all of that-- what that means and how to get 00:42:45.060 --> 00:42:47.460 that all working-- we'll talk about that. 00:42:47.460 --> 00:42:54.660 But a coin spawner script has to exist in our code base 00:42:54.660 --> 00:42:58.440 before we can actually add it to any game objects, right? 00:42:58.440 --> 00:43:02.610 So in my project I do have-- 00:43:02.610 --> 00:43:06.870 usually, you have assets, a folder called Assets in your Unity Project. 00:43:06.870 --> 00:43:09.240 And then I typically create a Resources folder. 00:43:09.240 --> 00:43:12.070 It's not mandatory that you do so, but just for organization, I'll 00:43:12.070 --> 00:43:14.442 create a Resources. 00:43:14.442 --> 00:43:17.400 And then I'll have a bunch of folders for all sorts of different things 00:43:17.400 --> 00:43:18.358 like we've done before. 00:43:18.358 --> 00:43:21.180 Where in the Love2D project, at the parent level, 00:43:21.180 --> 00:43:27.750 you have like a Fonts, a Music or Sounds, and then a source directory. 00:43:27.750 --> 00:43:30.510 In this case we have Fonts, Materials, Models, 00:43:30.510 --> 00:43:33.120 all the different assets that we will need in our game, 00:43:33.120 --> 00:43:35.040 but also a Scripts folder. 00:43:35.040 --> 00:43:41.970 And all the C# scripts here that we'll use amongst all of our components-- 00:43:41.970 --> 00:43:43.470 all of our game objects. 00:43:43.470 --> 00:43:46.020 And so you could easily just go to any of these, 00:43:46.020 --> 00:43:50.910 rather than have to go into your operating system, open up a new window, 00:43:50.910 --> 00:43:53.790 and find your file, and navigate through all the files 00:43:53.790 --> 00:43:56.910 that Unity generates for you, which can be kind of a pain. 00:43:56.910 --> 00:43:59.940 You can just double-click on a coin script, for example. 00:43:59.940 --> 00:44:02.640 And it'll open in your default editor. 00:44:02.640 --> 00:44:06.210 And so one thing that I'll just mention here 00:44:06.210 --> 00:44:08.850 is, if you go to your Unity preferences-- 00:44:08.850 --> 00:44:11.002 on Mac, it's Unity and then Preferences-- 00:44:11.002 --> 00:44:12.210 you can go to External Tools. 00:44:12.210 --> 00:44:15.510 So by default, starting in 2018, Unity is transitioning away 00:44:15.510 --> 00:44:19.649 from its prior IDE, which was called MonoDevelop, which was a good IDE. 00:44:19.649 --> 00:44:21.690 There's transitioning away from that, and they're 00:44:21.690 --> 00:44:26.970 making it focused on Visual Studio as the default IDE. 00:44:26.970 --> 00:44:28.170 I don't use Visual Studio. 00:44:28.170 --> 00:44:29.580 I like VS Code. 00:44:29.580 --> 00:44:33.000 So what I did was-- and what you can do is-- 00:44:33.000 --> 00:44:35.724 you can choose your external script editor here, 00:44:35.724 --> 00:44:37.890 if you prefer a different script editor-- like Atom, 00:44:37.890 --> 00:44:40.330 or VS Code, or Sublime Text. 00:44:40.330 --> 00:44:42.665 And then just browse for it on your file system, 00:44:42.665 --> 00:44:44.790 whether you're on a Windows, Linux, or Mac machine. 00:44:44.790 --> 00:44:47.123 And then you can easily just choose which file you want. 00:44:47.123 --> 00:44:48.670 In this case, I chose VS Code. 00:44:48.670 --> 00:44:50.610 And so that effect that that has is, whenever 00:44:50.610 --> 00:44:53.130 I double-click on a script within Unity, it 00:44:53.130 --> 00:44:56.370 will actually open the IDE or text editor 00:44:56.370 --> 00:45:00.630 that I have assigned to it in Unity's preferences. 00:45:00.630 --> 00:45:08.220 And so here is the Coin component that I have created for this example. 00:45:08.220 --> 00:45:13.440 And notice that every component, first of all, is a class. 00:45:13.440 --> 00:45:20.370 And actually, everything effectively in C#, just as in Java, is a class. 00:45:20.370 --> 00:45:21.790 It's a public class. 00:45:21.790 --> 00:45:26.710 And notice that I call it Coin, and I got this colon, and then MonoBehaviour. 00:45:26.710 --> 00:45:30.630 So this colon-- anybody know, anybody take a guess what the colon means? 00:45:30.630 --> 00:45:31.130 Tony? 00:45:31.130 --> 00:45:31.845 TONY: Extends. 00:45:31.845 --> 00:45:32.970 COLTON OGDEN: Extends, yes. 00:45:32.970 --> 00:45:36.525 Extends or inherits from MonoBehaviour. 00:45:36.525 --> 00:45:38.400 So anytime you have a component that you want 00:45:38.400 --> 00:45:41.970 to create, you want to add it to Unity, and allow you to see it in the editor, 00:45:41.970 --> 00:45:45.430 and allow you to actually drive behavior of an object, 00:45:45.430 --> 00:45:47.670 you need to inherit from MonoBehaviour. 00:45:47.670 --> 00:45:52.680 Like it says here on my VS Code, since I have the extension for OmniSharp, 00:45:52.680 --> 00:45:55.410 it will actually tell me, MonoBehaviour is the base class 00:45:55.410 --> 00:45:59.547 from which every Unity script derives. 00:45:59.547 --> 00:46:00.880 There's a couple of things here. 00:46:00.880 --> 00:46:03.450 So notice that we have a few methods. 00:46:03.450 --> 00:46:10.320 So void Start, void Update, and void OnTriggerEnter. 00:46:10.320 --> 00:46:12.609 So anybody take a guess as to what-- 00:46:12.609 --> 00:46:14.400 ignoring OnTriggerEnter-- does anybody have 00:46:14.400 --> 00:46:16.784 a guess as to what Start and Update do? 00:46:16.784 --> 00:46:17.768 Yeah. 00:46:17.768 --> 00:46:21.220 AUDIENCE: Could it be just like that and [INAUDIBLE] update [INAUDIBLE]?? 00:46:21.220 --> 00:46:22.281 COLTON OGDEN: Sorry, say it one more time. 00:46:22.281 --> 00:46:24.870 AUDIENCE: Would it just [INAUDIBLE] an update or [INAUDIBLE]?? 00:46:24.870 --> 00:46:25.786 COLTON OGDEN: Exactly. 00:46:25.786 --> 00:46:29.490 It would be just like we did before when we created objects 00:46:29.490 --> 00:46:35.220 in our Love2D projects, where we had an init function assigned to every class, 00:46:35.220 --> 00:46:37.250 and an update function assigned to every class. 00:46:37.250 --> 00:46:39.090 And we would call those ourselves. 00:46:39.090 --> 00:46:44.070 Every MonoBehaviour can have a Start method. 00:46:44.070 --> 00:46:46.800 In this case, it's empty, because every time you 00:46:46.800 --> 00:46:50.190 create a new script by the Unity editor, it will automatically-- first of all, 00:46:50.190 --> 00:46:53.390 it will automatically create a brand new file for you. 00:46:53.390 --> 00:46:55.530 So let's just say I want to create a new script. 00:46:55.530 --> 00:46:58.500 So if I'm in the Unity editor, and I go to my assets-- 00:46:58.500 --> 00:47:00.720 I right-click Create. 00:47:00.720 --> 00:47:03.160 And then I want to create a new C# script. 00:47:03.160 --> 00:47:04.830 It'll create it there. 00:47:04.830 --> 00:47:06.480 I can say, maybe I want this to be-- 00:47:06.480 --> 00:47:08.880 I don't know-- Test Component, right? 00:47:11.430 --> 00:47:15.870 So this should have the effect of, when I open it in my VS Code, 00:47:15.870 --> 00:47:18.330 this Test Component-- this was auto generated for us. 00:47:18.330 --> 00:47:20.340 We didn't have to write any of this boilerplate. 00:47:20.340 --> 00:47:26.850 But every script that you create, by default, 00:47:26.850 --> 00:47:29.805 is a MonoBehaviour, which it strictly does not have to be. 00:47:29.805 --> 00:47:34.034 You could create a class of your own, that maybe you call behind the scenes, 00:47:34.034 --> 00:47:36.450 or maybe it just represents a data structure or something. 00:47:36.450 --> 00:47:39.810 But by default, anytime you create a new script in Unity, 00:47:39.810 --> 00:47:43.200 it'll save you the hassle of typing out all this stuff by hand. 00:47:43.200 --> 00:47:48.380 And it'll give you an empty Start method and an empty Update method. 00:47:48.380 --> 00:47:53.130 And so, like Tony said, the Start method gets called as soon as the object 00:47:53.130 --> 00:47:55.980 that it's assigned to gets instantiated. 00:47:55.980 --> 00:47:59.640 Well, as soon as this component gets instantiated, rather. 00:47:59.640 --> 00:48:03.750 Which often is the case that it gets instantiated 00:48:03.750 --> 00:48:05.490 at the same time as a game object. 00:48:05.490 --> 00:48:06.020 Not always. 00:48:06.020 --> 00:48:10.140 You can create game components on the fly. 00:48:10.140 --> 00:48:12.535 But this Start method will get called. 00:48:12.535 --> 00:48:14.910 Anything that you put in here will get called right away. 00:48:14.910 --> 00:48:17.640 And then this Update method, Unity will-- every frame, 00:48:17.640 --> 00:48:20.760 go through every component on every live game object-- 00:48:20.760 --> 00:48:26.010 and will call the code that's contained within this Update function. 00:48:26.010 --> 00:48:28.140 And you don't have to call this anywhere yourself. 00:48:28.140 --> 00:48:34.410 Just by assigning this component to a game object in your scene, 00:48:34.410 --> 00:48:38.460 you get the update, and start, and all this other functionality 00:48:38.460 --> 00:48:40.110 given to you for free. 00:48:40.110 --> 00:48:43.140 And MonoBehaviours are actually much more complex 00:48:43.140 --> 00:48:48.190 than just Start and Update. 00:48:48.190 --> 00:48:56.650 So if you go to MonoBehaviour here, we can see that-- 00:48:56.650 --> 00:48:59.440 by the way, I want to shout out Unity's documentation. 00:48:59.440 --> 00:49:01.780 Unity has amazing documentation-- 00:49:01.780 --> 00:49:02.790 docs.unity3d.com. 00:49:02.790 --> 00:49:05.610 You will go through pretty much everything 00:49:05.610 --> 00:49:10.600 you possibly could ever want with every object implemented in Unity, in quite 00:49:10.600 --> 00:49:12.886 a good detail, with a lot of examples. 00:49:12.886 --> 00:49:14.760 But here we can see, just in the description, 00:49:14.760 --> 00:49:23.010 it will tell us, the MonoBehaviour will get start, update, fixed update, late 00:49:23.010 --> 00:49:26.859 update, on GUI-- all of these functions called for us, assuming 00:49:26.859 --> 00:49:27.900 that they're implemented. 00:49:27.900 --> 00:49:30.316 And you don't have to implement them if you don't want to. 00:49:30.316 --> 00:49:32.469 If they're not implemented, they just won't happen. 00:49:32.469 --> 00:49:34.260 If there's no start method, then that means 00:49:34.260 --> 00:49:35.710 there's no start logic for this component. 00:49:35.710 --> 00:49:37.050 So it doesn't need to execute. 00:49:37.050 --> 00:49:39.420 If there's no update, maybe it just needs to start at the very beginning, 00:49:39.420 --> 00:49:41.760 but never update after that, don't implement update. 00:49:41.760 --> 00:49:44.880 And update will not be called. 00:49:44.880 --> 00:49:46.680 All of these are optional. 00:49:46.680 --> 00:49:48.570 That's just a small chunk of MonoBehaviour, 00:49:48.570 --> 00:49:51.540 though, because you also have messages. 00:49:51.540 --> 00:49:56.610 So messages are functions that you override. 00:49:56.610 --> 00:49:59.650 As you can see, there's a whole lot of them. 00:49:59.650 --> 00:50:02.760 And all of these messages get called, depending on certain things that 00:50:02.760 --> 00:50:04.770 happen in the game scene. 00:50:04.770 --> 00:50:12.690 So OnTriggerEnter, for example, if our object is a trigger, and we enter it, 00:50:12.690 --> 00:50:15.750 then the behavior will get called in that function, which 00:50:15.750 --> 00:50:20.340 will allow us to do things like-- if our helicopter enters a building, 00:50:20.340 --> 00:50:22.350 we can call that helicopter's explode method, 00:50:22.350 --> 00:50:26.790 which is literally what we do in this project, thanks to this function. 00:50:26.790 --> 00:50:29.420 And all we really need to do is just a couple of lines of code. 00:50:29.420 --> 00:50:31.080 It's very simple. 00:50:31.080 --> 00:50:34.250 OnPostRender, OnPreRender-- all these different things 00:50:34.250 --> 00:50:35.500 are called at different times. 00:50:35.500 --> 00:50:38.499 You can look into all of these, if you want to, just by clicking on them 00:50:38.499 --> 00:50:41.070 and looking at their documentation. 00:50:41.070 --> 00:50:44.070 LateUpdate is called after all update functions have been called. 00:50:44.070 --> 00:50:49.560 This can be relevant for certain physics calculations. 00:50:49.560 --> 00:50:53.760 But there's a whole lot of different things you can do. 00:50:53.760 --> 00:50:56.490 You don't necessarily need to do a lot of things yourself, 00:50:56.490 --> 00:50:59.370 if Unity provides you with the function that gives you 00:50:59.370 --> 00:51:00.970 the effect that you're looking for. 00:51:00.970 --> 00:51:03.880 And so if you're curious, MonoBehaviour, and then the docs at large. 00:51:03.880 --> 00:51:07.200 This is just all the documentation-- just an insane amount of documentation. 00:51:07.200 --> 00:51:09.640 And that's just in the classes. 00:51:09.640 --> 00:51:14.470 There's all these other little side areas, as well. 00:51:14.470 --> 00:51:17.352 And so that's sort of what MonoBehaviour is. 00:51:17.352 --> 00:51:18.060 It's a component. 00:51:18.060 --> 00:51:20.526 It gets a lot of these functions called for you. 00:51:20.526 --> 00:51:21.900 You don't have to implement them. 00:51:21.900 --> 00:51:26.160 But if you do, you get a lot of functionality for free, basically. 00:51:26.160 --> 00:51:30.450 Any questions as to what a MonoBehaviour is, how it works, and so forth? 00:51:30.450 --> 00:51:37.150 Or any of the syntax we've seen thus far for creating a MonoBehaviour? 00:51:37.150 --> 00:51:38.240 All right. 00:51:38.240 --> 00:51:42.090 And so, here in our coin, for example, which we were looking at before, 00:51:42.090 --> 00:51:45.300 notice that I'm referencing something called a transform. 00:51:45.300 --> 00:51:51.780 Transform.position.x is less than negative 25, destroy a game object. 00:51:51.780 --> 00:51:54.983 If this is the coin, what do we think that this is accomplishing? 00:51:57.804 --> 00:51:59.720 AUDIENCE: It goes off the screen [INAUDIBLE]?? 00:51:59.720 --> 00:52:00.960 COLTON OGDEN: Yep. 00:52:00.960 --> 00:52:06.480 So the transform, recall, was our component 00:52:06.480 --> 00:52:09.450 that encapsulates our rotation, scale, and position. 00:52:09.450 --> 00:52:13.530 So we can just say, if transform.position.x is less 00:52:13.530 --> 00:52:17.280 than negative 25, destroy game object. 00:52:17.280 --> 00:52:19.320 Because we're spawning the coins dynamically. 00:52:19.320 --> 00:52:22.020 When they get off screen-- just like we did with the pipes, if you remember. 00:52:22.020 --> 00:52:23.978 And I had a screenshot, actually, in that slide 00:52:23.978 --> 00:52:25.770 that showcased what that looked like. 00:52:25.770 --> 00:52:29.940 We can see that exact thing live here. 00:52:29.940 --> 00:52:33.450 If I go to Layouts, two by three, and we play the game again, 00:52:33.450 --> 00:52:37.340 and then I'll just die at some point. 00:52:37.340 --> 00:52:42.741 But if we do this, we're seeing our scene live. 00:52:42.741 --> 00:52:43.990 So we're following this-- yep. 00:52:43.990 --> 00:52:46.920 See how the coin-- as soon as the building, and the plane, 00:52:46.920 --> 00:52:48.570 and the coins all get to this point-- 00:52:48.570 --> 00:52:53.875 this is negative 25 in Unity units, not in pixels. 00:52:53.875 --> 00:52:56.500 Everything in Unity is based on Unity units, which, by default, 00:52:56.500 --> 00:53:02.310 1 is equal to one meter, as opposed to-- we've been thus far using just pixels. 00:53:02.310 --> 00:53:07.152 But pixels aren't viable in 3D. 00:53:07.152 --> 00:53:10.291 [MUSIC PLAYING] 00:53:10.291 --> 00:53:12.290 But that's effectively what that component does. 00:53:12.290 --> 00:53:16.010 It's checking, in our Update function-- void Update-- 00:53:16.010 --> 00:53:20.300 if transform.position.x less than negative 25. 00:53:20.300 --> 00:53:23.090 And notice that we don't actually have to declare transform 00:53:23.090 --> 00:53:26.000 anywhere, which is interesting. 00:53:26.000 --> 00:53:28.130 That's because MonoBehaviour, by default, gives you 00:53:28.130 --> 00:53:32.000 access to its game objects transform just by default. 00:53:32.000 --> 00:53:35.270 That's just something you get for free. 00:53:35.270 --> 00:53:39.500 And then, notice gameObject-- we also haven't declared gameObject anywhere. 00:53:39.500 --> 00:53:42.050 Because by default, we have access to gameObject. 00:53:42.050 --> 00:53:46.330 It's the game object that this script belongs to. 00:53:46.330 --> 00:53:48.058 That this component belongs to. 00:53:48.058 --> 00:53:50.930 AUDIENCE: [INAUDIBLE] 00:53:50.930 --> 00:53:54.170 COLTON OGDEN: This would be the actual-- 00:53:54.170 --> 00:53:57.980 so the interesting thing about the classes 00:53:57.980 --> 00:54:00.920 is, you don't have to explicitly say this. 00:54:00.920 --> 00:54:08.490 Because if you had int myNumber equals 10, and you just say, myNumber-- 00:54:08.490 --> 00:54:12.260 the difference between Lua and C# and Java is that, 00:54:12.260 --> 00:54:16.070 it will already know what myNumber is, this is myNumber. 00:54:16.070 --> 00:54:17.535 It will know its this objects. 00:54:17.535 --> 00:54:18.160 AUDIENCE: Yeah. 00:54:18.160 --> 00:54:19.826 COLTON OGDEN: You don't have to do that. 00:54:23.000 --> 00:54:26.870 Sort of a nice little thing to save you a little bit of time. 00:54:26.870 --> 00:54:30.500 Because you could then just say, myNumber plus equals 10. 00:54:30.500 --> 00:54:33.710 Another nice thing about C#, by the way, which we didn't get in Lua-- 00:54:33.710 --> 00:54:36.051 you can do compound assignment operators. 00:54:36.051 --> 00:54:38.300 So you can do plus equals, minus equals, times equals. 00:54:38.300 --> 00:54:40.890 That's one of my little pet peeves I have with-- 00:54:40.890 --> 00:54:41.390 oh. 00:54:41.390 --> 00:54:43.806 And notice that also, the nice thing about the fact that I 00:54:43.806 --> 00:54:45.220 have OmniSharp-- it'll underline. 00:54:45.220 --> 00:54:48.410 And this is just a trait of most IDEs, honestly. 00:54:48.410 --> 00:54:50.660 So you get this with a lot of places. 00:54:50.660 --> 00:54:55.994 But it'll tell you myNumber is not assigned, with the underlining, 00:54:55.994 --> 00:54:57.410 and also just by hovering over it. 00:54:57.410 --> 00:55:00.650 The named myNumber does not exist in the current context. 00:55:00.650 --> 00:55:03.260 But I can just say, int myNumber. 00:55:03.260 --> 00:55:05.480 And then it's gone. 00:55:05.480 --> 00:55:07.430 A little bit more that we have to worry about, 00:55:07.430 --> 00:55:09.950 and a little bit less that we have to worry about. 00:55:09.950 --> 00:55:12.300 A little give and take. 00:55:12.300 --> 00:55:16.040 But still, I think, overall, C# is going to be a lot more syntax-heavy. 00:55:16.040 --> 00:55:19.820 You do have to worry about things like braces, and semi-colons, 00:55:19.820 --> 00:55:23.020 and putting everything in a boilerplate. 00:55:23.020 --> 00:55:26.570 And then, obviously, type declaration, and return type declaration. 00:55:26.570 --> 00:55:29.810 It can be a little bit more than we've gotten used to so far. 00:55:29.810 --> 00:55:34.190 But it's honestly not too bad, just given that you can use IDEs. 00:55:34.190 --> 00:55:37.610 First of all, the fact that you're statically typing everything, 00:55:37.610 --> 00:55:40.040 you can detect a lot more errors in advance. 00:55:40.040 --> 00:55:42.664 If you're trying to do something with some type 00:55:42.664 --> 00:55:45.080 that you're not supposed to do, like some function accepts 00:55:45.080 --> 00:55:48.230 some object of some type, but you're passing in some other object, 00:55:48.230 --> 00:55:50.620 you'll catch that in advance. 00:55:50.620 --> 00:55:53.760 And so that's a really nice thing. 00:55:53.760 --> 00:55:54.260 But yeah. 00:55:54.260 --> 00:55:57.440 It is a give and take. 00:55:57.440 --> 00:56:00.770 And also, IDEs will give you, like I said, 00:56:00.770 --> 00:56:03.470 a lot of the functionality-- a lot of the autocomplete-- that 00:56:03.470 --> 00:56:05.342 makes a lot of this more sustainable. 00:56:05.342 --> 00:56:08.550 And it's not to say, of course, that Lua and Love2D don't have their own IDE. 00:56:08.550 --> 00:56:11.637 Like ZeroBrane Studio is popular, from what I understand. 00:56:11.637 --> 00:56:12.470 Haven't used it yet. 00:56:12.470 --> 00:56:16.930 But particularly when you venture into Java, and C#, and compiled languages, 00:56:16.930 --> 00:56:20.890 static languages-- having those features does save you a lot more time, 00:56:20.890 --> 00:56:23.390 relatively speaking, than when you're in a dynamic language. 00:56:25.920 --> 00:56:28.730 So that's what MonoBehaviours are. 00:56:28.730 --> 00:56:32.720 Every component of our game effectively has-- like the helicopter 00:56:32.720 --> 00:56:35.330 has its own script, a Heli Controller. 00:56:35.330 --> 00:56:38.450 The coin has its own script-- the Coin Spawner, the Skyscraper Spawner, 00:56:38.450 --> 00:56:39.546 the Skyscraper-- 00:56:39.546 --> 00:56:42.170 they all have their own scripts that drive their game behavior. 00:56:42.170 --> 00:56:46.490 But they also have scripts and components that are part of Unity core, 00:56:46.490 --> 00:56:48.110 as well. 00:56:48.110 --> 00:56:50.280 Including Colliders and Triggers. 00:56:50.280 --> 00:56:52.370 So if I'm looking in Unity-- 00:56:52.370 --> 00:56:54.350 so I'm going to go to-- 00:56:54.350 --> 00:56:57.530 and this will actually be the last thing we look at before we take a break. 00:56:57.530 --> 00:57:03.380 But if I'm in Unity, and I'm going to go back to my default layout, 00:57:03.380 --> 00:57:06.830 just because it's a little cramped on a 720p. 00:57:06.830 --> 00:57:09.530 Go to my helicopter. 00:57:09.530 --> 00:57:11.450 Helicopter's got a couple of pieces to it. 00:57:11.450 --> 00:57:15.000 So let's actually go to where I can see it here. 00:57:15.000 --> 00:57:17.630 So one of the awesome things I love about Unity 00:57:17.630 --> 00:57:23.690 is, it gives you a lot of this editor magic-- this editor sort of sugar. 00:57:23.690 --> 00:57:27.590 It shows you visually where a lot of the things are in your game world. 00:57:27.590 --> 00:57:31.551 So the green rectangles-- anybody know what those are, or can guess? 00:57:31.551 --> 00:57:32.384 AUDIENCE: Hit boxes? 00:57:32.384 --> 00:57:33.180 COLTON OGDEN: Yep. 00:57:33.180 --> 00:57:34.030 Hit boxes. 00:57:34.030 --> 00:57:36.500 Exactly. 00:57:36.500 --> 00:57:38.900 These are colliders. 00:57:38.900 --> 00:57:41.750 So the blades-- it doesn't have a collider. 00:57:41.750 --> 00:57:44.510 That blades collider is actually separate. 00:57:44.510 --> 00:57:50.630 The box collider here is this collider right here. 00:57:50.630 --> 00:57:53.454 And so a collider is literally just something 00:57:53.454 --> 00:57:54.870 that collides with something else. 00:57:54.870 --> 00:57:56.870 And you can set it to be a trigger or not. 00:57:56.870 --> 00:58:02.930 If it's a trigger, then it actually won't trigger the OnTriggerCallback 00:58:02.930 --> 00:58:07.710 function that we briefly saw earlier. 00:58:07.710 --> 00:58:10.860 So the things that you want to activate triggers, 00:58:10.860 --> 00:58:12.360 you should make those not triggers. 00:58:12.360 --> 00:58:15.760 And then triggers, all you have to do is just click this little Trigger button. 00:58:15.760 --> 00:58:19.190 So what a trigger is is just a region that you've determined-- 00:58:19.190 --> 00:58:22.020 or some object that you've determined-- should cause behavior 00:58:22.020 --> 00:58:23.700 when it gets triggered. 00:58:23.700 --> 00:58:27.420 So in this case, I've assigned-- 00:58:30.390 --> 00:58:33.930 actually, I'll just play it. 00:58:33.930 --> 00:58:39.170 But the airplane has a trigger, right? 00:58:44.190 --> 00:58:48.930 All of these things have colliders, whether they're triggers or not. 00:58:48.930 --> 00:58:51.930 The helicopter-- its blades and its body-- 00:58:51.930 --> 00:58:55.860 there are two colliders, two boxes. 00:58:55.860 --> 00:58:57.810 The coins all have colliders. 00:58:57.810 --> 00:59:00.900 The skyscrapers will have colliders, and the airplanes have colliders. 00:59:00.900 --> 00:59:06.220 The difference is that-- oh, and by the way, another cool thing. 00:59:06.220 --> 00:59:08.810 It's easy to get very sidetracked, just because there's 00:59:08.810 --> 00:59:10.560 so many cool things to talk about. 00:59:10.560 --> 00:59:12.430 You can pause the game while it's running. 00:59:12.430 --> 00:59:17.500 So it's paused right now, but it's in the exact state that I left it. 00:59:17.500 --> 00:59:18.990 So there's three coins there. 00:59:18.990 --> 00:59:20.190 I got my helicopter there. 00:59:20.190 --> 00:59:21.600 I can freely go about the scene. 00:59:21.600 --> 00:59:23.070 I can analyze things. 00:59:23.070 --> 00:59:26.980 I can actually modify this in real time. 00:59:26.980 --> 00:59:30.630 So I can change its rotation, if I want to. 00:59:30.630 --> 00:59:32.559 Probably don't want to do that. 00:59:32.559 --> 00:59:33.600 But I could if I want to. 00:59:33.600 --> 00:59:35.700 I can change its position, right? 00:59:35.700 --> 00:59:37.450 So I can move it left to right, like that. 00:59:37.450 --> 00:59:39.741 And notice that I actually have just the body selected, 00:59:39.741 --> 00:59:42.111 so the blades are kind of separate. 00:59:42.111 --> 00:59:43.860 I don't even know what kind of crazy stuff 00:59:43.860 --> 00:59:45.840 would happen if I just messed with this and just let it run. 00:59:45.840 --> 00:59:47.214 I haven't tested it that crazily. 00:59:47.214 --> 00:59:49.480 But you are allowed to step through. 00:59:49.480 --> 00:59:49.980 Oh, OK. 00:59:49.980 --> 00:59:51.360 It looks like they both just go. 00:59:51.360 --> 00:59:54.360 Oh, yeah, because they're parented to the helicopter object. 00:59:54.360 --> 00:59:56.250 So they're both going to align. 00:59:56.250 --> 00:59:58.950 They're going to move at the exact same rate, 00:59:58.950 --> 01:00:02.220 regardless of how far apart they are. 01:00:02.220 --> 01:00:03.720 The individual objects. 01:00:03.720 --> 01:00:08.010 But you can just step through your game's execution frame by frame, 01:00:08.010 --> 01:00:09.839 and get a sense of-- 01:00:09.839 --> 01:00:11.880 if you're trying to pinpoint a bug, maybe, that's 01:00:11.880 --> 01:00:13.325 position-based or something that's tricky 01:00:13.325 --> 01:00:15.950 and you just haven't been able to find exactly what's going on. 01:00:19.156 --> 01:00:21.030 You can look through your whole scene and all 01:00:21.030 --> 01:00:26.506 of the fields of every object in step time, 01:00:26.506 --> 01:00:28.380 just by stepping through-- this button here-- 01:00:28.380 --> 01:00:29.910 assuming that you're in pause mode. 01:00:29.910 --> 01:00:32.460 And then just looking at all the components here on the right side. 01:00:32.460 --> 01:00:34.020 Because those will all still update. 01:00:34.020 --> 01:00:37.050 All these fields will update any time you perform 01:00:37.050 --> 01:00:40.590 any changes in the actual scene. 01:00:40.590 --> 01:00:42.570 So super helpful for debugging. 01:00:42.570 --> 01:00:44.010 I know I've used it a bunch. 01:00:44.010 --> 01:00:46.630 And then if I start again, or if I stop it, 01:00:46.630 --> 01:00:49.170 the nice thing is, any of the changes that you 01:00:49.170 --> 01:00:51.920 make while it's running to your object, they 01:00:51.920 --> 01:00:54.930 don't get applied when you actually go back to the game. 01:00:54.930 --> 01:00:59.104 So notice that I messed with the two pieces, I separated them. 01:00:59.104 --> 01:01:00.270 And then I stopped the game. 01:01:00.270 --> 01:01:04.120 It ended up going right back to where it was in the very beginning. 01:01:04.120 --> 01:01:06.820 So all this gets just basically saved like a snapshot. 01:01:06.820 --> 01:01:10.080 You can do whatever you want during your game, and then come back to it, 01:01:10.080 --> 01:01:12.440 and it will all get reverted back to where it was. 01:01:12.440 --> 01:01:12.951 Yeah. 01:01:12.951 --> 01:01:15.306 TONY: So [INAUDIBLE] if you hit single player, 01:01:15.306 --> 01:01:20.190 and I kept making changes while I'm not involved [INAUDIBLE].. 01:01:20.190 --> 01:01:20.940 COLTON OGDEN: Yes. 01:01:20.940 --> 01:01:21.720 So, yeah. 01:01:21.720 --> 01:01:24.011 Tony just basically echoed what I just said, which was, 01:01:24.011 --> 01:01:27.270 if you make changes in your game while it's running, 01:01:27.270 --> 01:01:31.020 and you're trying to maybe tweak them such that it's perfect when you're 01:01:31.020 --> 01:01:32.580 actually done, they don't get saved. 01:01:32.580 --> 01:01:36.600 So you have to actually make a conscious effort to remember what you've done, 01:01:36.600 --> 01:01:40.830 how you've changed different fields, to fix any bugs, if they do exist. 01:01:40.830 --> 01:01:45.400 But it is something that can be disheartening or frustrating, if you 01:01:45.400 --> 01:01:48.150 finally fix something, and then you forget what it is you changed. 01:01:48.150 --> 01:01:50.350 And then you have to mess with it a whole bunch. 01:01:50.350 --> 01:01:52.350 So remember all the changes you make, if they're 01:01:52.350 --> 01:01:53.970 pertinent to your actual game's execution 01:01:53.970 --> 01:01:55.320 and the debugging of your game. 01:01:58.170 --> 01:02:02.700 And then there's also a console, as well, which is nice. 01:02:02.700 --> 01:02:08.550 If you want to output things like JavaScript style on the web, 01:02:08.550 --> 01:02:09.810 you can do console.log. 01:02:09.810 --> 01:02:13.410 You can do the same thing with a debug call here in Unity. 01:02:13.410 --> 01:02:16.620 I don't have any of those calls in the actual game. 01:02:16.620 --> 01:02:19.347 But it is something that we'll look at going forward. 01:02:19.347 --> 01:02:21.180 And it is something that can be very helpful 01:02:21.180 --> 01:02:24.660 if you want to measure something or output something that you can't 01:02:24.660 --> 01:02:26.202 necessarily look at in the inspector. 01:02:26.202 --> 01:02:29.243 In the case of this game, most of anything that we want to take a look at 01:02:29.243 --> 01:02:30.570 is visible in the inspector. 01:02:30.570 --> 01:02:36.120 But if you have an algorithm, maybe you have a generator that's not visual, 01:02:36.120 --> 01:02:37.380 like a level generator. 01:02:37.380 --> 01:02:41.040 And you want to make sure that the data structure representing your level 01:02:41.040 --> 01:02:44.840 is generating things properly, you can output everything maybe via hashmarks 01:02:44.840 --> 01:02:46.590 or something in your console, and actually 01:02:46.590 --> 01:02:48.810 see it that way when you're running the code, 01:02:48.810 --> 01:02:52.460 rather than having to run the actual game and look through it that way. 01:02:52.460 --> 01:02:55.230 Some things just are hard to model in the editor, 01:02:55.230 --> 01:02:57.310 and still need console output. 01:02:57.310 --> 01:02:59.890 So the console is there to help you. 01:02:59.890 --> 01:03:02.980 And so debug.log is the function, I believe, 01:03:02.980 --> 01:03:07.150 that you need to see all that stuff. 01:03:07.150 --> 01:03:07.650 Right. 01:03:07.650 --> 01:03:08.640 Colliders and triggers. 01:03:08.640 --> 01:03:10.390 So we had a little bit of a tangent there, 01:03:10.390 --> 01:03:14.684 but the helicopter is comprised of these three things. 01:03:14.684 --> 01:03:16.600 But the blades collider should have ultimately 01:03:16.600 --> 01:03:18.580 been merged with the blades object here. 01:03:18.580 --> 01:03:21.610 But we can think of it as the blades and the body. 01:03:21.610 --> 01:03:26.470 The reason they're separated-- well, there's two reasons they're separated. 01:03:26.470 --> 01:03:30.010 One core reason they're separated is they're just different sizes. 01:03:30.010 --> 01:03:32.300 So the blades are longer than the body. 01:03:32.300 --> 01:03:35.500 And so we have, for that reason, two separate colliders. 01:03:35.500 --> 01:03:38.800 So we're looking at the helicopter here. 01:03:38.800 --> 01:03:42.850 We can see that the collider for the blades 01:03:42.850 --> 01:03:44.840 extends a little bit farther than the body. 01:03:44.840 --> 01:03:48.490 We don't want to create a box collider for the entire helicopter, 01:03:48.490 --> 01:03:52.220 because a box collider right that goes out here, for example, 01:03:52.220 --> 01:03:54.460 might not be super fair if we're just coming right 01:03:54.460 --> 01:03:56.515 over a building, and our body-- 01:03:59.080 --> 01:04:01.740 maybe the building's right here, and we just miss it. 01:04:01.740 --> 01:04:03.500 We don't want that to be collided with. 01:04:03.500 --> 01:04:05.590 So sometimes you'll need to combine colliders 01:04:05.590 --> 01:04:09.112 to accomplish the collision detection behavior you're looking at. 01:04:09.112 --> 01:04:11.570 The nice thing about box colliders, which we're using here, 01:04:11.570 --> 01:04:14.194 is that they're not very expensive, because they're just boxes. 01:04:14.194 --> 01:04:19.340 It's easy to compute 3D box collision with other things that are 3D boxes. 01:04:19.340 --> 01:04:23.320 And that's actually a topic in its own is, 01:04:23.320 --> 01:04:27.520 taking a complicated model or object, and then breaking it down, 01:04:27.520 --> 01:04:29.920 not in terms of what it looks like to be collided with, 01:04:29.920 --> 01:04:32.890 but how you can simplify the collision detection of something, 01:04:32.890 --> 01:04:38.320 like a character, by just modeling its arms, its body, its legs, as cylinders 01:04:38.320 --> 01:04:42.100 or boxes, rather than complicated geometry. 01:04:42.100 --> 01:04:45.850 You usually don't want to do peer geometry collision for anything, 01:04:45.850 --> 01:04:48.130 because that gets really expensive. 01:04:48.130 --> 01:04:52.510 You want to try and aim for simple shapes to be your colliders. 01:04:52.510 --> 01:04:54.370 And Unity gives you a lot of simple shapes 01:04:54.370 --> 01:04:59.212 by default. If you look at, for example, in our helicopter-- 01:04:59.212 --> 01:05:01.420 if you wanted to add a component-- which, by the way, 01:05:01.420 --> 01:05:05.170 you can easily do here, just in the component inspector. 01:05:05.170 --> 01:05:08.290 If you're looking at the bottom right, there's an Add Component button. 01:05:08.290 --> 01:05:12.020 So you can add any of the components that you've written, 01:05:12.020 --> 01:05:15.050 and also all the components that Unity gives you by default. 01:05:15.050 --> 01:05:16.851 So if we look at it by collider, we can see 01:05:16.851 --> 01:05:19.600 there's a lot of different colliders that Unity gives us for free. 01:05:19.600 --> 01:05:25.810 Polygon collider, mesh collider, box collider, capsule collider. 01:05:25.810 --> 01:05:28.540 I try and strive for boxes as much as I can. 01:05:28.540 --> 01:05:29.470 Spheres aren't bad. 01:05:29.470 --> 01:05:31.750 Spheres are usually fairly easy to calculate, as well. 01:05:31.750 --> 01:05:33.730 But boxes are the easiest. 01:05:33.730 --> 01:05:35.770 Capsules are pretty easy, too. 01:05:35.770 --> 01:05:39.220 A lot of players will be capsule colliders, because characters usually 01:05:39.220 --> 01:05:40.270 have rounded heads. 01:05:40.270 --> 01:05:45.142 So emulating the collision for their head with a capsule makes more sense. 01:05:45.142 --> 01:05:48.100 And we'll look at that, actually, next week, when we use a first-person 01:05:48.100 --> 01:05:49.810 component that we can get for free. 01:05:49.810 --> 01:05:55.180 The default collider for it is a capsule. 01:05:55.180 --> 01:06:02.950 But the blades and the body both have their own collider. 01:06:02.950 --> 01:06:04.360 They're not triggers. 01:06:04.360 --> 01:06:08.050 But if we look at our prefabs-- 01:06:08.050 --> 01:06:10.900 which we'll take a look at what a prefab is shortly-- 01:06:10.900 --> 01:06:16.240 a skyscraper has a box collider which is a trigger, as we can see here. 01:06:16.240 --> 01:06:18.340 And the coin is a trigger. 01:06:18.340 --> 01:06:20.710 And the airplane is a trigger. 01:06:20.710 --> 01:06:27.800 So these things all trigger, except other colliders that aren't triggers. 01:06:27.800 --> 01:06:30.940 And if it detects a collision with a collider that's not a trigger, 01:06:30.940 --> 01:06:33.923 it will call the OnTriggerEnter function, 01:06:33.923 --> 01:06:36.506 which we saw is something that you can get with MonoBehaviour. 01:06:36.506 --> 01:06:37.438 Yeah. 01:06:37.438 --> 01:06:41.163 AUDIENCE: Could you have two values if you want to call the special 01:06:41.163 --> 01:06:44.931 function two at the same time, you'd have the regular [INAUDIBLE].. 01:06:44.931 --> 01:06:47.456 Is there an easier way to do that? 01:06:47.456 --> 01:06:49.497 COLTON OGDEN: Can you give me a specific example? 01:06:49.497 --> 01:06:53.473 AUDIENCE: Well, if I want to have a pinball game or something, 01:06:53.473 --> 01:06:58.443 I'd want to model functioning when my ball hits something. 01:06:58.443 --> 01:07:01.440 But at the same time, I just don't it to bounce off of stuff. 01:07:01.440 --> 01:07:02.398 COLTON OGDEN: Oh, yeah. 01:07:02.398 --> 01:07:03.910 AUDIENCE: So you could do that? 01:07:03.910 --> 01:07:09.674 COLTON OGDEN: So the question was, can I implement such that, for example, 01:07:09.674 --> 01:07:12.340 in a pinball game, if I have a ball that collides with something 01:07:12.340 --> 01:07:15.994 and causes a trigger to occur, but also have it bounce off of something. 01:07:15.994 --> 01:07:17.660 And you would do that with a rigid body. 01:07:17.660 --> 01:07:19.330 So you give it a rigid body. 01:07:19.330 --> 01:07:23.110 In this case, I actually gave a rigid body to the helicopter 01:07:23.110 --> 01:07:26.699 because the original goal of mine was to have it be affected by gravity. 01:07:26.699 --> 01:07:29.990 But it turned out that I actually liked it a little bit better without gravity. 01:07:29.990 --> 01:07:32.200 So this rigid body isn't strictly necessary. 01:07:32.200 --> 01:07:34.720 But it has a gravity component that you can 01:07:34.720 --> 01:07:39.640 assign to it that will actually, then, calculate gravity, and pull it 01:07:39.640 --> 01:07:44.350 down wherever-- you have a global gravity definition that's 01:07:44.350 --> 01:07:47.810 in your Unity settings that will affect it that way. 01:07:47.810 --> 01:07:51.066 And so what you would do is, you would give your ball a rigid body. 01:07:51.066 --> 01:07:53.440 And other things that you want it to bounce off of those, 01:07:53.440 --> 01:07:55.450 those also have rigid bodies. 01:07:55.450 --> 01:07:59.532 And they can be kinematic or not, basically, 01:07:59.532 --> 01:08:00.740 which we talked about before. 01:08:00.740 --> 01:08:05.990 Kinematic can move, but not be affected by other objects. 01:08:05.990 --> 01:08:10.495 And so the object that's a trigger, you still trigger code, it does something. 01:08:10.495 --> 01:08:12.870 So your pinball machine, when it collides with something, 01:08:12.870 --> 01:08:17.054 and it triggers that thing, it'll still trigger that code. 01:08:17.054 --> 01:08:19.470 So whether that's increment your score, or cause something 01:08:19.470 --> 01:08:22.259 to flash, a part of it will flash, or play a sound, 01:08:22.259 --> 01:08:23.800 it'll do that in your OnTriggerEnter. 01:08:23.800 --> 01:08:26.640 But your rigid body will also perform its work, 01:08:26.640 --> 01:08:28.890 and bounce off of whatever it-- 01:08:28.890 --> 01:08:32.729 assuming that you don't destroy it with that OnTriggerEnter function, 01:08:32.729 --> 01:08:35.520 it will bounce off of that surface, and behave in the way 01:08:35.520 --> 01:08:37.450 that you are alluding to. 01:08:37.450 --> 01:08:40.130 Does that make sense? 01:08:40.130 --> 01:08:41.298 All right. 01:08:41.298 --> 01:08:41.798 Cool. 01:08:44.810 --> 01:08:47.540 So all these things have triggers. 01:08:47.540 --> 01:08:49.719 The IsTrigger flag-- 01:08:49.719 --> 01:08:51.510 I mean, that's as easy as we need it to be. 01:08:51.510 --> 01:08:52.939 So you just give a box collider. 01:08:52.939 --> 01:08:54.950 And the nice thing about box collider, too, 01:08:54.950 --> 01:09:00.020 is if your mesh is a box, or square, or rectangular, 01:09:00.020 --> 01:09:04.686 it will usually just fit it perfectly to whatever you're trying to assign it to. 01:09:04.686 --> 01:09:07.810 So in this case, I remember adding the box colliders for these skyscrapers. 01:09:07.810 --> 01:09:12.050 It just-- because they're all rectangular, or cubical-- 01:09:12.050 --> 01:09:12.649 I don't know. 01:09:12.649 --> 01:09:14.060 What's the rectangular 3D? 01:09:14.060 --> 01:09:15.780 I forget the term. 01:09:15.780 --> 01:09:16.279 What is it? 01:09:16.279 --> 01:09:17.479 AUDIENCE: Rectangular prism. 01:09:17.479 --> 01:09:19.020 COLTON OGDEN: Rectangular prism, yes. 01:09:19.020 --> 01:09:23.000 Because they're all rectangular prisms, the box collector fits them. 01:09:23.000 --> 01:09:25.310 It'll scale the right way. 01:09:25.310 --> 01:09:27.950 When you have differently weird shaped objects, 01:09:27.950 --> 01:09:30.229 it'll just basically be as big as it needs 01:09:30.229 --> 01:09:32.960 to be to completely encapsulate it. 01:09:32.960 --> 01:09:37.460 But like I said before, because the helicopter has got some weird geometry, 01:09:37.460 --> 01:09:41.090 if we were to do that, it would by default just be this entire box here, 01:09:41.090 --> 01:09:45.470 because this is the farthest it goes out on this particular axis. 01:09:45.470 --> 01:09:50.870 So we want to combine meshes to produce the collision 01:09:50.870 --> 01:09:52.310 behavior that we're looking for. 01:09:52.310 --> 01:10:02.090 And the trigger enter bit is relevant because, if your game object is 01:10:02.090 --> 01:10:09.560 a trigger, then once we collide with that object, 01:10:09.560 --> 01:10:11.920 we want-- and by default, when you do OnTriggerEnter, 01:10:11.920 --> 01:10:15.830 it will look for the collider on this object. 01:10:15.830 --> 01:10:18.630 It's going to take in a collider other, right? 01:10:18.630 --> 01:10:21.950 And what that is is the other collider-- the thing 01:10:21.950 --> 01:10:24.650 that's colliding with this object, with this coin. 01:10:24.650 --> 01:10:27.680 So the helicopter, because it's the only other object in our scene 01:10:27.680 --> 01:10:31.267 that has a non-trigger collider. 01:10:31.267 --> 01:10:33.350 OnTriggerEnter-- this is going to be a helicopter. 01:10:33.350 --> 01:10:38.480 We can just say other.transform.parent, because our helicopter has children, 01:10:38.480 --> 01:10:42.200 which have the actual colliders, and a parent has the helicopter controller 01:10:42.200 --> 01:10:43.060 component. 01:10:43.060 --> 01:10:47.460 We're going to GetComponent the HeliController. 01:10:47.460 --> 01:10:50.254 So we're going to go through our that objects, that other 01:10:50.254 --> 01:10:51.170 that collided with us. 01:10:51.170 --> 01:10:54.182 We're going to get its transform parent. 01:10:54.182 --> 01:10:57.140 We're going to do GetComponent, which is a function that will just look 01:10:57.140 --> 01:10:59.360 through all of its list of components. 01:10:59.360 --> 01:11:03.770 We specify which component we want using this identifier here. 01:11:03.770 --> 01:11:06.050 So of class HeliController. 01:11:06.050 --> 01:11:16.130 And these angle brackets are the generic type specifier 01:11:16.130 --> 01:11:17.930 syntax, which basically looks for it. 01:11:17.930 --> 01:11:20.780 You could pass in any type here, effectively, 01:11:20.780 --> 01:11:23.210 and GetComponent will look at whatever type is in here, 01:11:23.210 --> 01:11:25.850 and get the component of that type, specifically. 01:11:25.850 --> 01:11:29.750 So you do have some sort of type flexibility in C#, 01:11:29.750 --> 01:11:32.330 but you have to go the extra mile and specify it, 01:11:32.330 --> 01:11:35.840 and implement functions that take generic arguments like this. 01:11:35.840 --> 01:11:41.430 Which is similar to Java, and C++, and other languages that do it that way. 01:11:41.430 --> 01:11:45.590 And then once we've gotten that component of type HeliController, 01:11:45.590 --> 01:11:50.010 with this function call, we execute PickupCoin, 01:11:50.010 --> 01:11:53.390 which is a function that's part of the HeliController. 01:11:53.390 --> 01:11:55.110 Any guesses as to what PickupCoin does? 01:11:59.574 --> 01:12:00.570 AUDIENCE: [INAUDIBLE] 01:12:00.570 --> 01:12:01.278 COLTON OGDEN: Sorry? 01:12:01.278 --> 01:12:04.180 AUDIENCE: Increments the coin counter and tells the coin to disappear. 01:12:04.180 --> 01:12:06.470 COLTON OGDEN: Increments the coin counter, calls the coin to disappear. 01:12:06.470 --> 01:12:09.910 Well, it actually doesn't call the coin to disappear, because we do that here. 01:12:09.910 --> 01:12:10.710 AUDIENCE: Oh. 01:12:10.710 --> 01:12:13.510 COLTON OGDEN: Destroy game object-- 01:12:13.510 --> 01:12:17.284 game object is going to be this coin that's executing this function. 01:12:17.284 --> 01:12:18.450 There's one more thing, too. 01:12:18.450 --> 01:12:21.120 Do you remember what happens when we pick up a coin? 01:12:21.120 --> 01:12:21.620 Exactly. 01:12:21.620 --> 01:12:22.280 The particle effect. 01:12:22.280 --> 01:12:23.530 It triggers a particle effect. 01:12:23.530 --> 01:12:28.060 We can go to the HeliController class and take a look at that. 01:12:28.060 --> 01:12:28.840 PickupCoin. 01:12:31.540 --> 01:12:33.730 Here, coinTotal plus equals 1. 01:12:33.730 --> 01:12:37.851 GetComponent AudioSource. 01:12:37.851 --> 01:12:38.350 Play. 01:12:38.350 --> 01:12:39.860 So it's a little bit weird. 01:12:39.860 --> 01:12:44.150 So with audio source, you can have multiple audio files. 01:12:44.150 --> 01:12:48.160 So GetComponents AudioSource is what we need to actually get 01:12:48.160 --> 01:12:49.970 the audio attached to this object. 01:12:49.970 --> 01:12:51.400 And at index 0-- 01:12:51.400 --> 01:12:54.400 because there's only going to be one audio source anyway. 01:12:54.400 --> 01:12:58.510 And then we just call Play, so that'll play the coin sound. 01:12:58.510 --> 01:13:00.430 And then GetComponent, because there's only 01:13:00.430 --> 01:13:04.944 going to be one particle system associated with this helicopter object. 01:13:04.944 --> 01:13:06.860 We're going to get the particle system object. 01:13:06.860 --> 01:13:09.985 And then we're just going to call Play on that, which will actually trigger 01:13:09.985 --> 01:13:14.830 an emission one time of its particles. 01:13:14.830 --> 01:13:18.100 That's in a nutshell what colliders and triggers are. 01:13:18.100 --> 01:13:22.780 It's a lot of syntax at once, because Unity is really big. 01:13:22.780 --> 01:13:25.030 But it's pretty simple. 01:13:25.030 --> 01:13:27.940 Just make sure that you give the right shapes to your objects. 01:13:27.940 --> 01:13:29.950 Make the right things triggers that you want 01:13:29.950 --> 01:13:34.930 to cause behavior to happen when non-trigger things touch them. 01:13:34.930 --> 01:13:38.440 And then implement OnTriggerEnter with the behavior-- the game logic-- 01:13:38.440 --> 01:13:39.880 that you need. 01:13:39.880 --> 01:13:43.270 In the case of the skyscraper, for example, if we look at the skyscraper. 01:13:43.270 --> 01:13:45.890 So I have a skyscraper component here. 01:13:45.890 --> 01:13:49.990 And then if I OnTriggerEnter here, it effectively 01:13:49.990 --> 01:13:53.890 does the same thing that the airplane does, 01:13:53.890 --> 01:14:00.500 which is just go through the others, transform parent game object, 01:14:00.500 --> 01:14:03.350 HeliController, and then call Explode. 01:14:03.350 --> 01:14:06.890 And so Explode-- similar thing to what PickupCoin does, 01:14:06.890 --> 01:14:08.950 and it triggers a particle effect. 01:14:08.950 --> 01:14:14.200 But it also destroys the helicopter, and it tweaks the Game Over text 01:14:14.200 --> 01:14:16.850 to turn on at that point. 01:14:16.850 --> 01:14:20.794 So any questions as to how triggers work, or any of the syntax we've 01:14:20.794 --> 01:14:21.710 talked about thus far? 01:14:21.710 --> 01:14:24.010 I know that it's a lot. 01:14:24.010 --> 01:14:25.330 It's kind of a fast tour. 01:14:25.330 --> 01:14:30.130 But moving right along. 01:14:30.130 --> 01:14:30.910 All right. 01:14:30.910 --> 01:14:34.240 Oh, and here's a screenshot I took just to illustrate the green lines-- 01:14:34.240 --> 01:14:40.690 the box-- and then the orange is the actual mesh of the helicopter. 01:14:40.690 --> 01:14:41.975 So we're going take a break. 01:14:41.975 --> 01:14:44.350 And then when we get back, we're gonna talk about prefabs 01:14:44.350 --> 01:14:47.350 and spawning them, and dive a little bit deeper 01:14:47.350 --> 01:14:49.821 into some of the other parts of the project. 01:14:49.821 --> 01:14:50.320 All right. 01:14:50.320 --> 01:14:52.090 Welcome back to GD50 Lecture 8. 01:14:52.090 --> 01:14:53.560 This is Helicopter Game 3D. 01:14:53.560 --> 01:14:57.130 So before the break, we were talking about colliders and triggers, 01:14:57.130 --> 01:15:01.930 and also just getting our hands used to using MonoBehaviours, and the editor, 01:15:01.930 --> 01:15:03.610 and all sorts of things. 01:15:03.610 --> 01:15:05.680 But we haven't really taken a look at prefabs, 01:15:05.680 --> 01:15:08.260 which is a major part of this game. 01:15:08.260 --> 01:15:12.040 So the coins, the skyscrapers, the airplanes-- 01:15:12.040 --> 01:15:16.810 those are all prefabricated assets that we have gotten 01:15:16.810 --> 01:15:19.670 ready for spawning into our scene. 01:15:19.670 --> 01:15:22.730 And we're going to take a look at how that actually works. 01:15:22.730 --> 01:15:24.670 So here's a list of-- 01:15:24.670 --> 01:15:27.310 in our editor view-- all the different prefabs that we have. 01:15:27.310 --> 01:15:31.960 So we can see airplane, blades, and body are prefabs. 01:15:31.960 --> 01:15:33.812 The coin, all the skyscrapers. 01:15:33.812 --> 01:15:35.770 There are three different kinds of skyscrapers. 01:15:35.770 --> 01:15:37.227 And then the helicopter. 01:15:37.227 --> 01:15:39.310 The helicopter itself we're not using as a prefab, 01:15:39.310 --> 01:15:40.870 because I've already created it in the scene, 01:15:40.870 --> 01:15:42.670 and it never gets instantiated dynamically. 01:15:42.670 --> 01:15:45.910 But we could easily make it so, because I have 01:15:45.910 --> 01:15:49.990 created a prefab with the helicopter. 01:15:49.990 --> 01:15:53.290 So when we're looking at the scene here, we 01:15:53.290 --> 01:15:57.350 notice that we have just the helicopter, and we have the background. 01:15:57.350 --> 01:16:01.790 But there's no skyscrapers, there's no coins, and there's no airplanes. 01:16:01.790 --> 01:16:07.170 Well, we do have our skyscraper spawner, the coin spawner, and the airplane 01:16:07.170 --> 01:16:07.840 spawner. 01:16:07.840 --> 01:16:10.570 And the three of those are just empty game objects, 01:16:10.570 --> 01:16:13.450 but they have associated with them these spawner scripts. 01:16:13.450 --> 01:16:16.120 And the spawner scripts, we've written ourself. 01:16:16.120 --> 01:16:19.580 And then, once we've written them, we just simply add component here, 01:16:19.580 --> 01:16:22.450 and then chosen the appropriate spawner. 01:16:22.450 --> 01:16:24.040 And so what those do-- 01:16:24.040 --> 01:16:28.450 if we look in our code actually, and we go, for example, to the airplane 01:16:28.450 --> 01:16:33.520 spawner, we have a Start method. 01:16:33.520 --> 01:16:34.610 We have an Update method. 01:16:34.610 --> 01:16:38.140 Notice that the Update method doesn't do anything, paradoxically, 01:16:38.140 --> 01:16:42.040 because the airplane spawner is running over time. 01:16:42.040 --> 01:16:45.100 We are spawning airplanes over time. 01:16:45.100 --> 01:16:48.430 But the way that we do things over time asynchronously in Unity 01:16:48.430 --> 01:16:51.470 is a little bit different than anything that we've done so far. 01:16:51.470 --> 01:16:54.910 So this Start method here, we see that we're calling 01:16:54.910 --> 01:16:57.400 this function called StartCoroutine. 01:16:57.400 --> 01:17:01.330 And that function takes in a function called SpawnAirplanes. 01:17:01.330 --> 01:17:06.460 And so at a high level, a coroutine is effectively a function 01:17:06.460 --> 01:17:09.850 that yields control every time it's called. 01:17:09.850 --> 01:17:15.310 So it'll run, and then, rather than go through its entire body of code, 01:17:15.310 --> 01:17:19.180 and then end or return some value, and have that just be the end of it, 01:17:19.180 --> 01:17:25.720 it'll actually yield, when you use the keyword Yield. 01:17:25.720 --> 01:17:30.160 And depending on what you've done with that Yield, 01:17:30.160 --> 01:17:34.660 it'll pause for some length of time, or do something for some length of time, 01:17:34.660 --> 01:17:37.130 rather than end that function call. 01:17:37.130 --> 01:17:39.310 So this SpawnAirplanes function here-- 01:17:39.310 --> 01:17:41.770 notice that it has a while true. 01:17:41.770 --> 01:17:45.550 And so while true is not usually something that you want in a game, 01:17:45.550 --> 01:17:49.480 because that's just going to lock your game forever. 01:17:49.480 --> 01:17:54.760 But in the case of a coroutine, a coroutine is going to run, 01:17:54.760 --> 01:17:56.680 but then it's going to yield control back 01:17:56.680 --> 01:17:58.600 to whatever called it for some length of time, 01:17:58.600 --> 01:18:00.940 or depending on how we've programmed it. 01:18:00.940 --> 01:18:02.500 In this case, you can see here-- 01:18:02.500 --> 01:18:07.270 yield return new WaitForSeconds Random.Range 3, 10. 01:18:07.270 --> 01:18:10.270 Does anybody have an idea of what that does? 01:18:10.270 --> 01:18:10.770 Yeah. 01:18:10.770 --> 01:18:15.650 AUDIENCE: The logic [INAUDIBLE] waits for between 3 and 10 seconds, 01:18:15.650 --> 01:18:16.600 and continues. 01:18:16.600 --> 01:18:19.050 COLTON OGDEN: It does. 01:18:19.050 --> 01:18:22.660 It yields for 3 to 10 seconds, and then continues its execution. 01:18:22.660 --> 01:18:23.605 That's exactly right. 01:18:23.605 --> 01:18:24.760 Did you have a question? 01:18:24.760 --> 01:18:27.984 AUDIENCE: I was thinking, why do you have three different skyscrapers set 01:18:27.984 --> 01:18:28.484 up? 01:18:28.484 --> 01:18:32.177 Couldn't you just have one skyscraper and change [INAUDIBLE]?? 01:18:32.177 --> 01:18:33.510 COLTON OGDEN: You could do that. 01:18:33.510 --> 01:18:34.129 Yeah. 01:18:34.129 --> 01:18:36.045 I guess for the sake of demonstrating prefabs. 01:18:36.045 --> 01:18:38.503 And also, it's a little bit complex more complicated to get 01:18:38.503 --> 01:18:42.981 into dynamic material setting, and changing materials in code. 01:18:42.981 --> 01:18:43.480 But yeah. 01:18:43.480 --> 01:18:50.230 You could effectively just create one skyscraper with one base color, 01:18:50.230 --> 01:18:56.570 and then dynamically change its material. 01:18:56.570 --> 01:18:59.885 But also to illustrate having multiple different prefabs 01:18:59.885 --> 01:19:02.260 assigned to an object, that you can then choose at random 01:19:02.260 --> 01:19:03.510 to generate in the game scene. 01:19:03.510 --> 01:19:05.600 They might not necessarily be skyscrapers 01:19:05.600 --> 01:19:07.100 that will have the exact same color. 01:19:07.100 --> 01:19:12.770 It could be a goblin, or a orc, or a troll, or something. 01:19:12.770 --> 01:19:15.290 And they're all different prefabs that we've created. 01:19:15.290 --> 01:19:18.220 But you can put them in a list, and then dynamically choose 01:19:18.220 --> 01:19:20.305 which one we want at random. 01:19:20.305 --> 01:19:21.430 So a few different reasons. 01:19:21.430 --> 01:19:21.929 But yeah. 01:19:21.929 --> 01:19:25.027 In a situation where everything is just effectively differentiated 01:19:25.027 --> 01:19:26.860 by a single color and a material change, you 01:19:26.860 --> 01:19:29.020 could dynamically swap that as needed. 01:19:33.610 --> 01:19:36.730 This code routine that we've started-- this function that 01:19:36.730 --> 01:19:42.400 effectively can pause itself, even though it's being called while true 01:19:42.400 --> 01:19:45.170 is in play. 01:19:45.170 --> 01:19:47.290 It yields control with this Yield keyword. 01:19:47.290 --> 01:19:51.100 And what it does is, it allows us to call something over and over again, 01:19:51.100 --> 01:19:53.300 but then pause for some length of time. 01:19:53.300 --> 01:19:53.800 Right? 01:19:53.800 --> 01:19:57.201 We don't have to maintain a counter for spawn time in here. 01:19:57.201 --> 01:19:57.950 Which we could do. 01:19:57.950 --> 01:20:01.690 We could do float spawn time equals 0, right? 01:20:01.690 --> 01:20:06.880 And then float spawn increment equals like 1,000. 01:20:06.880 --> 01:20:13.000 And then while spawn time is less than spawn increment-- 01:20:13.000 --> 01:20:16.450 we could say in Update, if spawn increment. 01:20:16.450 --> 01:20:20.389 Or we would do spawn time plus equals time.delta time first, 01:20:20.389 --> 01:20:22.930 to get the length of time that's passed since the last frame. 01:20:22.930 --> 01:20:26.170 And then we would say, if spawn time is greater 01:20:26.170 --> 01:20:32.260 than spawn increment, instantiate a new airplane. 01:20:32.260 --> 01:20:37.120 And then set spawn time back to 0. 01:20:37.120 --> 01:20:40.430 And then just rinse and repeat this over and over again. 01:20:40.430 --> 01:20:44.470 But coroutines take out this need, much like timer 01:20:44.470 --> 01:20:49.000 did, for having anything that you keep track of with a specific timer. 01:20:49.000 --> 01:20:51.550 You can do a whole bunch of different things with coroutines. 01:20:51.550 --> 01:20:53.341 One of them, in this case that we're doing, 01:20:53.341 --> 01:20:57.850 is just pausing for some length of time to do something. 01:20:57.850 --> 01:21:00.160 In this case, we want to wait for some time 01:21:00.160 --> 01:21:07.000 in between each instantiation of an airplane. 01:21:07.000 --> 01:21:10.850 So we'll just yield control back to our game, 01:21:10.850 --> 01:21:12.850 because we want to break out of this while true. 01:21:12.850 --> 01:21:16.141 But we don't want to break out of it and completely break out of this function. 01:21:16.141 --> 01:21:19.930 We want this to keep going over and over again. 01:21:19.930 --> 01:21:23.500 So we see here, this Instantiate function is 01:21:23.500 --> 01:21:25.540 where the actual instantiation happens. 01:21:25.540 --> 01:21:29.500 And Instantiate takes in a prefab-- 01:21:29.500 --> 01:21:30.900 so a game object. 01:21:30.900 --> 01:21:35.350 So in this case, we have a prefabs list here. 01:21:35.350 --> 01:21:39.259 GameObject public, GameObject array called prefabs. 01:21:39.259 --> 01:21:41.800 So this can take in any number of prefabs that we want it to. 01:21:44.380 --> 01:21:48.700 We're going to return a range between 0 and length. 01:21:48.700 --> 01:21:52.992 And then also, we want it to spawn. 01:21:52.992 --> 01:21:54.950 We give it a position that we want to spawn in. 01:21:54.950 --> 01:21:58.480 So Instantiate-- it takes in an object, it takes in a position, 01:21:58.480 --> 01:21:59.890 and it takes in a rotation. 01:21:59.890 --> 01:22:02.710 In this case, we want to give it this position. 01:22:02.710 --> 01:22:03.840 So it's a Vector3-- 01:22:03.840 --> 01:22:05.740 it's an x, y, and a z-- 01:22:05.740 --> 01:22:06.460 at 26. 01:22:06.460 --> 01:22:09.580 So off the right edge of the screen 7 to 10. 01:22:09.580 --> 01:22:14.140 So within a range of verticality up towards the top. 01:22:14.140 --> 01:22:17.920 And then at 11 on the z-axis, which is aligned with our helicopter 01:22:17.920 --> 01:22:21.280 and the skyscrapers. 01:22:21.280 --> 01:22:25.300 And then this Quaternion.Euler-- 01:22:25.300 --> 01:22:30.230 so 3D rotation, the math behind it is pretty complex. 01:22:30.230 --> 01:22:32.000 And I don't know it well at all. 01:22:32.000 --> 01:22:35.700 But Quaternion.Euler allows us to think in degrees, 01:22:35.700 --> 01:22:40.130 and actually perform a 3D rotation on something fairly easily. 01:22:40.130 --> 01:22:43.540 So if you want to rotate something in 3D, Quaternion.Euler. 01:22:43.540 --> 01:22:46.980 Negative 90 degrees on the, I believe it's z, x, y. 01:22:46.980 --> 01:22:50.860 In this case, the way that the default rotation of the airplane is, 01:22:50.860 --> 01:22:54.070 we want to set it to negative 90, negative 90, 0. 01:22:54.070 --> 01:22:58.180 You could also set up your prefab in a way such 01:22:58.180 --> 01:23:00.550 that you don't need to pass this in. 01:23:00.550 --> 01:23:03.420 You could do Quaternion.Identity in that case. 01:23:03.420 --> 01:23:06.632 But this is just to illustrate how, if you want to rotate something 01:23:06.632 --> 01:23:07.840 in code, how you would do it. 01:23:07.840 --> 01:23:10.720 So Quaternion.Euler is the way that you rotate something in 3D. 01:23:13.660 --> 01:23:15.957 So Instantiate-- global function that you 01:23:15.957 --> 01:23:18.040 can call anywhere you want to, as long as you just 01:23:18.040 --> 01:23:23.560 give it a actual object or prefab that it knows how to instantiate. 01:23:23.560 --> 01:23:25.700 And then WaitForSeconds-- another global object, 01:23:25.700 --> 01:23:28.120 which is a asynchronous object that will allow 01:23:28.120 --> 01:23:31.630 us to yield for this length of time. 01:23:31.630 --> 01:23:33.302 You pass in the length of time here. 01:23:33.302 --> 01:23:35.260 It takes it in seconds, because WaitForSeconds. 01:23:35.260 --> 01:23:39.610 And then, as soon as this length of time has passed, 01:23:39.610 --> 01:23:42.910 it's going to come back up here into this while true instruction, 01:23:42.910 --> 01:23:44.290 and then instantiate again. 01:23:44.290 --> 01:23:47.950 We don't have to keep track of a time or anything-- any weird boilerplate. 01:23:47.950 --> 01:23:51.290 We just have to call StartCoroutine here. 01:23:51.290 --> 01:23:54.640 And notice that we explicitly have to call StartCoroutine routine in order 01:23:54.640 --> 01:23:58.760 to trigger a coroutine function. 01:23:58.760 --> 01:24:02.410 And to do that, it returns what's called an IEnumerator. 01:24:02.410 --> 01:24:05.570 And so a lot of these details, you don't need to necessarily know 01:24:05.570 --> 01:24:06.760 the low-level details of. 01:24:06.760 --> 01:24:10.120 I certainly don't know all the low-level details of everything 01:24:10.120 --> 01:24:11.560 that happens in Unity. 01:24:11.560 --> 01:24:13.810 But just know if you want asynchronous behavior, 01:24:13.810 --> 01:24:15.730 your function needs to return an IEnumerator, 01:24:15.730 --> 01:24:22.750 which C# knows is a generator function which will yield control 01:24:22.750 --> 01:24:24.910 at predetermined times. 01:24:24.910 --> 01:24:27.250 And it will manage it for you. 01:24:27.250 --> 01:24:29.590 And to trigger it, you need to StartCoroutine, 01:24:29.590 --> 01:24:33.280 which is a function that Unity has defined for you. 01:24:33.280 --> 01:24:38.555 So any questions as to how this works at a high level, at least? 01:24:38.555 --> 01:24:40.888 AUDIENCE: I'm a little confused on the syntax for Yield. 01:24:40.888 --> 01:24:42.390 Does the Yield return-- 01:24:42.390 --> 01:24:44.680 COLTON OGDEN: Yes. 01:24:44.680 --> 01:24:51.670 Yield takes in something, and you get a new to instantiate a new WaitForSecond. 01:24:51.670 --> 01:24:56.451 It's just the way the syntax is for yielding an object. 01:24:56.451 --> 01:24:56.950 Yield-- 01:24:56.950 --> 01:24:58.482 AUDIENCE: What is it returning back? 01:24:58.482 --> 01:25:00.940 COLTON OGDEN: It's returning this to the Yield instruction. 01:25:00.940 --> 01:25:05.260 And the Yield instruction is then yielding that. 01:25:05.260 --> 01:25:06.980 It is a little bit weird, though. 01:25:06.980 --> 01:25:09.970 But you only really have to-- 01:25:09.970 --> 01:25:11.900 this is a common pattern that you'll see. 01:25:11.900 --> 01:25:13.316 And so you'll just get used to it. 01:25:16.360 --> 01:25:20.080 And honestly, this is probably one of the more syntactically difficult things 01:25:20.080 --> 01:25:20.600 about Unity. 01:25:20.600 --> 01:25:22.349 So I mean, as soon as you understand this, 01:25:22.349 --> 01:25:25.840 pretty much anything else is fairly easy at that point. 01:25:25.840 --> 01:25:28.930 I would say this is one of the weirder sides. 01:25:28.930 --> 01:25:32.680 Because in Lua, and Love2D, and those kinds of environments, 01:25:32.680 --> 01:25:37.540 it's a little bit easier to do this sort of thing with as much syntax. 01:25:37.540 --> 01:25:42.400 C#, being a statically-typed environment, to get the same behavior, 01:25:42.400 --> 01:25:46.290 you have to go a little bit further. 01:25:46.290 --> 01:25:48.460 Do things their way. 01:25:48.460 --> 01:25:54.190 But that's getting asynchronous behavior to work in C#. 01:25:54.190 --> 01:26:01.290 And in Unity, typically, in order to avoid messy state management, 01:26:01.290 --> 01:26:06.790 you will use coroutines, which are IEnumerators, often 01:26:06.790 --> 01:26:09.910 with the WaitForSeconds object. 01:26:09.910 --> 01:26:14.290 And just make sure to trigger them with StartCoroutine. 01:26:14.290 --> 01:26:17.115 And then call that function as if it were an object. 01:26:17.115 --> 01:26:17.740 Just like that. 01:26:20.710 --> 01:26:25.960 And the behavior for the airplane spawner, the coin spawner, 01:26:25.960 --> 01:26:27.950 and so forth, they're all fairly similar. 01:26:27.950 --> 01:26:31.330 So StartCoroutine SpawnCoins. 01:26:31.330 --> 01:26:32.560 And then while true. 01:26:32.560 --> 01:26:36.670 So coins-- this row just spawns a random number of coins vertically. 01:26:36.670 --> 01:26:40.387 So you can have one, or you can maybe have a couple. 01:26:40.387 --> 01:26:42.220 And then for each of those, instantiate them 01:26:42.220 --> 01:26:46.330 at a random position on the y-axis. 01:26:46.330 --> 01:26:49.180 Here, random negative 10 to 10. 01:26:49.180 --> 01:26:52.540 In this case, Quaternion.Identity, because we don't want 01:26:52.540 --> 01:26:58.250 to rotate them any differently than they already are, which I alluded to before. 01:26:58.250 --> 01:27:01.350 So Quaternion.Identity just means no rotation applied to the object. 01:27:01.350 --> 01:27:05.510 So whatever its base rotation is as a prefab. 01:27:05.510 --> 01:27:08.000 So it'll be whatever it is when you see it in the editor, 01:27:08.000 --> 01:27:12.270 and when you create a new one, that's going to be its default rotation. 01:27:12.270 --> 01:27:15.230 So basically the equivalent of, don't rotate this by anything. 01:27:18.200 --> 01:27:25.400 And then, same as we saw before, yields a new WaitForSeconds. 01:27:25.400 --> 01:27:29.660 In this case, 1 to 5, so a little bit more frequently than the airplane, 01:27:29.660 --> 01:27:30.230 on average. 01:27:30.230 --> 01:27:31.870 More coins. 01:27:31.870 --> 01:27:37.580 As the airplane, I believe, was 3 to 10, so every 3 to 10 seconds. 01:27:37.580 --> 01:27:39.920 And that's basically that. 01:27:39.920 --> 01:27:44.660 And then we StartCoroutine, just like we did before with the airplane spawner. 01:27:44.660 --> 01:27:47.330 And then lastly, the skyscraper spawner. 01:27:47.330 --> 01:27:52.690 In this case, we only have one coin prefab, 01:27:52.690 --> 01:27:57.230 we only have one airplane prefab, but we have three skyscraper prefabs. 01:27:57.230 --> 01:28:01.070 And so the actual Random.Range here comes into play, 01:28:01.070 --> 01:28:05.010 because that's how we get the different color skyscrapers spawning at random. 01:28:05.010 --> 01:28:07.100 And like I said before, this can be extrapolated 01:28:07.100 --> 01:28:09.016 to whatever sort of game environment you want, 01:28:09.016 --> 01:28:11.120 where you have multiple types of objects that 01:28:11.120 --> 01:28:13.220 are more complicated than just a color swap, 01:28:13.220 --> 01:28:17.180 and you want to choose them at random. 01:28:17.180 --> 01:28:20.000 We're doing all the same things that we did before. 01:28:20.000 --> 01:28:25.850 And also, here, we can see that they have a random chance 01:28:25.850 --> 01:28:30.610 1 in 4, so a 25% chance of increasing the speed. 01:28:30.610 --> 01:28:35.950 So skyscraper spawner actually has-- and this is relevant to the assignment-- 01:28:35.950 --> 01:28:41.570 skyscraper spawner has a float called speed here, which is, by default, 10. 01:28:41.570 --> 01:28:46.460 And this drives the scroll speed of the skyscrapers, the coins, 01:28:46.460 --> 01:28:48.340 and the airplanes. 01:28:48.340 --> 01:28:53.388 And so when we call it static, do we know what that means? 01:28:53.388 --> 01:28:53.888 Yeah? 01:28:53.888 --> 01:29:00.730 AUDIENCE: Well, it's the same for all [INAUDIBLE] objects [INAUDIBLE].. 01:29:00.730 --> 01:29:01.500 COLTON OGDEN: Yes. 01:29:01.500 --> 01:29:07.290 So no matter how many skyscraper spawners we create, 01:29:07.290 --> 01:29:10.410 they're all going to share this field speed, 01:29:10.410 --> 01:29:13.590 and it's always going to be equal to the same amount across all instances. 01:29:13.590 --> 01:29:15.660 So static means that it's part of the class. 01:29:15.660 --> 01:29:18.090 It belongs to the SkyscraperSpawner class. 01:29:18.090 --> 01:29:21.390 It does not belong to a SkyscraperSpawner object. 01:29:21.390 --> 01:29:26.340 And so we don't ever really want to change that ourselves in this game. 01:29:26.340 --> 01:29:32.740 But the airplane, for example, notice that in our Update function 01:29:32.740 --> 01:29:37.360 here, if the transform.position.x is less than negative 25, 01:29:37.360 --> 01:29:38.740 we should destroy the airplane. 01:29:38.740 --> 01:29:41.180 So when it goes off screen, we should destroy it. 01:29:41.180 --> 01:29:47.110 But if not, then we want to translate this object 01:29:47.110 --> 01:29:52.780 on the x-axis by negative SkyscraperSpawner.speed times 2 times 01:29:52.780 --> 01:29:54.610 Time.deltaTime. 01:29:54.610 --> 01:29:57.040 So we're translating it on the x-axis, and we're 01:29:57.040 --> 01:30:00.940 using the SkyscraperSpawner.speed as our core multiplier. 01:30:00.940 --> 01:30:03.850 And then if we look at coin-- 01:30:03.850 --> 01:30:04.480 same thing. 01:30:08.740 --> 01:30:11.350 I should ask, what is one design consideration 01:30:11.350 --> 01:30:12.610 if we're looking at this-- 01:30:12.610 --> 01:30:13.840 all these components? 01:30:13.840 --> 01:30:17.380 And let's say we're trying to get as decoupled as we 01:30:17.380 --> 01:30:19.580 can, and well-engineered as we can. 01:30:19.580 --> 01:30:23.110 What is a consideration that we can, noticing that, for example, 01:30:23.110 --> 01:30:29.135 this exists in coin, and this exists in airplane? 01:30:33.750 --> 01:30:35.250 AUDIENCE: What's the question again? 01:30:35.250 --> 01:30:37.374 COLTON OGDEN: So how could we better engineer this? 01:30:37.374 --> 01:30:39.120 Notice that we have-- 01:30:39.120 --> 01:30:43.290 and taking into consideration this component model in Unity-- 01:30:43.290 --> 01:30:45.738 what could we do with, for example, this? 01:30:45.738 --> 01:30:50.420 AUDIENCE: So that Unity better [INAUDIBLE].. 01:30:50.420 --> 01:30:53.640 COLTON OGDEN: Well, I'm thinking that, because the airplane and the coin-- 01:30:53.640 --> 01:30:55.890 well, first of all, it wouldn't belong in the spawner, 01:30:55.890 --> 01:30:58.230 because the spawner's job is to spawn coins. 01:30:58.230 --> 01:31:00.980 But the coins and the airplanes-- they have their behavior, right? 01:31:00.980 --> 01:31:03.320 They have their update behavior. 01:31:03.320 --> 01:31:06.800 But they're all doing kind of the same thing, which is scrolling to the left, 01:31:06.800 --> 01:31:09.330 and then de-spawning at negative 25. 01:31:09.330 --> 01:31:13.940 So a design consideration here would be, maybe we have a scroll component, 01:31:13.940 --> 01:31:15.395 right? 01:31:15.395 --> 01:31:17.300 Or a scroll and destroy component. 01:31:17.300 --> 01:31:20.697 Or just a scroll component with an optional destroy flag. 01:31:20.697 --> 01:31:23.780 And then we just put this on anything that we want to automatically scroll 01:31:23.780 --> 01:31:25.904 to the left screen and de-spawn, rather than having 01:31:25.904 --> 01:31:28.530 to code this in every single class. 01:31:28.530 --> 01:31:30.800 So if you're ever looking through your code, 01:31:30.800 --> 01:31:39.410 and you're seeing, for example, this and this being the exact same, especially 01:31:39.410 --> 01:31:42.560 in Unity, because of how flexible components are, 01:31:42.560 --> 01:31:46.340 try and think about how you can make it into its own component. 01:31:46.340 --> 01:31:48.800 AUDIENCE: So where would you put the coins [INAUDIBLE]?? 01:31:48.800 --> 01:31:50.258 COLTON OGDEN: You make it yourself. 01:31:50.258 --> 01:31:53.210 So if we went into here, into our Scripts thing, and just 01:31:53.210 --> 01:31:56.870 made a new script. 01:31:56.870 --> 01:31:59.600 And then we called it Scrollable. 01:31:59.600 --> 01:32:02.720 And then we double-click it, it'll open up in our editor 01:32:02.720 --> 01:32:04.434 that we've chosen in our preferences. 01:32:04.434 --> 01:32:07.100 By default, it's going be Visual Studio with the newer versions. 01:32:07.100 --> 01:32:09.320 But now we have a new scrollable behavior. 01:32:09.320 --> 01:32:10.580 And then all we need to do-- 01:32:10.580 --> 01:32:12.470 we would say, oops-- 01:32:12.470 --> 01:32:13.970 not that. 01:32:13.970 --> 01:32:17.360 If-- once again, I can't type. 01:32:17.360 --> 01:32:23.150 Transform.position.x is less than negative 25, 01:32:23.150 --> 01:32:25.850 destroy game object, right? 01:32:25.850 --> 01:32:30.510 And so this is the exact same thing as all that behavior that we saw before. 01:32:30.510 --> 01:32:35.120 So now we can take all of that out of coin-- 01:32:35.120 --> 01:32:38.450 we can take this out, and we can take this out here, and then 01:32:38.450 --> 01:32:42.710 just add to the airplane and to the coin prefabs, 01:32:42.710 --> 01:32:44.600 we'd just add this new Scrollable prefab, 01:32:44.600 --> 01:32:45.680 and it'll take care of that for us. 01:32:45.680 --> 01:32:46.180 Yeah. 01:32:46.180 --> 01:32:48.330 AUDIENCE: How would you add that? 01:32:48.330 --> 01:32:50.330 COLTON OGDEN: So if we're going back to Unity-- 01:32:50.330 --> 01:32:54.230 so the question is, how would you add the component to the prefab? 01:32:54.230 --> 01:32:57.410 So in our prefabs, note that we have airplane, we have coin, 01:32:57.410 --> 01:32:58.940 and we have all the skyscrapers. 01:32:58.940 --> 01:33:00.169 So these are all prefabs. 01:33:00.169 --> 01:33:02.210 Oh, and I haven't actually detailed how to create 01:33:02.210 --> 01:33:04.700 a prefab, which I apologize for. 01:33:04.700 --> 01:33:08.429 So a prefab-- all you need to do is create an object in your scene. 01:33:08.429 --> 01:33:10.220 For example, I did it with this helicopter. 01:33:10.220 --> 01:33:13.700 So I'm going to delete the helicopter, because this is just the helicopter 01:33:13.700 --> 01:33:14.240 prefab. 01:33:14.240 --> 01:33:17.660 It's not going to actually delete the helicopter from our scene. 01:33:17.660 --> 01:33:24.796 But if I take this helicopter here, and then I drag it in here, 01:33:24.796 --> 01:33:29.720 notice that now we have a prefab here. 01:33:29.720 --> 01:33:33.120 We could take this helicopter out, and just add a new one right there. 01:33:33.120 --> 01:33:36.490 So now I have two helicopters. 01:33:36.490 --> 01:33:37.700 That's all a prefab is. 01:33:37.700 --> 01:33:40.070 It's just something that you've made in your scene 01:33:40.070 --> 01:33:44.780 that you want to replicate or duplicate in the future, ideally through code. 01:33:44.780 --> 01:33:50.870 And notice it's showing here in our hierarchy view. 01:33:50.870 --> 01:33:53.780 But obviously you don't want that. 01:33:53.780 --> 01:33:57.290 But that's how you create a prefab is, you find something 01:33:57.290 --> 01:34:01.850 that you've configured in your game scene, and then in your code, 01:34:01.850 --> 01:34:04.220 you're allowed to then instantiate that prefab, 01:34:04.220 --> 01:34:10.400 assuming that you've made that prefab a member of whatever class 01:34:10.400 --> 01:34:11.210 instantiates it. 01:34:11.210 --> 01:34:13.940 So in this case, the airplane spawner. 01:34:13.940 --> 01:34:18.430 So notice that we call Instantiate here, like we saw, before on line 24. 01:34:18.430 --> 01:34:21.130 But it's looking at prefabs. 01:34:21.130 --> 01:34:24.980 It's a list, and it's looking at a random range between 0 01:34:24.980 --> 01:34:27.560 and the length of the prefabs. 01:34:27.560 --> 01:34:31.280 You have to declare a public GameObject list prefabs here. 01:34:31.280 --> 01:34:35.330 And then, once we do that, and we go to our airplane spawner here, 01:34:35.330 --> 01:34:38.300 notice that we have this prefabs list here. 01:34:38.300 --> 01:34:44.450 So we actually get a editor view of that code, that data structure. 01:34:44.450 --> 01:34:48.770 And we can just add prefabs that we want to. 01:34:48.770 --> 01:34:54.560 And if we change the size to 2, then we can add a second prefab. 01:34:54.560 --> 01:34:59.360 Or if we make the size 10, then we can put 10 different airplanes there. 01:34:59.360 --> 01:35:02.800 But we only have one airplane that I modeled, so I was going to make it 1. 01:35:02.800 --> 01:35:05.480 But this is the same thing. 01:35:05.480 --> 01:35:08.720 This GameObject list is that same list, only 01:35:08.720 --> 01:35:10.910 that's the view we have of it in the editor. 01:35:10.910 --> 01:35:13.730 And it's just a different way of looking at the data. 01:35:13.730 --> 01:35:16.790 And that's the nice thing about Unity is that, if you make 01:35:16.790 --> 01:35:19.640 any of your fields public, like this. 01:35:19.640 --> 01:35:24.590 If I did public int someNumber, right? 01:35:24.590 --> 01:35:27.590 And I save that, and I go back here, my airplane spawner 01:35:27.590 --> 01:35:32.510 should get a someNumber right here. 01:35:32.510 --> 01:35:34.760 And then I can just set someNumber to whatever I want. 01:35:34.760 --> 01:35:36.290 It doesn't do anything right now, because someNumber 01:35:36.290 --> 01:35:37.860 doesn't affect the script. 01:35:37.860 --> 01:35:44.090 But this is a nice way to take the burden from you out of the code. 01:35:44.090 --> 01:35:46.910 You're not experimenting with code. 01:35:46.910 --> 01:35:49.120 You're not tweaking some variable in your script. 01:35:49.120 --> 01:35:52.810 SomeNumber 10, run me, OK-- someNumber 12, run it. 01:35:52.810 --> 01:35:56.680 You can just assign it here in your actual editor view, 01:35:56.680 --> 01:35:58.227 and then just tweak it as you want. 01:35:58.227 --> 01:35:59.560 So I can just scroll through it. 01:35:59.560 --> 01:36:03.010 I can start the game and I can pause the game. 01:36:03.010 --> 01:36:05.082 AUDIENCE: So is it that you just make it public? 01:36:05.082 --> 01:36:06.790 COLTON OGDEN: You have to make it public. 01:36:06.790 --> 01:36:07.240 Exactly. 01:36:07.240 --> 01:36:08.320 AUDIENCE: Oh, then that shows in. 01:36:08.320 --> 01:36:09.070 COLTON OGDEN: Yep. 01:36:09.070 --> 01:36:10.240 And so I can just do this. 01:36:10.240 --> 01:36:11.490 And then I should be able to-- 01:36:11.490 --> 01:36:14.170 I can just change this now, if I wanted to, to 67. 01:36:14.170 --> 01:36:18.070 And so if that actually had some sort of effect on my game world-- 01:36:18.070 --> 01:36:21.490 if my game relied on that number being meaningful-- 01:36:21.490 --> 01:36:22.980 this would update the scene. 01:36:22.980 --> 01:36:25.540 And so you can make whatever-- you can debug this way, 01:36:25.540 --> 01:36:29.190 or you can customize your components more this way. 01:36:29.190 --> 01:36:33.220 But it's just a tremendous amount of flexibility. 01:36:33.220 --> 01:36:37.630 And so that's how we're instantiating this from this list of prefabs. 01:36:37.630 --> 01:36:39.640 It's a list of game objects. 01:36:39.640 --> 01:36:42.460 We've made it explicit to Unity. 01:36:42.460 --> 01:36:45.580 The editor's going to know, OK, these are game objects. 01:36:45.580 --> 01:36:47.710 And so prefabs are game objects. 01:36:47.710 --> 01:36:51.520 So we can just put any of these into this field 01:36:51.520 --> 01:36:55.870 here, this element 0 field, or however many fields we have. 01:36:55.870 --> 01:36:59.410 And it will, in the code, randomly choose one of those, 01:36:59.410 --> 01:37:01.690 and then instantiate it. 01:37:01.690 --> 01:37:04.374 So any questions as to how prefabs work, or instantiation, 01:37:04.374 --> 01:37:05.290 or anything like that? 01:37:07.721 --> 01:37:08.220 OK. 01:37:11.118 --> 01:37:14.500 AUDIENCE: Does each prefab have a unique number or not? 01:37:14.500 --> 01:37:16.750 COLTON OGDEN: Does each prefab have a unique number? 01:37:16.750 --> 01:37:18.250 Not a unique number. 01:37:18.250 --> 01:37:21.880 They just are all assets in your folder here. 01:37:21.880 --> 01:37:26.170 They have some kind of identifier to Unity that's hidden from you. 01:37:26.170 --> 01:37:28.180 It might be visible from you if you look. 01:37:28.180 --> 01:37:31.180 They might have some sort of generated ID or something like that, so 01:37:31.180 --> 01:37:33.380 that it knows, underneath the scenes. 01:37:33.380 --> 01:37:38.380 But it's not something that you worry about in your actual code. 01:37:38.380 --> 01:37:41.540 We've created a list here that's just-- 01:37:41.540 --> 01:37:43.720 it will expect some number. 01:37:43.720 --> 01:37:44.832 It doesn't know how many. 01:37:44.832 --> 01:37:47.290 And then, in the editor, you can actually tell it how many. 01:37:50.830 --> 01:37:55.630 Because every list that you make visible in 01:37:55.630 --> 01:37:58.420 the editor will have this size field. 01:37:58.420 --> 01:38:00.850 And that's just part of the editor's abstraction. 01:38:00.850 --> 01:38:04.030 The editor has abstractions for a lot of different objects. 01:38:04.030 --> 01:38:07.630 You can create a lot of different objects in your MonoBehaviours, 01:38:07.630 --> 01:38:12.220 and make them public, and Unity will have a different view for them. 01:38:12.220 --> 01:38:14.596 Things like color pickers, and stuff like that. 01:38:14.596 --> 01:38:17.470 I don't know the exact object offhand, but if you make a public color 01:38:17.470 --> 01:38:20.081 picker in your MonoBehaviour or something like that, 01:38:20.081 --> 01:38:23.080 you'll actually get a color picker here that you can choose a color for, 01:38:23.080 --> 01:38:24.560 which is pretty awesome. 01:38:24.560 --> 01:38:27.190 And there's a lot of different customized views. 01:38:30.529 --> 01:38:33.070 I think, actually, the directional light might be an example. 01:38:33.070 --> 01:38:34.510 See this color here? 01:38:34.510 --> 01:38:37.300 This is somewhere in code. 01:38:37.300 --> 01:38:40.040 There's a public color something. 01:38:40.040 --> 01:38:42.520 And then in the editor, when you're actually editing it, 01:38:42.520 --> 01:38:43.600 you can choose the color. 01:38:43.600 --> 01:38:46.400 And Unity gives you the option to make it wherever you want. 01:38:46.400 --> 01:38:50.740 And notice it's actually affecting the background there. 01:38:50.740 --> 01:38:52.690 One of the really big strengths of Unity, 01:38:52.690 --> 01:38:56.350 and a reason to really make your components customizable, 01:38:56.350 --> 01:39:01.390 is this one-to-one mapping between your data, your code, 01:39:01.390 --> 01:39:05.485 and your editor view of the data. 01:39:05.485 --> 01:39:07.360 Take the burden away from you programming it, 01:39:07.360 --> 01:39:10.630 which you're more prone to make mistakes, too, 01:39:10.630 --> 01:39:12.640 and also waste a lot of time. 01:39:12.640 --> 01:39:14.620 And then just be able to modify. 01:39:14.620 --> 01:39:16.900 How much faster is it for me to just say, 01:39:16.900 --> 01:39:20.470 I want this red color, rather than color.r equals something, 01:39:20.470 --> 01:39:23.440 and then color.g equals something, color.b equals something. 01:39:23.440 --> 01:39:24.800 And then assign it that way. 01:39:24.800 --> 01:39:26.841 So that's just a simple example to illustrate it. 01:39:26.841 --> 01:39:29.890 But there's a tremendous amount of potential involved 01:39:29.890 --> 01:39:33.320 in making your components customizable. 01:39:33.320 --> 01:39:34.570 And so that's what I did here. 01:39:34.570 --> 01:39:43.270 Because I wanted the skyscraper spawner to spawn not just one skyscraper 01:39:43.270 --> 01:39:48.160 but several skyscrapers, I created this public prefabs list, 01:39:48.160 --> 01:39:50.770 that I can then populate from Unity here. 01:39:50.770 --> 01:39:53.620 And say, OK, this object, this object, and this object. 01:39:53.620 --> 01:39:56.560 Put that into the skyscraper spawner here, in these slots. 01:39:56.560 --> 01:40:02.200 And then my code knows to instantiate it, randomly picking one of those. 01:40:02.200 --> 01:40:02.700 Yeah. 01:40:02.700 --> 01:40:04.986 AUDIENCE: In the example earlier, how would you 01:40:04.986 --> 01:40:09.560 actually go about making something scrollable now that you've made that? 01:40:09.560 --> 01:40:12.329 Would you just add component to the coin? 01:40:12.329 --> 01:40:15.370 COLTON OGDEN: How would you go about making something scrollable now that 01:40:15.370 --> 01:40:15.869 you've-- 01:40:15.869 --> 01:40:18.670 AUDIENCE: You declared that Scrollable class, right? 01:40:18.670 --> 01:40:19.690 COLTON OGDEN: Oh, yeah. 01:40:19.690 --> 01:40:24.550 So I have a Scrollable script here. 01:40:24.550 --> 01:40:28.507 Oh, do you mean the infinite scrolling background, or the scrollable object? 01:40:28.507 --> 01:40:31.840 AUDIENCE: The one where you define it as being destroyed when it's [INAUDIBLE].. 01:40:31.840 --> 01:40:32.798 COLTON OGDEN: Oh, yeah. 01:40:32.798 --> 01:40:35.780 So in order to do that-- so we've made the Scrollable script here. 01:40:35.780 --> 01:40:38.050 So you would just go to-- in this case, since we're 01:40:38.050 --> 01:40:42.340 instantiating all of the coins, and skyscrapers, and airplanes as prefabs, 01:40:42.340 --> 01:40:44.470 you actually edit the prefab itself. 01:40:44.470 --> 01:40:46.160 So I'd go to this coin prefab. 01:40:46.160 --> 01:40:48.370 I'd add component here at the bottom. 01:40:48.370 --> 01:40:51.580 And I would add Scrollable there, which is a script. 01:40:51.580 --> 01:40:54.070 And you can tell it's yours, because it says script there. 01:40:54.070 --> 01:40:57.460 Just like coin here is a script, and rotate script is a script. 01:40:57.460 --> 01:41:01.110 That's actually an old script that I didn't use anymore, 01:41:01.110 --> 01:41:05.200 because I just made it part of the coin itself. 01:41:05.200 --> 01:41:08.380 But this is another part of what makes the coin class, by the way, 01:41:08.380 --> 01:41:14.590 is this transform.rotate x, y, and z, either relative 01:41:14.590 --> 01:41:16.340 to itself or to the world space. 01:41:16.340 --> 01:41:18.590 In this case, it shows the world space, because I want 01:41:18.590 --> 01:41:20.370 it to rotate on the world's y-axis. 01:41:20.370 --> 01:41:24.227 But if you rotate an object, its own x, y, z still exist. 01:41:24.227 --> 01:41:26.560 And so you can have something rotate about its own x, y, 01:41:26.560 --> 01:41:29.574 and z, regardless of its rotation in the world. 01:41:29.574 --> 01:41:31.240 And so I want the coin to always rotate. 01:41:31.240 --> 01:41:35.450 So 5 degrees on the y-axis here. 01:41:35.450 --> 01:41:40.030 So this is another part that you could take and make it its own script-- 01:41:40.030 --> 01:41:42.190 just a rotatable script. 01:41:42.190 --> 01:41:43.390 Auto rotate script. 01:41:43.390 --> 01:41:47.590 And then just make these public fields, like public x, public y, public z. 01:41:47.590 --> 01:41:49.570 And then you could change those in the editor, 01:41:49.570 --> 01:41:54.970 and then actually customize your objects without having to go into the code 01:41:54.970 --> 01:41:56.324 itself. 01:41:56.324 --> 01:42:00.300 AUDIENCE: So you don't have to do any collisions, actually, yourself. 01:42:00.300 --> 01:42:04.019 You just click the button and type in the Collide function. 01:42:04.019 --> 01:42:04.810 COLTON OGDEN: Yeah. 01:42:04.810 --> 01:42:06.934 You don't have to do any of the collision yourself, 01:42:06.934 --> 01:42:09.744 because Unity comes with a 3D physics engine. 01:42:09.744 --> 01:42:12.160 You have to tell it what to do when the collisions happen. 01:42:12.160 --> 01:42:16.750 But you don't have to actually code the 3D physics engine yourself, which 01:42:16.750 --> 01:42:19.710 is a tremendous amount of work. 01:42:19.710 --> 01:42:21.460 One of the big selling points, definitely, 01:42:21.460 --> 01:42:23.410 for doing any 3D things in Unity. 01:42:23.410 --> 01:42:26.800 I mean, a lot of engines now have 3D engines for free. 01:42:26.800 --> 01:42:29.202 There was a time when it was less prevalent. 01:42:29.202 --> 01:42:31.619 AUDIENCE: How would you know what you collided with? 01:42:31.619 --> 01:42:33.910 COLTON OGDEN: Because there is a collider that it gets. 01:42:38.331 --> 01:42:39.080 Where is it again? 01:42:39.080 --> 01:42:41.572 Is it the skyscraper, for example? 01:42:41.572 --> 01:42:43.780 So every skyscraper, when it collides with something, 01:42:43.780 --> 01:42:47.320 this OnTriggerEnter gets passed in this collider other. 01:42:47.320 --> 01:42:53.014 And so that's going to be the object that you collided with. 01:42:53.014 --> 01:42:56.180 You can assign a name to an object, and then get its name, as well, in code, 01:42:56.180 --> 01:42:58.599 if you needed to do that. 01:42:58.599 --> 01:43:01.390 In this case, we wanted to know whether it's the helicopter or not. 01:43:01.390 --> 01:43:04.160 So we got the HeliController from it. 01:43:04.160 --> 01:43:06.280 But in our game, it's kind of a special case, 01:43:06.280 --> 01:43:08.290 because there's only one type of object that 01:43:08.290 --> 01:43:11.500 has a collider that's a non-trigger, and that's the helicopter. 01:43:11.500 --> 01:43:15.400 So we can assume that this exists when we do get a collision. 01:43:15.400 --> 01:43:20.410 But otherwise, we probably want to say, get component of HeliController, 01:43:20.410 --> 01:43:22.340 and then test it for equal to null. 01:43:22.340 --> 01:43:26.500 And if it's equal to null, then we want to not do something. 01:43:26.500 --> 01:43:29.587 If we tried to call explode on a null object, 01:43:29.587 --> 01:43:31.420 that's going to be a null pointer exception. 01:43:31.420 --> 01:43:33.624 And then you're going to crash your game. 01:43:33.624 --> 01:43:36.040 But in this case, we're guaranteed for that not to happen. 01:43:36.040 --> 01:43:38.530 Because, like I said, the only collider that 01:43:38.530 --> 01:43:42.900 can collide with this that's not a trigger is the helicopter object. 01:43:42.900 --> 01:43:45.085 So does that makes sense? 01:43:45.085 --> 01:43:48.480 AUDIENCE: Sounds like a physics problem with an exploding element. 01:43:48.480 --> 01:43:49.640 COLTON OGDEN: Oh, yeah. 01:43:49.640 --> 01:43:50.280 Yeah. 01:43:50.280 --> 01:43:52.230 That's all too real. 01:43:55.370 --> 01:43:59.196 In this case, though, all explode is is, thankfully, just destroy game object 01:43:59.196 --> 01:44:00.570 and then start a particle effect. 01:44:00.570 --> 01:44:04.800 So any more questions as to how instantiation, 01:44:04.800 --> 01:44:08.610 prefabs, using the Unity editor, interacting with your model 01:44:08.610 --> 01:44:10.330 behaviors, public variables? 01:44:10.330 --> 01:44:11.905 Yeah. 01:44:11.905 --> 01:44:15.300 AUDIENCE: You get processes, you first enter the data in that to there, 01:44:15.300 --> 01:44:19.665 and then it runs the code to load the data, 01:44:19.665 --> 01:44:23.070 or can you also put value data in the editor? 01:44:23.070 --> 01:44:24.480 COLTON OGDEN: You cannot define-- 01:44:24.480 --> 01:44:27.570 so the question is, do you first create the data in the editor, 01:44:27.570 --> 01:44:31.380 and then the code, and then tie them together that way? 01:44:31.380 --> 01:44:34.650 In order to get a new component, you will have to create the class first-- 01:44:34.650 --> 01:44:37.440 the model behavior that you want-- 01:44:37.440 --> 01:44:41.550 and give it the public fields that it needs for the editor to actually read. 01:44:41.550 --> 01:44:45.000 So the editor reads your script, looks through all the public fields, 01:44:45.000 --> 01:44:47.820 and then will create the necessary GUI elements in the editor 01:44:47.820 --> 01:44:50.020 to interact with the code. 01:44:50.020 --> 01:44:51.390 But this needs to exist. 01:44:51.390 --> 01:44:52.980 All this code needs to exist. 01:44:52.980 --> 01:44:56.430 Anything that has these public variables that you want accessible in the editor 01:44:56.430 --> 01:44:59.130 needs to exist in code first, and then you 01:44:59.130 --> 01:45:00.900 have the power to use it in the editor. 01:45:00.900 --> 01:45:04.440 And then it's customizable at that point. 01:45:04.440 --> 01:45:08.130 Any more questions? 01:45:08.130 --> 01:45:09.540 All right. 01:45:09.540 --> 01:45:11.460 So that's the prefabs. 01:45:11.460 --> 01:45:13.456 So we looked at texture scrolling before. 01:45:13.456 --> 01:45:15.580 And we're going to go kind of quickly through this. 01:45:15.580 --> 01:45:18.220 But all texture showing was, if we recall, 01:45:18.220 --> 01:45:21.450 was I have a scrolling background class here. 01:45:21.450 --> 01:45:22.510 It's got a scroll speed. 01:45:22.510 --> 01:45:25.387 So if we wanted to, since it's public, we can edit it in the editor 01:45:25.387 --> 01:45:26.595 and make it faster or slower. 01:45:29.170 --> 01:45:31.230 But if we maintain a reference to our renderer. 01:45:31.230 --> 01:45:35.550 Every object has a renderer-- mesh renderer, typically, for 3D objects. 01:45:35.550 --> 01:45:39.900 And the renderer has a material associated with it. 01:45:39.900 --> 01:45:43.230 Everything in Unity has a material. 01:45:43.230 --> 01:45:45.660 And material doesn't necessarily have a texture. 01:45:45.660 --> 01:45:48.570 But in this case, our background does have a texture, 01:45:48.570 --> 01:45:51.000 and it's going to be called MainTex by default. 01:45:51.000 --> 01:45:53.910 That's the main texture, if we want to assign a texture 01:45:53.910 --> 01:45:55.920 to see visually on a material. 01:45:55.920 --> 01:45:59.700 So material can just be a color often, but it can also 01:45:59.700 --> 01:46:02.350 be a color and also a texture. 01:46:02.350 --> 01:46:04.410 So in this case, the background is a texture. 01:46:04.410 --> 01:46:05.993 It does have a texture assigned to it. 01:46:05.993 --> 01:46:09.810 And notice that if we go to the background, 01:46:09.810 --> 01:46:13.590 and then here is where we actually create. 01:46:13.590 --> 01:46:15.360 So this is a material here. 01:46:15.360 --> 01:46:16.530 It's got a shader. 01:46:16.530 --> 01:46:19.037 So we're not going to talk too much about what shaders are. 01:46:19.037 --> 01:46:20.370 We've talked about them briefly. 01:46:20.370 --> 01:46:24.720 In Unity, you can go quite a bit farther with them. 01:46:24.720 --> 01:46:28.860 Well, technically speaking, I guess you could go equally far with Love2D-- 01:46:28.860 --> 01:46:34.290 2D shaders and 3D shaders, at least in vertex and fragment shaders. 01:46:34.290 --> 01:46:37.590 But for all intents and purposes, we're not 01:46:37.590 --> 01:46:40.560 going to go into detail on shaders today. 01:46:40.560 --> 01:46:42.690 But they're very similar. 01:46:42.690 --> 01:46:47.247 In this case, every material has a shader in Unity, 01:46:47.247 --> 01:46:48.330 in order for it to render. 01:46:48.330 --> 01:46:52.170 Because anything that renders needs to be shaded in Unity. 01:46:52.170 --> 01:46:54.340 But notice that here we have a texture. 01:46:54.340 --> 01:46:57.100 So this is that main texture thing that we saw before. 01:46:57.100 --> 01:46:58.904 And then this is the bump map here. 01:46:58.904 --> 01:47:01.320 We don't have a bump map, because our texture isn't bumpy. 01:47:01.320 --> 01:47:04.170 It doesn't have any contour detail or anything like that. 01:47:04.170 --> 01:47:06.300 But you can just select a texture here. 01:47:06.300 --> 01:47:08.670 So I could give it that texture if I wanted to. 01:47:08.670 --> 01:47:10.440 Or I have another couple of textures here. 01:47:13.730 --> 01:47:14.910 This texture here. 01:47:14.910 --> 01:47:18.120 It doesn't matter which texture you choose, but you can choose a texture. 01:47:18.120 --> 01:47:21.810 And then that material will then, it will calculate, 01:47:21.810 --> 01:47:25.770 based on the mesh, how to draw that texture best to it. 01:47:25.770 --> 01:47:32.520 And you can set every material's texture offset via its SetTextureOffset 01:47:32.520 --> 01:47:34.800 function on the x and the y-axis. 01:47:34.800 --> 01:47:38.850 And that'll shift it, effectively accomplishing 01:47:38.850 --> 01:47:41.010 what a scrolling background needs. 01:47:41.010 --> 01:47:44.340 It'll draw it, and then it'll basically wrap around to the other side. 01:47:44.340 --> 01:47:48.330 So that's how we get the infinite scrolling texture. 01:47:48.330 --> 01:47:51.050 We just set its texture offset. 01:47:51.050 --> 01:47:54.480 We specific call SetTextureOffset on the main texture, 01:47:54.480 --> 01:47:55.910 and then we pass in a Vector 2. 01:47:55.910 --> 01:47:57.720 So just two numbers-- 01:47:57.720 --> 01:47:58.650 offset and 0. 01:47:58.650 --> 01:48:01.920 Because we don't want to touch the y-axis, so it was 0, and then offset 01:48:01.920 --> 01:48:04.590 is just some value that increases over time. 01:48:04.590 --> 01:48:06.390 And then Time.time, recall-- 01:48:06.390 --> 01:48:08.640 time since the beginning of the game has started. 01:48:08.640 --> 01:48:11.550 Time.delta time-- time since the last frame. 01:48:11.550 --> 01:48:15.480 And so we can just do one calculation in here and update every time, 01:48:15.480 --> 01:48:17.610 and then multiply it times scroll speed to get 01:48:17.610 --> 01:48:19.440 the scroll amount that we want here. 01:48:19.440 --> 01:48:23.710 And I've set it to 0.1 just for a semi-slow effect. 01:48:23.710 --> 01:48:32.170 But in the editor, if we look at our scrolling background, which is here. 01:48:32.170 --> 01:48:36.584 And then I've made it public, so I could just easily make this 1. 01:48:36.584 --> 01:48:39.250 And I don't know how fast it's going to be, but 10 times faster. 01:48:39.250 --> 01:48:41.334 So probably pretty fast. 01:48:41.334 --> 01:48:42.650 Yep. 01:48:42.650 --> 01:48:45.200 So it's hauling. 01:48:45.200 --> 01:48:45.840 But yeah. 01:48:45.840 --> 01:48:50.310 All that is is a shifting how it maps the texture onto the 3D surface. 01:48:50.310 --> 01:48:53.760 And this 3D surface, to be clear, is just a plane. 01:48:53.760 --> 01:48:55.350 So just a plane. 01:48:55.350 --> 01:48:57.600 And notice that it doesn't get rendered from the back. 01:48:57.600 --> 01:49:02.970 So anything which is a polygon has one side that gets shaded 01:49:02.970 --> 01:49:05.560 and one side that does not get shaded. 01:49:05.560 --> 01:49:09.522 So if you see invisibility on one side, and not invisibility on one side, 01:49:09.522 --> 01:49:10.230 that's not a bug. 01:49:10.230 --> 01:49:12.807 That's a feature. 01:49:12.807 --> 01:49:14.640 That's the texture scrolling side of things. 01:49:14.640 --> 01:49:18.160 Anybody have any questions as to how that works? 01:49:18.160 --> 01:49:20.747 We won't really need it for much going forward. 01:49:20.747 --> 01:49:22.080 It's not part of the assignment. 01:49:22.080 --> 01:49:24.500 But it ties in to what we've done before. 01:49:24.500 --> 01:49:27.214 So I thought it would be interesting to cover. 01:49:27.214 --> 01:49:28.630 Last thing we'll look at is audio. 01:49:28.630 --> 01:49:30.190 Audio is pretty easy. 01:49:30.190 --> 01:49:37.440 All you need in Unity to do audio is an audio source and an audio listener. 01:49:37.440 --> 01:49:39.150 So a source plays audio. 01:49:39.150 --> 01:49:44.670 So James, if you are an audio source, I'd be an audio listener. 01:49:44.670 --> 01:49:46.920 And I'm listening for audio and playing it back 01:49:46.920 --> 01:49:52.770 to the speakers when I hear any sort of source of audio in the game world. 01:49:52.770 --> 01:49:56.820 So you can have infinite audio sources, but ideally one audio listener. 01:49:56.820 --> 01:50:02.550 And it's usually whatever main camera that you're drawing with. 01:50:02.550 --> 01:50:05.520 And then sounds in Unity can be either 2D or 3D. 01:50:05.520 --> 01:50:10.110 In this case, all the sounds that I've put into this game are 2D. 01:50:10.110 --> 01:50:12.560 And that's just this spatial blend here. 01:50:12.560 --> 01:50:15.570 Notice that there's a 2D to 3D slide. 01:50:15.570 --> 01:50:17.820 And so that'll calculate, based on where the sound is, 01:50:17.820 --> 01:50:19.380 how it sounds in the game space. 01:50:19.380 --> 01:50:23.430 And it's based on how far away it is, and what side of you it is. 01:50:23.430 --> 01:50:27.150 And so the main camera has the audio source for the music. 01:50:27.150 --> 01:50:29.730 And so it just starts the music right away. 01:50:29.730 --> 01:50:31.870 Notice that we didn't have to code any of this. 01:50:31.870 --> 01:50:34.000 I just attached an audio source to the camera. 01:50:34.000 --> 01:50:38.340 And then there's a Play On Awake checkbox, and a Loop checkbox. 01:50:38.340 --> 01:50:40.260 So normally we've done like-- 01:50:40.260 --> 01:50:43.650 at the start of our game code, set looping to true, and then 01:50:43.650 --> 01:50:44.595 play the source. 01:50:44.595 --> 01:50:46.720 In this case, we'd have to do none of those things. 01:50:46.720 --> 01:50:49.260 This is just given to us by Unity by default. 01:50:49.260 --> 01:50:51.106 AUDIENCE: You put the audio on the camera? 01:50:51.106 --> 01:50:51.855 COLTON OGDEN: Yep. 01:50:51.855 --> 01:50:53.070 AUDIENCE: You could put it on anything. 01:50:53.070 --> 01:50:54.876 COLTON OGDEN: You could put it on anything you want to. 01:50:54.876 --> 01:50:56.700 AUDIENCE: The sound is relative to that object. 01:50:56.700 --> 01:50:59.075 COLTON OGDEN: The sound is relative to that object, yeah. 01:51:01.439 --> 01:51:01.980 That's audio. 01:51:01.980 --> 01:51:03.420 It's pretty simple. 01:51:03.420 --> 01:51:05.460 I mean, it's an art form when it comes to how 01:51:05.460 --> 01:51:06.840 you want to position things in your game world, 01:51:06.840 --> 01:51:09.030 and how you want them to sound, and whatnot. 01:51:09.030 --> 01:51:10.738 And you can get more complicated with it. 01:51:10.738 --> 01:51:14.360 But that's how you would do basic 2D, in this case, audio. 01:51:14.360 --> 01:51:16.110 But you could easily also do 3D audio just 01:51:16.110 --> 01:51:19.620 by making this set to 0 from 0 to 1. 01:51:19.620 --> 01:51:21.660 And you can make it more or less 3D, too. 01:51:21.660 --> 01:51:24.290 If it's not all the way to 1, it'll somewhat be 2D. 01:51:24.290 --> 01:51:27.660 So you'll hear some of it no matter what, and some of it will be 3D. 01:51:27.660 --> 01:51:29.977 And then setting it to 1, it'll be purely 3D. 01:51:29.977 --> 01:51:32.310 So if it gets far enough away, you won't hear it at all. 01:51:35.640 --> 01:51:40.240 The explosion sound, as well, gets triggered. 01:51:40.240 --> 01:51:41.520 And so this happens in the-- 01:51:41.520 --> 01:51:44.130 I forget exactly offhand where it gets triggered. 01:51:49.000 --> 01:51:55.020 I believe it's in the HelicopterExplode function? 01:51:55.020 --> 01:51:55.590 Oh, yes. 01:52:01.435 --> 01:52:04.560 I created an object in the scene that has an audio source for the explosion 01:52:04.560 --> 01:52:05.220 sound. 01:52:05.220 --> 01:52:08.470 And because I made this public, I can just put it on this object. 01:52:08.470 --> 01:52:12.130 And so there's a reference to that audio source at all times. 01:52:12.130 --> 01:52:16.230 And so I trigger explosionSound.play whenever we call this Explode method 01:52:16.230 --> 01:52:17.754 on the HeliController. 01:52:17.754 --> 01:52:20.670 For the reason that I didn't put it on this object, because we destroy 01:52:20.670 --> 01:52:24.180 this object as soon as we get into a collision. 01:52:24.180 --> 01:52:27.515 And so I didn't want to put the explosion sound 01:52:27.515 --> 01:52:30.390 audio source on this object, because it would get destroyed in there. 01:52:30.390 --> 01:52:33.270 It would not play audio, effectively, as soon as we destroy it. 01:52:33.270 --> 01:52:35.380 So we have to have it somewhere else on the scene. 01:52:35.380 --> 01:52:40.505 I could have also just made the object invisible, but I didn't. 01:52:40.505 --> 01:52:41.130 I destroyed it. 01:52:44.670 --> 01:52:46.270 And so, yeah. 01:52:46.270 --> 01:52:51.930 That's this explosion sound object which, if we look at the helicopter, 01:52:51.930 --> 01:52:57.910 in the HeliController, which is all the way down here. 01:52:57.910 --> 01:53:01.780 Notice that it has a reference to an explosion particle 01:53:01.780 --> 01:53:03.760 system and an explosion sound. 01:53:03.760 --> 01:53:08.320 And we just have to click and drag the object effectively from here to here 01:53:08.320 --> 01:53:09.550 to pair the two of them. 01:53:09.550 --> 01:53:11.710 And then the script that this is referring 01:53:11.710 --> 01:53:14.170 to will always have a reference to those, as long as these 01:53:14.170 --> 01:53:15.580 are set to something. 01:53:15.580 --> 01:53:18.010 And notice that we also have coin total we've made public. 01:53:18.010 --> 01:53:19.660 So I guess I could experiment with it. 01:53:19.660 --> 01:53:22.900 And then speed-- we made this public so that you can make the helicopter 01:53:22.900 --> 01:53:25.100 faster, if you wanted to, or slower. 01:53:25.100 --> 01:53:30.987 And so you'll find it often useful to make a lot of these fields public 01:53:30.987 --> 01:53:32.320 just for you to experiment with. 01:53:32.320 --> 01:53:34.930 And then there's never really harm in doing so, 01:53:34.930 --> 01:53:39.452 because folks aren't going to be able to actually see this in the editor 01:53:39.452 --> 01:53:40.660 when they download your game. 01:53:40.660 --> 01:53:43.210 So make as much public as you want for debugging purposes, 01:53:43.210 --> 01:53:46.027 and just have fun with it. 01:53:46.027 --> 01:53:46.735 But that's audio. 01:53:46.735 --> 01:53:48.600 Audio sources produce the sound. 01:53:48.600 --> 01:53:50.260 Audio listeners listen to the sound. 01:53:50.260 --> 01:53:53.050 And actually make it go through your computer speakers 01:53:53.050 --> 01:53:57.460 or whatever your default audio system is. 01:53:57.460 --> 01:54:01.360 And here's just a showcase of the two on the camera. 01:54:01.360 --> 01:54:03.070 And that's audio. 01:54:03.070 --> 01:54:08.384 So any questions as to how the audio works at all? 01:54:08.384 --> 01:54:09.280 All right. 01:54:09.280 --> 01:54:11.321 A couple of last things before we close out here. 01:54:11.321 --> 01:54:14.380 So the Asset Store is probably one of the biggest things about Unity 01:54:14.380 --> 01:54:16.630 that sells it. 01:54:16.630 --> 01:54:20.590 So oftentimes, it's a lot easier just to get something, 01:54:20.590 --> 01:54:23.560 whether it's a library, if you're programming, or something else, 01:54:23.560 --> 01:54:25.930 get something that's implemented for you, 01:54:25.930 --> 01:54:29.950 so that you don't have to implement it yourself. 01:54:29.950 --> 01:54:32.680 In this case, there's an RPG Systems for Rapid Development 01:54:32.680 --> 01:54:36.850 something, Visual Scripting system, looks similar to Unreal. 01:54:36.850 --> 01:54:43.990 There's a ton of things in the Asset Store-- models, scripts, audio, editor 01:54:43.990 --> 01:54:44.800 tool kits. 01:54:44.800 --> 01:54:45.820 A lot of cool things. 01:54:45.820 --> 01:54:48.190 A lot of it's free, if you want to experiment. 01:54:48.190 --> 01:54:52.660 So a lot of the assets that I got to mess with in this game here 01:54:52.660 --> 01:54:56.312 are free, like the coin and some of the other stuff that's bundled with it. 01:54:56.312 --> 01:54:58.770 There's a lot of really cool things and really cool systems 01:54:58.770 --> 01:55:00.340 to help you for $10 or $20. 01:55:00.340 --> 01:55:02.830 You can spend a little bit of money, and then 01:55:02.830 --> 01:55:06.310 get like 25% of your game done right away. 01:55:06.310 --> 01:55:08.860 And then you can actually get closer to shipping it. 01:55:08.860 --> 01:55:12.790 So I think it's hugely valuable to be looking at the Asset Store 01:55:12.790 --> 01:55:15.310 and thinking about how you can save your time that way, 01:55:15.310 --> 01:55:18.830 if you're trying to actually ship a game and get to market. 01:55:18.830 --> 01:55:21.070 So definitely look through the Asset Store. 01:55:21.070 --> 01:55:24.220 See if there's anything that will make your life easier 01:55:24.220 --> 01:55:25.930 when it comes to developing games. 01:55:25.930 --> 01:55:30.940 Because I know that I've used it several times, and I rarely regret doing so. 01:55:30.940 --> 01:55:35.120 So Assignment 8 is going to be pretty simple. 01:55:35.120 --> 01:55:39.820 So for the second part, there's a bug in the game 01:55:39.820 --> 01:55:45.400 where, if you die over and over again, the scroll speed never resets. 01:55:45.400 --> 01:55:48.940 So it is keeping faster, and faster, and faster, and faster forever. 01:55:48.940 --> 01:55:50.890 But it's a one line fix. 01:55:50.890 --> 01:55:54.010 And I want you guys to find where to fix it, given that we know, 01:55:54.010 --> 01:55:55.390 given what we've seen today. 01:55:55.390 --> 01:55:57.880 And there's a hint here about static variables. 01:55:57.880 --> 01:56:01.540 So it will also be detailed in the spec as well. 01:56:01.540 --> 01:56:03.010 But this is an easy part. 01:56:03.010 --> 01:56:05.665 This part's fairly easy, too, because all it really is 01:56:05.665 --> 01:56:08.740 is taking the kind of the same stuff we've looked at-- 01:56:08.740 --> 01:56:10.570 the coin generator and coins-- 01:56:10.570 --> 01:56:16.780 and then making gems that spawn in addition to the coins at a rarer rate. 01:56:16.780 --> 01:56:19.150 And these gems should be worth five coins. 01:56:19.150 --> 01:56:22.765 And so when you collide with the gems, just add 5 to the coin total. 01:56:22.765 --> 01:56:25.392 And if you collide with a coin, add 1 to the coin total. 01:56:25.392 --> 01:56:27.100 And that's basically it for Assignment 8. 01:56:27.100 --> 01:56:31.750 So next time, we're going to dive into first-person games in Unity. 01:56:31.750 --> 01:56:35.080 So we'll look at some of the features that we get for free. 01:56:35.080 --> 01:56:39.100 We're going to implement a simple maze-like game where you can navigate. 01:56:39.100 --> 01:56:41.080 And it will be dark and kind of scary, similar 01:56:41.080 --> 01:56:43.600 to a game called Dreadhalls, which is a mobile VR game. 01:56:43.600 --> 01:56:48.160 And we'll actually test out Unity's VR, and try and get a VR headset in here 01:56:48.160 --> 01:56:51.080 so people can check that out. 01:56:51.080 --> 01:56:51.580 Cool. 01:56:51.580 --> 01:56:52.121 Thanks a lot. 01:56:52.121 --> 01:56:54.030 I'll see you guys next time.