CS50 Video Player
    • 🧁

    • 🍭

    • 🍒

    • 🍿
    • 0:00:00Introduction
    • 0:07:36Unity
    • 0:12:11C#
    • 0:17:24Blender
    • 0:19:09GameObjects
    • 0:29:32Components
    • 0:38:28Composition vs. Inheritance
    • 0:40:29MonoBehaviours
    • 0:56:46Colliders and Triggers
    • 1:14:49Prefabs and Spawning
    • 1:45:14Texture Scrolling
    • 1:49:26Audio
    • 1:54:08Asset Store
    • 1:55:30In Conclusion
    • 0:00:00[MUSIC PLAYING]
    • 0:00:16COLTON OGDEN: All right.
    • 0:00:17Welcome back to GD50.
    • 0:00:18This is Lecture 8.
    • 0:00:19Today we're going to be diving into the world of Unity
    • 0:00:22for the first time, which I'm excited about.
    • 0:00:25Going to be a whirlwind tour, but I'll try to cover as much as possible.
    • 0:00:28Transitioning away from 2D and away from Lua and LOVE 2D into 3D and C#
    • 0:00:34in the context of Unity.
    • 0:00:35Today we'll be talking about Helicopter Game 3D.
    • 0:00:37So Helicopter Game is a 2D game that was really famous in the 2000s.
    • 0:00:42It was a web game.
    • 0:00:44I was sponsored on a bunch of websites.
    • 0:00:46Addictinggames.com still has it on there,
    • 0:00:48and a few other websites have it.
    • 0:00:49It was a flash game.
    • 0:00:50But I remember playing it a lot.
    • 0:00:52It was the old precursor to Flappy Bird, which
    • 0:00:54was mentioned on the Wikipedia page.
    • 0:00:56There's a reference to it there.
    • 0:00:58And this is what the game play looked like.
    • 0:00:59It was very similar to Flappy Bird-- a little bit different
    • 0:01:01in that, instead of trying to avoid pipes, you're in a cave,
    • 0:01:04and you're trying to avoid the ceiling and the ground of the level.
    • 0:01:08And there were these little obstacles that would spawn in the middle,
    • 0:01:10as well.
    • 0:01:10So you'd have to navigate that.
    • 0:01:11But it was the same exact mechanic-- the sort of like, click to go up.
    • 0:01:15And then, when you didn't click, your helicopter
    • 0:01:17would just sink down via gravity.
    • 0:01:20Today we'll be talking about a bunch of brand new topics, things like Unity,
    • 0:01:25first and foremost-- the ecosystem with which we'll be doing
    • 0:01:28a lot of the things we'll be doing.
    • 0:01:29C# is the primary language we'll be using.
    • 0:01:32So we're going to take a step away from dynamic languages and move towards
    • 0:01:36statically-typed languages--
    • 0:01:38languages like C#, and Java, and the like.
    • 0:01:40Blender is a program we'll look at briefly today,
    • 0:01:42just because, in the context of 3D development,
    • 0:01:45you're going to want to have a tool that will let you create models.
    • 0:01:48And so the 3D software that I like to advocate for the most, especially
    • 0:01:51for folks that are just starting out, is Blender, because it's free,
    • 0:01:53and open source, and it has much the same feature
    • 0:01:56set as any commercial software, like 3D Studio Max, and Cinema 4D,
    • 0:02:00and the like.
    • 0:02:01We'll talk about what components are-- entities and components, how
    • 0:02:04they relate in this model that Unity has adopted for all of its programming.
    • 0:02:08Components are little pieces of behavior that you can then
    • 0:02:11combine to form a whole, that will then drive the behavior of whatever object
    • 0:02:16in your scene you want, rather than having
    • 0:02:18to customize its behavior via a long chain of inheritance and instantiation.
    • 0:02:23Colliders and triggers are important in 3D--
    • 0:02:26and 2D.
    • 0:02:27But today we'll be talking about colliders
    • 0:02:29and triggers-- things like the helicopter
    • 0:02:30colliding with coins, and buildings, and other planes that are flying.
    • 0:02:34Each of those has to have a collider.
    • 0:02:37And certain things have to be considered triggers in order to trigger
    • 0:02:40certain behavior with other entities.
    • 0:02:43Prefabs and spawning-- prefabs is a huge concept in Unity.
    • 0:02:46So prefabs are basically prefabricated objects
    • 0:02:48that you can customize as you want to-- lay them out in the editor,
    • 0:02:52rather than having to necessarily code all the details.
    • 0:02:55And then you can instantiate them in the actual scene,
    • 0:02:58via code programmatically, in a way that fits the model you're striving for.
    • 0:03:02Texture scrolling is something we'll look at briefly, because it's
    • 0:03:05the way that we accomplish the infinite scrolling aesthetic or behavior.
    • 0:03:09And we'll look at how we can do that in a different way
    • 0:03:12than we've done before, using u-v coordinates,
    • 0:03:14and specifically looking at materials, and modifying
    • 0:03:17certain attributes of those materials.
    • 0:03:20And lastly, to tie everything together as we've done before,
    • 0:03:23we'll look at audio-- things like audio listeners and audio sources--
    • 0:03:26what the difference is between them, and how
    • 0:03:28to add them easily to our game project.
    • 0:03:30But first, a demo-- if there would be anybody
    • 0:03:32willing to come up and take a look and play the 3D helicopter game that I
    • 0:03:35put together, that would be awesome.
    • 0:03:37Anybody?
    • 0:03:40Steven?
    • 0:03:41Awesome.
    • 0:03:42Thank you so much.
    • 0:03:44Let me go ahead and actually get it--
    • 0:03:46so I've pre-built it.
    • 0:03:48So let me go ahead and.
    • 0:03:52So the nice thing about Unity is, it exports to multiple platforms.
    • 0:03:55And right out of the gate, you can get just a--
    • 0:03:57I didn't put an icon for it.
    • 0:03:59But you can create just a native application very easily.
    • 0:04:02And so whenever you're ready, go ahead and hit Play,
    • 0:04:05and Up and Down will move your helicopter.
    • 0:04:12So this is the 3D helicopter game.
    • 0:04:14And I don't think we have sound live, but there should be audio.
    • 0:04:18Oh, I might have actually-- here we go.
    • 0:04:20[MUSIC PLAYING]
    • 0:04:21There we go.
    • 0:04:22That was my bad.
    • 0:04:23So there is music playing.
    • 0:04:24There's sound effects.
    • 0:04:25So notice that we have a 3D model.
    • 0:04:27This is what's called a 2.5D game.
    • 0:04:30So even though everything is in 3D--
    • 0:04:33the models and so forth--
    • 0:04:34the actual axes upon which we're bound are just two.
    • 0:04:38We're just bound to, I believe, the x and the y.
    • 0:04:40Could be the z and the x.
    • 0:04:41I don't recall offhand.
    • 0:04:42But we're bound to just simply two axes of movement.
    • 0:04:45But all the models, as we can see by the camera,
    • 0:04:48are in 3D, including our helicopter.
    • 0:04:50So we have a few things going on.
    • 0:04:51We have skyscrapers that are scrolling by.
    • 0:04:54We have coins that are also going by at the same speed as the skyscrapers.
    • 0:04:58We have a background that is infinitely scrolling.
    • 0:05:02We have, of course, our helicopter which has a rotating set of blades.
    • 0:05:07And when we collide with a coin, notice that we get a little--
    • 0:05:10it might be hard to see in house, but we have a little particle
    • 0:05:13effect that plays.
    • 0:05:15There's airplanes that are flying up top,
    • 0:05:17so we're instantiating those, as well, to fly past us
    • 0:05:20to provide another layer of obstacle.
    • 0:05:22And if we collide with an airplane, notice that we get de-spawned,
    • 0:05:26and then we trigger another particle effect to imitate an explosion.
    • 0:05:29And then, notice we also have a couple of other elements.
    • 0:05:32We have a GUI.
    • 0:05:32We have two GUI elements-- a coin total at the top right,
    • 0:05:36and then a game over here in the middle of the screen, which
    • 0:05:38only shows up once we have died.
    • 0:05:41And the explosive behavior-- if you want to collide with a building,
    • 0:05:45you'll see that.
    • 0:05:46It also triggers when you collide with a building.
    • 0:05:48So there's two things looking for these explosions-- the airplanes up top,
    • 0:05:52and the buildings below.
    • 0:05:53Those are our two obstacles.
    • 0:05:55But when they collide with the coins, we should increment our coin total,
    • 0:05:59and then display a different particle effect.
    • 0:06:01And then this goes on ad infinitum.
    • 0:06:02You can press Space to restart.
    • 0:06:04So we have keyboard input that's based on what
    • 0:06:06we press, different things happen.
    • 0:06:09And so that's effectively the demo that I've put together today.
    • 0:06:11So thanks, Steven.
    • 0:06:12I appreciate you coming up to demo it.
    • 0:06:17So that's the 3D helicopter game.
    • 0:06:19It's got most of the same mechanics as the web version from before--
    • 0:06:24I would say, maybe even more features just to illustrate a few new concepts.
    • 0:06:29But that's effectively what we're going with today.
    • 0:06:31We're just a pretty simple, Flappy Bird esque differently-themed game,
    • 0:06:37based on the same principles.
    • 0:06:38Fly forever, avoid obstacles.
    • 0:06:40And in this case, even get little collectibles.
    • 0:06:43And so notice that there are also effectively two states
    • 0:06:46in our game, which are just the playing state, and then the game over state.
    • 0:06:50The two are almost effectively the same.
    • 0:06:52The only real difference is that one doesn't have the helicopter present,
    • 0:06:56and displays a different GUI element in the middle of the screen.
    • 0:07:00If you haven't downloaded Unity already, there's two links here.
    • 0:07:02So the top link is just the catchall download link.
    • 0:07:06And then the second link is the beta link.
    • 0:07:08So we're actually using the beta in this course,
    • 0:07:10because Unity has started transitioning away
    • 0:07:12from a numerical system for their releases,
    • 0:07:15and is now going yearly with their releases.
    • 0:07:17So the last long-term release candidate was 2017's version.
    • 0:07:22But now that we're almost halfway through 2018,
    • 0:07:25the newest beta is the 2018 version.
    • 0:07:27It has a bunch of new features.
    • 0:07:28So go ahead and check that out.
    • 0:07:30And everything's been well tested, and runs very well--
    • 0:07:33very smoothly on Windows and Mac--
    • 0:07:36with the new beta.
    • 0:07:37So what is Unity?
    • 0:07:40The difference between what we've done so far and what we're doing today is,
    • 0:07:43now we're actually using a full-fledged game engine--
    • 0:07:46this system.
    • 0:07:47It's got a built in editor and all this awesome, cool
    • 0:07:49functionality that we really didn't get with Love2D before.
    • 0:07:52What we were doing before was using a framework,
    • 0:07:54and just implementing everything purely in code.
    • 0:07:56And as we'll see today, everything that you want to do that's customizable
    • 0:08:00effectively is--
    • 0:08:01or can be-- done via code.
    • 0:08:03But there are a lot of more efficient and more user-friendly
    • 0:08:06ways to accomplish the same thing, which we'll take a look at.
    • 0:08:09So Unity has a tremendous market share right now.
    • 0:08:12I forget.
    • 0:08:13I think in 2016 it had like 43% of all games released were done in Unity.
    • 0:08:19I don't know what the current numbers are.
    • 0:08:21I couldn't find them.
    • 0:08:22But there are other engines that are also very well used--
    • 0:08:25Unreal being among them.
    • 0:08:26And Unreal actually may have more market share now,
    • 0:08:28because of games like Fortnite, and because it's
    • 0:08:30been improved a lot over the last couple of years, and really marketed well.
    • 0:08:35But Godot, CryEngine-- there are a lot of game engines
    • 0:08:38that are similar to this that provide you
    • 0:08:39this all-encompassing way of dealing with your game scene
    • 0:08:42and with all your game data.
    • 0:08:44But Unity is a very easy engine to start getting used to,
    • 0:08:48and cranking things out, and being productive with,
    • 0:08:51without the tremendous learning curve that some
    • 0:08:54of the other engines like Unreal might have.
    • 0:08:56Unreal does have a more user-friendly way of doing things.
    • 0:08:58But if you want to get down into the nitty gritty with Unreal,
    • 0:09:02you're coding in semi-arcane C++.
    • 0:09:05So for folks who aren't used to it and aren't used to 3D game development,
    • 0:09:08it can be kind of a large board to get onto.
    • 0:09:11The nice thing about Unity, aside from the fact
    • 0:09:13that it's fairly easy to get started with, is that it's free.
    • 0:09:16And you can use it completely with all of its features
    • 0:09:19until you start making over $100,000 in gross revenue releasing Unity products.
    • 0:09:26And then there are other tiers.
    • 0:09:27The next tier above that is if you start making $200,000,
    • 0:09:30and you get new features with these other tiers.
    • 0:09:33But if you want to just start up a new company,
    • 0:09:35and use Unity, and take something to market--
    • 0:09:38completely free to do so.
    • 0:09:39And once you get over $100,000, that's a good problem to have.
    • 0:09:41It's not necessarily too much to ask to start
    • 0:09:44paying Unity to use it as a means of getting
    • 0:09:48onto the market in the first place.
    • 0:09:49And especially in mobile and VR, Unity's sort of like the forefront.
    • 0:09:55It's got even higher percentage.
    • 0:09:56It's like 60-something or 70% market share on mobile.
    • 0:10:00And then VR-- from the beginning, it's marketed itself very strongly
    • 0:10:05towards the use of VR.
    • 0:10:06And we'll actually use VR in the next lecture.
    • 0:10:10And the way in which we will accomplish all of the programmatic aspect
    • 0:10:14of this-- getting things actually implemented in code--
    • 0:10:17is via C#, which is very different than what we've used so far,
    • 0:10:20which we've used Lua, which is a dynamic scripting language,
    • 0:10:23very much like JavaScript.
    • 0:10:25So C# is very similar to Java, in which things actually have types.
    • 0:10:30And so here's a couple of screenshots of what the Unity editor looks like.
    • 0:10:34So the nice thing about the Unity editor, actually--
    • 0:10:36which we can see right off the gate here--
    • 0:10:38is that it's very customizable.
    • 0:10:40So on the top, that's the default view.
    • 0:10:43You have a bottom panel that shows you all your resources,
    • 0:10:46all your assets, things like scripts, and shaders, and models,
    • 0:10:49and textures, and sounds.
    • 0:10:50You have a nice file browser there on the left-hand side, which allows
    • 0:10:53you to easily navigate your project.
    • 0:10:55You don't have to go looking through your Windows or Mac computer, using
    • 0:10:58your finder, or whatnot, or your File Explorer,
    • 0:11:00and actually look through all your files.
    • 0:11:02You get a nice view there, so that you stay integrated
    • 0:11:05within the Unity ecosystem right there.
    • 0:11:08On the right-hand side, you can see all the behavior for whatever objects
    • 0:11:11you might have in your scene.
    • 0:11:12You get a nice big scene view.
    • 0:11:14So rather than having to run your game live, and look
    • 0:11:17at the behavior that way, you can actually
    • 0:11:19see in advance what your scene looks like, and analyze
    • 0:11:22your game objects that way, and their appearances,
    • 0:11:25and whatever you want to do with them.
    • 0:11:27And lay them out perfectly, rather than have
    • 0:11:29to programmatically figure things out.
    • 0:11:31And on the left-hand side there, you can see
    • 0:11:33a full list of all the game objects.
    • 0:11:35And then on the bottom right screen shot,
    • 0:11:36you can see that the editor is heavily customizable.
    • 0:11:39So you can lay things out however you want
    • 0:11:41to to fit your style of development.
    • 0:11:43I often like to have a panel on top, which shows me my scene view,
    • 0:11:47but then have a panel right below that, that shows me the game view.
    • 0:11:50So if I'm actually running a game and seeing it happen live,
    • 0:11:54I can also see it in the scene, and rotate around in this god mode
    • 0:11:58that you can get in a lot of games.
    • 0:12:00And actually analyze and see things that way,
    • 0:12:03and analyze their behavior frame by frame,
    • 0:12:05even if I want to, in a way that's not possible with however
    • 0:12:08I might have coded the camera in the actual game itself.
    • 0:12:13So C#.
    • 0:12:14So has anybody in here used a static language,
    • 0:12:17or is familiar with statically-typed languages
    • 0:12:19versus dynamically-typed languages?
    • 0:12:21[INAUDIBLE], Steven.
    • 0:12:23So what languages have you guys used, just out of curiosity?
    • 0:12:27Steven.
    • 0:12:28STEVEN: Java, C, C++.
    • 0:12:29COLTON OGDEN: Java, C, C++.
    • 0:12:30Donny?
    • 0:12:31DONNY: [INAUDIBLE]
    • 0:12:31COLTON OGDEN: C and C++.
    • 0:12:32OK.
    • 0:12:32So to you guys, this will be pretty similar.
    • 0:12:35So C# is very similar to Java.
    • 0:12:38Almost looks identical at first glance.
    • 0:12:40There are some features that are different.
    • 0:12:42But it was Microsoft's initiative to compete with Java.
    • 0:12:49It's a Microsoft language, first and foremost.
    • 0:12:51But there are ways to run C# code on other platforms,
    • 0:12:55primarily with the use of what's called Mono.
    • 0:12:57So Mono is an open source implementation of what's called the CLR--
    • 0:13:01the common language runtime--
    • 0:13:03which is how Microsoft allows several of its languages, like F#, and C#,
    • 0:13:09and Visual C++, Visual Basic.
    • 0:13:12They all compile to this intermediary format,
    • 0:13:15like how Java compiles to bytecode.
    • 0:13:17And you can run any of those languages' code--
    • 0:13:21their version of the bytecode-- with the CLR.
    • 0:13:24Mono-- what Mono is, and what Unity relies on
    • 0:13:27to allow its use across multiple operating systems,
    • 0:13:30is a CLR that's not just Windows specific.
    • 0:13:33It actually runs on Mac and on Linux machines, as well.
    • 0:13:37And you'll actually see evidence of its existence via the nomenclature used
    • 0:13:43for Mono behavior.
    • 0:13:45So within Unity, there's this thing called a Mono
    • 0:13:47behavior, which we'll take a look at.
    • 0:13:49From the beginning, actually, Unity was developed for Mac platforms
    • 0:13:53exclusively.
    • 0:13:54But in 2012 or 2011 they ended up making it usable across all major desktop
    • 0:14:00operating systems.
    • 0:14:02But C#-- suffice to say, very similar Java.
    • 0:14:04We'll look at its syntax.
    • 0:14:05But it's different from Lua in that, with Lua, you could just say,
    • 0:14:09oh, x equals 10, or object equals-- and then create
    • 0:14:14a table with whatever you want.
    • 0:14:16C# is a lot less flexible in this sense, in that you have to actually tell it
    • 0:14:20in advance what each data type is that you're trying to make.
    • 0:14:23So you can't just create a table or a integer.
    • 0:14:26You actually have to say, int my_int, or x equals, and then 10,
    • 0:14:31and then semi-colon.
    • 0:14:33So there's also more syntax to be conscious of.
    • 0:14:37And so really quickly, I can show you just what some C# looks like.
    • 0:14:41We'll take a look at this again going forward.
    • 0:14:43But as you can see here, we have public.
    • 0:14:46So that's another thing about C#.
    • 0:14:49In Java, if you're familiar with Java, they're
    • 0:14:51object-oriented programming languages.
    • 0:14:54And as such, there are objects that are public and private,
    • 0:14:59and you have access specifiers for different variables and classes
    • 0:15:04that will tell other variables and classes whether or not
    • 0:15:06they can communicate effectively.
    • 0:15:08So public class just means effectively anybody can see this class.
    • 0:15:12Other classes can see this.
    • 0:15:15But then you have--
    • 0:15:17see if I have one of these that has a private variable.
    • 0:15:21I know there's at least one.
    • 0:15:22Here we go.
    • 0:15:23So private, Text, text here, for example.
    • 0:15:25So first of all, notice that these are variable declarations
    • 0:15:27like we've seen before.
    • 0:15:29We're saying, this is a variable that I'm going to use.
    • 0:15:32In this case, public GameObject helicopter.
    • 0:15:34So I'm just defining it.
    • 0:15:36Or I'm declaring it.
    • 0:15:37I'm not defining it.
    • 0:15:38It doesn't equal anything yet.
    • 0:15:40But I'm saying, this is going to exist, right?
    • 0:15:43You can say equals something, and then define it on the same line.
    • 0:15:50But in this case, we are just declaring in advance what different variables
    • 0:15:55we're going to need later on.
    • 0:15:57Like for example, here.
    • 0:15:58We see, in our start method.
    • 0:16:00And we'll go over what all these methods are and how they're relevant.
    • 0:16:03But we can see here, text equals--
    • 0:16:05and then we're calling some function called GetComponent.
    • 0:16:08And then we have some funky syntax here--
    • 0:16:10less than, Text, greater than--
    • 0:16:12and then function call syntax--
    • 0:16:15two parentheses.
    • 0:16:16So we can see that there's a lot more syntax.
    • 0:16:19But all of the same principles still hold true.
    • 0:16:22It's still much the same way to think about programming.
    • 0:16:25It's just, there's a little bit more to stay conscious of.
    • 0:16:28And we trade off this dynamism for more performance.
    • 0:16:32So that's ultimately what it comes down to-- static versus dynamic languages,
    • 0:16:35you're trading flexibility for performance, in this case.
    • 0:16:39Though C# obviously is a lot faster than Lua.
    • 0:16:42We can do a lot more with it.
    • 0:16:44And actually, Unity isn't itself programmed in C#.
    • 0:16:47Unity itself is programmed in C++.
    • 0:16:50But it allows us to program any behavior that we want to with C#.
    • 0:16:58All right.
    • 0:16:58So that's a look at C# so we can see also what I was alluding to up here.
    • 0:17:04We have our private, public, and we do things with them.
    • 0:17:08And then, depending on what we've declared public or private,
    • 0:17:12these things also transfer into the editor.
    • 0:17:14We'll see how all of that comes together soon.
    • 0:17:16But suffice to say, that's a look at C#-- what it looks like.
    • 0:17:19And we'll use it, and we'll get comfortable with it.
    • 0:17:21But it's a little bit different than what we've done thus far.
    • 0:17:25Away from programming, we'll a very brief look at what Blender is.
    • 0:17:29So I have it installed here.
    • 0:17:31And this isn't required for the course.
    • 0:17:33I will provide you with all the models and all the assets
    • 0:17:36that you need to get working.
    • 0:17:39But this is what Blender is.
    • 0:17:40So Blender almost looks, at first glance, very similar to Unity.
    • 0:17:46The big difference is, this is meant to create new assets.
    • 0:17:50And technically, Blender does have a built-in game engine,
    • 0:17:53but it's not used for that purpose very much.
    • 0:17:55But the sole purpose that we would be using it in this course
    • 0:18:00would be just to create new 3D models.
    • 0:18:01So as you can see here, I can click on these vertices, and move them around.
    • 0:18:06And I'm not a guru by any stretch of the imagination when it comes to Blender.
    • 0:18:12But the helicopter, and jet, and skyscrapers,
    • 0:18:15and those kind of simple models, I made all of those in Blender.
    • 0:18:18And those are bundled with the project, if you
    • 0:18:21want to take a look at how those are implemented.
    • 0:18:23And you can download Blender at the--
    • 0:18:25I forget what the exact link is, actually.
    • 0:18:27Let's take a look.
    • 0:18:28Blender dot org.
    • 0:18:33And then, if we just go down here, download Blender,
    • 0:18:362.79 looks like the most recent version.
    • 0:18:39Blender 2.8-- I guess it's in development.
    • 0:18:42But there's nothing concrete about that on the front page.
    • 0:18:45But yeah.
    • 0:18:45If you want to model 3D assets, and you're curious,
    • 0:18:48and you want a free piece of really awesome software,
    • 0:18:51can't recommend Blender enough.
    • 0:18:53But like I said, I'm going to spend too much time on it, because it's not
    • 0:18:57something that will actually be required in the course
    • 0:18:59to implement 3D models, to create 3D models,
    • 0:19:02since I'll be providing all of that to you in the project in the GitHub repo.
    • 0:19:07And so here is a screenshot of basically what we just saw.
    • 0:19:10So the fundamental part of Unity.
    • 0:19:13So first of all, let's take a look at the Unity editor.
    • 0:19:17So we can see here much of what we saw in the screenshots.
    • 0:19:20But here, I am live looking at my scene, right?
    • 0:19:24I have a helicopter.
    • 0:19:25I have this background back here.
    • 0:19:27I have a camera--
    • 0:19:28that's right here.
    • 0:19:30You can see that it's a camera, because it's got the little camera icon.
    • 0:19:32But it's effectively just an invisible game object.
    • 0:19:34It's not actually going to be rendered to the screen ever.
    • 0:19:38And notice that there are no skyscrapers, no coins, no jets,
    • 0:19:42or anything like that.
    • 0:19:43Those are all instantiated dynamically.
    • 0:19:45But this is the beginning of our scene.
    • 0:19:47And it's all laid out in advance.
    • 0:19:48And we can see here with this camera preview--
    • 0:19:50which is kind of hard to see because it's really small--
    • 0:19:53but here's a larger view of what it looks like.
    • 0:19:56And then we've got a GUI element here, we've got coins here.
    • 0:19:59We have our helicopter.
    • 0:20:00But all of this is a marked difference from what we've gotten
    • 0:20:04used to, which is, program everything, and sort of load it,
    • 0:20:07and, oh, did I put this in the right position?
    • 0:20:09No.
    • 0:20:09I didn't.
    • 0:20:10So I got to.
    • 0:20:10If I wanted to come over here and just move
    • 0:20:13the helicopter a little bit which--
    • 0:20:15like that.
    • 0:20:16Whoops.
    • 0:20:17I just triggered it.
    • 0:20:17If you click on something, by the way, it
    • 0:20:20will play any particle systems that are associated with it.
    • 0:20:23So you can actually get a preview for those, as well.
    • 0:20:25But I can easily just move it here, to the right,
    • 0:20:27or to the left, before the game actually starts.
    • 0:20:30And if I click on the camera, we can see it there.
    • 0:20:33It's a little bit shifted to the left, as opposed to what it was before.
    • 0:20:37But if I just press Command-Z couple of times, take it back to normal.
    • 0:20:41So game object is an important concept.
    • 0:20:44So a game object is basically everything in Unity.
    • 0:20:49So the camera is a game object.
    • 0:20:51The helicopter, which is right here, is a game object.
    • 0:20:54Everything, by the way, that you want to see in your scene in Unity
    • 0:20:57is on this left-hand hierarchy right here.
    • 0:20:59So helicopter, the game object.
    • 0:21:02There's got to be a light source in a 3D scene in order
    • 0:21:05for you to actually see things.
    • 0:21:06So directional light-- that's a game object.
    • 0:21:09Background skyscraper spawner-- we don't see it anywhere.
    • 0:21:12But that's also a game object.
    • 0:21:13It's just an invisible one.
    • 0:21:15A coin spawner.
    • 0:21:17There's something called a canvas, which if we double-click that,
    • 0:21:20we can see we have this obscenely large GUI here that, paradoxically,
    • 0:21:26isn't on top of our scene.
    • 0:21:29Unity does a very interesting thing with all of its GUI elements,
    • 0:21:33in that it basically maps the canvas to one pixel
    • 0:21:40being equal to one Unity unit, which is usually equivalent to a meter.
    • 0:21:44And it draws this in a different draw call than it
    • 0:21:48draws all of the actual 3D stuff--
    • 0:21:52all the stuff that's down here, basically-- in World Space.
    • 0:21:55So when you create a canvas and you see it's gigantic,
    • 0:21:59that's just Unity's way of doing GUI.
    • 0:22:01It's strange.
    • 0:22:03But apparently they do it for performance reasons,
    • 0:22:05because they don't have to calculate like fractional points of where
    • 0:22:08the UI is supposed to be in World Space, which can get really small.
    • 0:22:13But the canvas is a game object.
    • 0:22:18Notice that helicopter has children.
    • 0:22:21It's got blades, a body, and then a blades collider, which actually could
    • 0:22:24have been part of the blades object.
    • 0:22:26Canvas itself has two children-- coin text and game over.
    • 0:22:30And those are the text on the top right, and "game over" in the center.
    • 0:22:34So those are just two text objects, which
    • 0:22:38are labels, that we can just populate with whatever text data we want.
    • 0:22:43The event system is an object.
    • 0:22:45That just gets added to your scene automatically when you add a canvas.
    • 0:22:49Airplane spawner, explosion particles, and explosion sound.
    • 0:22:52So we have all these different objects.
    • 0:22:54They're all part of our scene, and they all do different things.
    • 0:22:58But at the core, they're just game objects.
    • 0:23:00That's the core-- like the bottom type.
    • 0:23:03Yes?
    • 0:23:04AUDIENCE: So I would imagine you're not actually using
    • 0:23:07a helicopter [INAUDIBLE].
    • 0:23:11COLTON OGDEN: Correct.
    • 0:23:12AUDIENCE: So should you actually reset the position
    • 0:23:16of the background [INAUDIBLE]?
    • 0:23:20COLTON OGDEN: So the question was, since we are maintaining
    • 0:23:25a consistent position with the--
    • 0:23:28I'm going to try and scroll in, there we go.
    • 0:23:30The nice about Unity 2 is, if you right click,
    • 0:23:32you can use W-A-S-D to move around the scene,
    • 0:23:34which is super easy and convenient.
    • 0:23:37But the helicopter here stays in one spot.
    • 0:23:40And the camera always stays in one spot forever.
    • 0:23:43So do we move the background image, like we
    • 0:23:50do in our Love2D implementation of Flappy Bird,
    • 0:23:54where we reset its position?
    • 0:23:55And the answer is--
    • 0:23:57I will play it right now in scene view, and let you decide for yourself.
    • 0:24:03So let's go to Window.
    • 0:24:04I'm gonna go to Layouts.
    • 0:24:06So I like the two by three, like I said before,
    • 0:24:08so you can see the scene and the game running live at the same time.
    • 0:24:14I'm going to move my camera in the scene so that I'm
    • 0:24:16looking at this from back here.
    • 0:24:21And then I'm going to play the game.
    • 0:24:26[MUSIC PLAYING]
    • 0:24:29But so.
    • 0:24:32Here's where we-- I'm just going to hold it still.
    • 0:24:37So what do we think is happening?
    • 0:24:40Does it look like our thing is moving?
    • 0:24:42Or is it staying still?
    • 0:24:46It is staying still.
    • 0:24:48Any guesses as to how we're achieving this?
    • 0:24:52Changing the texture.
    • 0:24:54We are scrolling its texture.
    • 0:24:58So when you take a texture and apply it to a 3D surface,
    • 0:25:01you map the texture coordinates to the 3D coordinates of the object
    • 0:25:08that you want to render.
    • 0:25:09It's called UV Mapping.
    • 0:25:11They call it UV, because usually, when you're dealing with 3D objects,
    • 0:25:14you have your x, y, z.
    • 0:25:15And then you want to think of your texture separately from the 3D objects.
    • 0:25:18So you use u, v instead of x, y, since you already have x, y, z
    • 0:25:21allocated for your 3D object.
    • 0:25:27Basically, there's an offset part of the texture--
    • 0:25:32the material that holds the texture--
    • 0:25:34there's an offset field that will reposition the UV mapping
    • 0:25:39of that texture onto the 3D surface.
    • 0:25:43And when you offset it, it will just sort of wrap itself around,
    • 0:25:47if that makes any sense.
    • 0:25:49So what we do is we--
    • 0:25:51and I can actually show you in the code where this is.
    • 0:25:53This is going to be mentioned at the end of the lecture.
    • 0:25:55But we have the scrolling background component here.
    • 0:26:01And there's this thing on each material called a texture offset,
    • 0:26:06which basically shifts the UV mapping of your texture to your 3D object.
    • 0:26:10And so, by setting that texture offset to some value offset,
    • 0:26:14which is very similar to what we've done before.
    • 0:26:17Notice that offset is just scroll speed times time--
    • 0:26:21Time.time, in this case.
    • 0:26:23And I don't mean to overwhelm with, necessarily, all the details here.
    • 0:26:26But the bigger picture is that we're taking time--
    • 0:26:29the amount of time since the beginning of the game is started--
    • 0:26:33and we have some scroll speed that we've pre-determined.
    • 0:26:36And we can just scroll the texture offset here.
    • 0:26:40We're just placing it here at the x.
    • 0:26:41So this new Vector2, offset 0--
    • 0:26:44just think of these two as an x and y--
    • 0:26:46a vector 2, vector 3.
    • 0:26:47Vectors are just combinations of numbers.
    • 0:26:50So 1, 2, 3, 4-- however many you want.
    • 0:26:52A Vector 2 offset in 0.
    • 0:26:55So we don't want to scroll on the y-axis.
    • 0:26:57We just want to scroll left to right.
    • 0:26:59So we're going to apply no texture offset to our y-axis,
    • 0:27:03but we want to apply a texture offset to our x-axis.
    • 0:27:06So that's what their offset there is.
    • 0:27:09And I included it also here--
    • 0:27:11notice there's a Bump Map texture offset.
    • 0:27:13There's no Bump Map actually on our texture.
    • 0:27:16So a Bump Map is effectively--
    • 0:27:17I can maybe find a good Google image for it,
    • 0:27:21if you're not familiar with a Bump Map.
    • 0:27:25Let me go in here.
    • 0:27:30I'm going to hope that there's no shady images on Google Images, but a Bump
    • 0:27:35Map--
    • 0:27:37can we see it?
    • 0:27:37Well, it's kind of hard to tell.
    • 0:27:41But in a lot of 3D games, you'll see like bumpiness and shininess
    • 0:27:46on surfaces.
    • 0:27:47And that's accomplished the majority of the time using Bump Mapping.
    • 0:27:51Because obviously, if you were to model every single tiny little bump or model
    • 0:27:55in a surface, it would get extremely difficult to render large objects.
    • 0:27:59Because you're looking at thousands of polygons for a surface
    • 0:28:02that was actually this detailed in a game.
    • 0:28:06So what you do is, you take what's called a Bump Map,
    • 0:28:09and the Bump Map gets--
    • 0:28:11during lighting, it will effectively skew the surface normals of a 3D mesh.
    • 0:28:18So effectively, it will pretend as if your 3D mesh has a bunch of bumps in it
    • 0:28:23for the lighting.
    • 0:28:26Only for the lighting.
    • 0:28:27And so when it gets lit, and it gets shaded, it looks as if it's bumpy,
    • 0:28:32but you're still dealing with a completely flat, completely
    • 0:28:35simple cubic mesh in this case, or whatever mesh you want.
    • 0:28:39And so the long story short, here, if you
    • 0:28:43wanted to include a Bump Map on whatever surface you want to scroll,
    • 0:28:45or if you want to edit the Bump Map, this
    • 0:28:47is here just because you can also manipulate the Bump Map texture offset.
    • 0:28:52It's an included field in a material.
    • 0:28:58So any questions as to how this works at large?
    • 0:29:02We still have a lot to cover before we go into a lot of the specifics.
    • 0:29:06But conceptually, do we understand how this sort of works?
    • 0:29:11OK?
    • 0:29:12Cool.
    • 0:29:12So let's go back to the slides.
    • 0:29:18Right.
    • 0:29:18So we were talking about game objects.
    • 0:29:20So all of those things that we saw before were just game objects.
    • 0:29:25So let's go back to the default layout, and then we can look back at our scene.
    • 0:29:32So this is our scene.
    • 0:29:33All of those things were all of our game objects.
    • 0:29:36Those are ultimately containers.
    • 0:29:38I talked about this in a prior lecture.
    • 0:29:39But this is the beginning of an entity component system, in which case,
    • 0:29:43these game objects are our entities.
    • 0:29:45They are the entity class--
    • 0:29:47container class-- for what drives behavior.
    • 0:29:50And the thing that allows us to actually get interesting behavior out
    • 0:29:55of this sort of abstraction is the use of components.
    • 0:29:59And we'll talk about that.
    • 0:30:01So components are all of the things on the right-hand side,
    • 0:30:05by default of the Unity editor.
    • 0:30:07So if we're looking at our camera, for example,
    • 0:30:09and we take a look at all these things on the right,
    • 0:30:12we can see that we have something called a transform,
    • 0:30:14we have something called a camera.
    • 0:30:16A GUI layer deprecated, so that's by default.
    • 0:30:19It was imported from a prior version of Unity,
    • 0:30:21so you could actually delete this.
    • 0:30:23A flare layer, which we're not using.
    • 0:30:26An audio listener-- I believe that comes with all cameras by default,
    • 0:30:29though, in case you do want to use it.
    • 0:30:30An audio listener and an audio source.
    • 0:30:33So all of these different pieces are components.
    • 0:30:37They are what drive the behavior of this game object.
    • 0:30:40We can create just a brand new, empty game object-- oops,
    • 0:30:43I created it as a child.
    • 0:30:45We can create a brand new, empty game object here.
    • 0:30:48It's just a game object in our scene.
    • 0:30:51And it's right where our mouse is.
    • 0:30:55Well, it's right here.
    • 0:30:56And it does nothing.
    • 0:30:59It has one component.
    • 0:31:01And that component is the transform.
    • 0:31:03Anybody guess what a transform is?
    • 0:31:08Yeah.
    • 0:31:09AUDIENCE: Is that position, rotation, scale, et cetera?
    • 0:31:11COLTON OGDEN: Yes.
    • 0:31:12It is the position, rotation, and scale of a game object.
    • 0:31:16Something that was before put into six fields--
    • 0:31:20or in this case, nine fields, potentially, or maybe
    • 0:31:22three fields with children, is now an object that we can modify at will.
    • 0:31:29Well, it's a component that we can modify at will.
    • 0:31:32So if I do this-- notice, I'm just scrolling the x.
    • 0:31:36It's just moving that transform, which is just the position of that object.
    • 0:31:40And Unity knows to look at the transform component,
    • 0:31:44and render our object based upon where its transform lies,
    • 0:31:47rather than us having to manually set all these things, which we still
    • 0:31:51can do in the code.
    • 0:31:52We can just modify them in the Unity editor
    • 0:31:55directly via a graphical interface.
    • 0:31:57It's just an interesting, helpful layer of abstraction.
    • 0:32:01So a transform is a component-- a camera, in this case.
    • 0:32:05It's just a component.
    • 0:32:06We can attach this to anything we want to, and it becomes a camera.
    • 0:32:09And then we can set it to be either the default camera or not.
    • 0:32:13The camera has a bunch of different things.
    • 0:32:15And I can't claim to know all of the fields of every object
    • 0:32:18in Unity, because there's just a tremendous number of things.
    • 0:32:21But clear flags, background, culling mask--
    • 0:32:24all these things that are relevant to how the camera does its job--
    • 0:32:29they are all things that we have complete access
    • 0:32:31to here in the Unity editor.
    • 0:32:32We don't even need to touch code, really, for a lot of things.
    • 0:32:36An interesting fun thing we can take a look at
    • 0:32:38is if we go to Layouts-- go back to two by three, and take a look at our game
    • 0:32:43again.
    • 0:32:44So we have our camera currently looking at the screen here.
    • 0:32:51It's just always in one spot.
    • 0:32:52And it has a way of projecting the scene.
    • 0:32:55It can do one of two things.
    • 0:32:57It can be perspective projection or orthographic projection.
    • 0:33:03Does anybody know what the difference is between the two, at least visually?
    • 0:33:08So perspective projection-- what that does
    • 0:33:11is it models how real cameras, real lenses, the human eye, et cetera,
    • 0:33:15behave in real life.
    • 0:33:17Things distort a little bit.
    • 0:33:19And so you see things, depending on where you're looking at them,
    • 0:33:22they look wider or skewed, and not completely geometrical,
    • 0:33:27like you would if you were just to draw them at a certain distance.
    • 0:33:31Things have vanishing points, et cetera.
    • 0:33:34Orthographic-- things look a lot different.
    • 0:33:36So notice instantly, so we can see here, perspective
    • 0:33:40doesn't really change a whole lot visually with our helicopter.
    • 0:33:44Things do change a little bit with the background,
    • 0:33:46because the view angle is different between the two--
    • 0:33:50the perspective and the orthographic camera.
    • 0:33:52But if we make this a little bit larger.
    • 0:33:55So I'm going to increase the size like that.
    • 0:34:02And I play.
    • 0:34:05One thing we'll notice--
    • 0:34:06what's the first thing that folks are noticing?
    • 0:34:10You can actually see the difference between the top and the bottom.
    • 0:34:14Whoop.
    • 0:34:16How, in particular, I'll put your attention towards the buildings.
    • 0:34:20How do the buildings differ?
    • 0:34:22AUDIENCE: You can't see the side.
    • 0:34:23COLTON OGDEN: You can't see the side anymore.
    • 0:34:27The lens sort of curves a bit.
    • 0:34:30And so I'm not entirely familiar with all the math involved.
    • 0:34:34But at the end of the day, what it boils down to is, with a perspective camera,
    • 0:34:38you can actually gauge things as distance
    • 0:34:40relative to each other a little bit better.
    • 0:34:42With a orthographic camera, everything is completely flat,
    • 0:34:45and no matter how far away from you it is
    • 0:34:47on the access that's completely perpendicular to you,
    • 0:34:51it's going to look the exact same.
    • 0:34:53So these buildings are always going to look the exact same, no matter how far
    • 0:34:55away they are, no matter which position they are.
    • 0:34:57Because everything is just looked at completely flat.
    • 0:35:00And the view matrix is calculated in a different way.
    • 0:35:06And so, just with a simple button, you can
    • 0:35:09change how your game looks completely.
    • 0:35:12You've probably seen a lot of games.
    • 0:35:13I believe Crossy Road does everything with a orthographic camera,
    • 0:35:17versus a perspective camera.
    • 0:35:18It has a very distinctive look, especially
    • 0:35:21once you skew things a little bit.
    • 0:35:23But that's just one thing that you can change just
    • 0:35:26without having to touch a single line of code--
    • 0:35:28how your game looks via just the camera's implementation.
    • 0:35:32Let's take things back to how it was.
    • 0:35:36And there's a lot of things like the field of view.
    • 0:35:38So if you want to see more of the game world.
    • 0:35:40So things like in Quake and other shooters,
    • 0:35:42you can change this view, usually in your menu settings,
    • 0:35:46just so you can see more around you.
    • 0:35:49And it looks a little like a fisheye lens a little bit,
    • 0:35:51depending on how you do it.
    • 0:35:52And that's just more distortion of the perspective projection.
    • 0:35:58Yeah.
    • 0:35:59All of these things, they all have--
    • 0:36:00I don't know necessarily what every single one of them does,
    • 0:36:03just because there's just a lot involved.
    • 0:36:05And generally, you don't have to mess with it too much.
    • 0:36:07It just ultimately depends on what you are trying to accomplish in your game.
    • 0:36:11And you'll end up finding specific areas of the editor
    • 0:36:14and specific areas of the code base and documentation
    • 0:36:16that you dive deeply into.
    • 0:36:18But this essentially is what a component affords you the ability to do.
    • 0:36:23When you create a component and you attach it to a game object,
    • 0:36:26you can easily not only combine different things
    • 0:36:29to create this emergent new behavior and combination
    • 0:36:33of behaviors for your game objects.
    • 0:36:36But Unity allows you, via different ways of programming the components,
    • 0:36:40to modify them, depending on how customizable you want them to be,
    • 0:36:45in the editor itself.
    • 0:36:46So you don't have to touch any of this in code.
    • 0:36:49You can just go into the editor and quickly
    • 0:36:51whip things up because of the way that you've modeled all your components.
    • 0:36:55And so we see other things like the audio listener.
    • 0:36:58An audio listener is something that will literally listen for audio,
    • 0:37:01and play it back like a microphone to the game player.
    • 0:37:04And then an audio source is an actual source of audio.
    • 0:37:07And so it will play that audio at the location
    • 0:37:09of whatever that game object is.
    • 0:37:11So we've combined all these things.
    • 0:37:13So now we have a camera that is projecting everything
    • 0:37:17with perspective projection.
    • 0:37:19And it's an audio listener, so it's going to listen for audio in our scene.
    • 0:37:24And it's also going to play an audio source and listen to itself.
    • 0:37:29And that's just the beginning.
    • 0:37:30We have a whole bunch of other components
    • 0:37:32here, which we can take a look just really quickly.
    • 0:37:35So the directional light has a light component.
    • 0:37:39And so a light, you can do all kinds of things.
    • 0:37:41You can make a spotlight, directional light, point light.
    • 0:37:44All these look a little bit differently.
    • 0:37:46You can make it have a specific color.
    • 0:37:48So maybe if you wanted a really dark scene, you could have a dark light.
    • 0:37:53Or you could even emulate dawn or dusk with an orange light.
    • 0:37:57That's sort of how you'd go about doing that.
    • 0:38:01You can bake your lighting, which means that you just pre-compute it,
    • 0:38:04so that you don't have to render it in real time
    • 0:38:06when you actually play it on hardware.
    • 0:38:07A lot of different things, a lot of different settings.
    • 0:38:09We don't have time necessarily to go into all of them.
    • 0:38:11But looking through all of these, you can
    • 0:38:13see all these game objects are just combinations of these components.
    • 0:38:17And those combinations of components are responsible for the behavior
    • 0:38:24that we get in our game.
    • 0:38:25That's the ultimate essence of what Unity is, and how it does what it does.
    • 0:38:29And to illustrate the difference, we've talked about this before.
    • 0:38:32This is an inheritance chain, where Monster
    • 0:38:35inherits from Creature, which then goes to Goblin, Goblin Chief, Elite Goblin
    • 0:38:38Chief.
    • 0:38:39In Unity, you could create a game object,
    • 0:38:42and then give it a creature component, a goblin component, a patrol component--
    • 0:38:47right?
    • 0:38:47So maybe you want different things to patrol.
    • 0:38:52In Unity, it would be kind of complicated.
    • 0:38:53But you could create basically a pathway,
    • 0:38:57and then have your entity follow that pathway at a specific time.
    • 0:39:02And then, depending on how you've programmed it,
    • 0:39:04you could specify all these different characteristics in the editor.
    • 0:39:07So you could just say on the editor, OK, I
    • 0:39:09want you to go patrol from this range to this range.
    • 0:39:12And I want you to do it with this length of time, pause for this long--
    • 0:39:15right?
    • 0:39:16And then you can give that to anything in your scene.
    • 0:39:18You could make a camera patrol if you wanted to,
    • 0:39:21and then have that be demo code for the beginning of your game.
    • 0:39:24The flexibility is just insane.
    • 0:39:26Elite component.
    • 0:39:27Right?
    • 0:39:27If you want, maybe, certain enemies or certain objects, if they're elite,
    • 0:39:31maybe they shine bright.
    • 0:39:32And maybe they drop more experience or something.
    • 0:39:34A chief component maybe has better weaponry than a non-chief component.
    • 0:39:38And then a toxic component, maybe, is an enemy that, when it dies,
    • 0:39:41it sprays toxic gas or toxic liquid all over the place.
    • 0:39:46But the flexibility is there.
    • 0:39:48You can ascribe any component to any object to get any sort of behavior
    • 0:39:52that you want to.
    • 0:39:53It's on you, of course, to implement all these components, right?
    • 0:39:56You're not going to get all these for free.
    • 0:39:57You're going to get a lot for free.
    • 0:39:59Unity gives you a ton of components-- really good components.
    • 0:40:04But you're ultimately going to need to program your game logic.
    • 0:40:07And so you'll have to implement all these things-- elite,
    • 0:40:10goblin, what it means to be all these things.
    • 0:40:12But thankfully, it's not terribly painful.
    • 0:40:15The way at which we go about doing all of this-- and by the way,
    • 0:40:19are there any questions so far as to how Unity's model works,
    • 0:40:23the difference between composition versus inheritance,
    • 0:40:25anything we've talked about this far?
    • 0:40:28All right.
    • 0:40:30The way at which we actually go about making our own components,
    • 0:40:35which is probably what you'll spend the most of your time doing,
    • 0:40:38at least in the beginning, when you're bootstrapping your game,
    • 0:40:41is programming what's called a MonoBehaviour.
    • 0:40:45And so we talked about Mono before.
    • 0:40:48So Mono is the open source implementation of the CLR.
    • 0:40:52And MonoBehaviour, I imagine--
    • 0:40:54I tried to look this up and see where it derives from.
    • 0:40:56I imagine it's because it was originally a Mac exclusive project, Unity.
    • 0:41:03And so because everything was implemented in Mono,
    • 0:41:05and because this is way it's scripted, MonoBehaviour became the name.
    • 0:41:11But a MonoBehaviour is what a component is.
    • 0:41:14They are effectively one and the same.
    • 0:41:16The difference being that a MonoBehaviour
    • 0:41:18is how it's illustrated in code.
    • 0:41:19In C#, if you want to program something to be a component that you can then
    • 0:41:23attach to a game object, it needs to be inherited from MonoBehaviour.
    • 0:41:31So if we go to coin spawner, here.
    • 0:41:37And you can see the difference between what's built in to Unity
    • 0:41:40and what's your own via--
    • 0:41:42it'll say script here.
    • 0:41:44So in this case, I have a coin spawner object, right?
    • 0:41:46It's just an empty object, at least in terms of what it displays.
    • 0:41:51It's got a transform, which is irrelevant.
    • 0:41:53It could be literally anywhere in our entire scene.
    • 0:41:56The only difference between this and the empty game
    • 0:42:00object that we saw before is that it has a coin spawner.
    • 0:42:04And this coin spawner has this thing here.
    • 0:42:10All components that you add would have this script field here,
    • 0:42:14just to show you that that's the script that it's
    • 0:42:17getting it's code behavior from.
    • 0:42:19But also, we have this field here called prefabs, which has a size of 1.
    • 0:42:25And it's actually calculated based on how many elements
    • 0:42:29the list that it's responsible for has.
    • 0:42:32And we have one element, as it says, here.
    • 0:42:35And it's got a coin pre-fab, which is here.
    • 0:42:38And notice that I clicked on it.
    • 0:42:40It took me right to it in my assets.
    • 0:42:42And so prefabs and all of that-- what that means and how to get
    • 0:42:45that all working-- we'll talk about that.
    • 0:42:47But a coin spawner script has to exist in our code base
    • 0:42:54before we can actually add it to any game objects, right?
    • 0:42:58So in my project I do have--
    • 0:43:02usually, you have assets, a folder called Assets in your Unity Project.
    • 0:43:06And then I typically create a Resources folder.
    • 0:43:09It's not mandatory that you do so, but just for organization, I'll
    • 0:43:12create a Resources.
    • 0:43:14And then I'll have a bunch of folders for all sorts of different things
    • 0:43:17like we've done before.
    • 0:43:18Where in the Love2D project, at the parent level,
    • 0:43:21you have like a Fonts, a Music or Sounds, and then a source directory.
    • 0:43:27In this case we have Fonts, Materials, Models,
    • 0:43:30all the different assets that we will need in our game,
    • 0:43:33but also a Scripts folder.
    • 0:43:35And all the C# scripts here that we'll use amongst all of our components--
    • 0:43:41all of our game objects.
    • 0:43:43And so you could easily just go to any of these,
    • 0:43:46rather than have to go into your operating system, open up a new window,
    • 0:43:50and find your file, and navigate through all the files
    • 0:43:53that Unity generates for you, which can be kind of a pain.
    • 0:43:56You can just double-click on a coin script, for example.
    • 0:43:59And it'll open in your default editor.
    • 0:44:02And so one thing that I'll just mention here
    • 0:44:06is, if you go to your Unity preferences--
    • 0:44:08on Mac, it's Unity and then Preferences--
    • 0:44:11you can go to External Tools.
    • 0:44:12So by default, starting in 2018, Unity is transitioning away
    • 0:44:15from its prior IDE, which was called MonoDevelop, which was a good IDE.
    • 0:44:19There's transitioning away from that, and they're
    • 0:44:21making it focused on Visual Studio as the default IDE.
    • 0:44:26I don't use Visual Studio.
    • 0:44:28I like VS Code.
    • 0:44:29So what I did was-- and what you can do is--
    • 0:44:33you can choose your external script editor here,
    • 0:44:35if you prefer a different script editor-- like Atom,
    • 0:44:37or VS Code, or Sublime Text.
    • 0:44:40And then just browse for it on your file system,
    • 0:44:42whether you're on a Windows, Linux, or Mac machine.
    • 0:44:44And then you can easily just choose which file you want.
    • 0:44:47In this case, I chose VS Code.
    • 0:44:48And so that effect that that has is, whenever
    • 0:44:50I double-click on a script within Unity, it
    • 0:44:53will actually open the IDE or text editor
    • 0:44:56that I have assigned to it in Unity's preferences.
    • 0:45:00And so here is the Coin component that I have created for this example.
    • 0:45:08And notice that every component, first of all, is a class.
    • 0:45:13And actually, everything effectively in C#, just as in Java, is a class.
    • 0:45:20It's a public class.
    • 0:45:21And notice that I call it Coin, and I got this colon, and then MonoBehaviour.
    • 0:45:26So this colon-- anybody know, anybody take a guess what the colon means?
    • 0:45:30Tony?
    • 0:45:31TONY: Extends.
    • 0:45:31COLTON OGDEN: Extends, yes.
    • 0:45:32Extends or inherits from MonoBehaviour.
    • 0:45:36So anytime you have a component that you want
    • 0:45:38to create, you want to add it to Unity, and allow you to see it in the editor,
    • 0:45:41and allow you to actually drive behavior of an object,
    • 0:45:45you need to inherit from MonoBehaviour.
    • 0:45:47Like it says here on my VS Code, since I have the extension for OmniSharp,
    • 0:45:52it will actually tell me, MonoBehaviour is the base class
    • 0:45:55from which every Unity script derives.
    • 0:45:59There's a couple of things here.
    • 0:46:00So notice that we have a few methods.
    • 0:46:03So void Start, void Update, and void OnTriggerEnter.
    • 0:46:10So anybody take a guess as to what--
    • 0:46:12ignoring OnTriggerEnter-- does anybody have
    • 0:46:14a guess as to what Start and Update do?
    • 0:46:16Yeah.
    • 0:46:17AUDIENCE: Could it be just like that and [INAUDIBLE] update [INAUDIBLE]??
    • 0:46:21COLTON OGDEN: Sorry, say it one more time.
    • 0:46:22AUDIENCE: Would it just [INAUDIBLE] an update or [INAUDIBLE]??
    • 0:46:24COLTON OGDEN: Exactly.
    • 0:46:25It would be just like we did before when we created objects
    • 0:46:29in our Love2D projects, where we had an init function assigned to every class,
    • 0:46:35and an update function assigned to every class.
    • 0:46:37And we would call those ourselves.
    • 0:46:39Every MonoBehaviour can have a Start method.
    • 0:46:44In this case, it's empty, because every time you
    • 0:46:46create a new script by the Unity editor, it will automatically-- first of all,
    • 0:46:50it will automatically create a brand new file for you.
    • 0:46:53So let's just say I want to create a new script.
    • 0:46:55So if I'm in the Unity editor, and I go to my assets--
    • 0:46:58I right-click Create.
    • 0:47:00And then I want to create a new C# script.
    • 0:47:03It'll create it there.
    • 0:47:04I can say, maybe I want this to be--
    • 0:47:06I don't know-- Test Component, right?
    • 0:47:11So this should have the effect of, when I open it in my VS Code,
    • 0:47:15this Test Component-- this was auto generated for us.
    • 0:47:18We didn't have to write any of this boilerplate.
    • 0:47:20But every script that you create, by default,
    • 0:47:26is a MonoBehaviour, which it strictly does not have to be.
    • 0:47:29You could create a class of your own, that maybe you call behind the scenes,
    • 0:47:34or maybe it just represents a data structure or something.
    • 0:47:36But by default, anytime you create a new script in Unity,
    • 0:47:39it'll save you the hassle of typing out all this stuff by hand.
    • 0:47:43And it'll give you an empty Start method and an empty Update method.
    • 0:47:48And so, like Tony said, the Start method gets called as soon as the object
    • 0:47:53that it's assigned to gets instantiated.
    • 0:47:55Well, as soon as this component gets instantiated, rather.
    • 0:47:59Which often is the case that it gets instantiated
    • 0:48:03at the same time as a game object.
    • 0:48:05Not always.
    • 0:48:06You can create game components on the fly.
    • 0:48:10But this Start method will get called.
    • 0:48:12Anything that you put in here will get called right away.
    • 0:48:14And then this Update method, Unity will-- every frame,
    • 0:48:17go through every component on every live game object--
    • 0:48:20and will call the code that's contained within this Update function.
    • 0:48:26And you don't have to call this anywhere yourself.
    • 0:48:28Just by assigning this component to a game object in your scene,
    • 0:48:34you get the update, and start, and all this other functionality
    • 0:48:38given to you for free.
    • 0:48:40And MonoBehaviours are actually much more complex
    • 0:48:43than just Start and Update.
    • 0:48:48So if you go to MonoBehaviour here, we can see that--
    • 0:48:56by the way, I want to shout out Unity's documentation.
    • 0:48:59Unity has amazing documentation--
    • 0:49:01docs.unity3d.com.
    • 0:49:02You will go through pretty much everything
    • 0:49:05you possibly could ever want with every object implemented in Unity, in quite
    • 0:49:10a good detail, with a lot of examples.
    • 0:49:12But here we can see, just in the description,
    • 0:49:14it will tell us, the MonoBehaviour will get start, update, fixed update, late
    • 0:49:23update, on GUI-- all of these functions called for us, assuming
    • 0:49:26that they're implemented.
    • 0:49:27And you don't have to implement them if you don't want to.
    • 0:49:30If they're not implemented, they just won't happen.
    • 0:49:32If there's no start method, then that means
    • 0:49:34there's no start logic for this component.
    • 0:49:35So it doesn't need to execute.
    • 0:49:37If there's no update, maybe it just needs to start at the very beginning,
    • 0:49:39but never update after that, don't implement update.
    • 0:49:41And update will not be called.
    • 0:49:44All of these are optional.
    • 0:49:46That's just a small chunk of MonoBehaviour,
    • 0:49:48though, because you also have messages.
    • 0:49:51So messages are functions that you override.
    • 0:49:56As you can see, there's a whole lot of them.
    • 0:49:59And all of these messages get called, depending on certain things that
    • 0:50:02happen in the game scene.
    • 0:50:04So OnTriggerEnter, for example, if our object is a trigger, and we enter it,
    • 0:50:12then the behavior will get called in that function, which
    • 0:50:15will allow us to do things like-- if our helicopter enters a building,
    • 0:50:20we can call that helicopter's explode method,
    • 0:50:22which is literally what we do in this project, thanks to this function.
    • 0:50:26And all we really need to do is just a couple of lines of code.
    • 0:50:29It's very simple.
    • 0:50:31OnPostRender, OnPreRender-- all these different things
    • 0:50:34are called at different times.
    • 0:50:35You can look into all of these, if you want to, just by clicking on them
    • 0:50:38and looking at their documentation.
    • 0:50:41LateUpdate is called after all update functions have been called.
    • 0:50:44This can be relevant for certain physics calculations.
    • 0:50:49But there's a whole lot of different things you can do.
    • 0:50:53You don't necessarily need to do a lot of things yourself,
    • 0:50:56if Unity provides you with the function that gives you
    • 0:50:59the effect that you're looking for.
    • 0:51:00And so if you're curious, MonoBehaviour, and then the docs at large.
    • 0:51:03This is just all the documentation-- just an insane amount of documentation.
    • 0:51:07And that's just in the classes.
    • 0:51:09There's all these other little side areas, as well.
    • 0:51:14And so that's sort of what MonoBehaviour is.
    • 0:51:17It's a component.
    • 0:51:18It gets a lot of these functions called for you.
    • 0:51:20You don't have to implement them.
    • 0:51:21But if you do, you get a lot of functionality for free, basically.
    • 0:51:26Any questions as to what a MonoBehaviour is, how it works, and so forth?
    • 0:51:30Or any of the syntax we've seen thus far for creating a MonoBehaviour?
    • 0:51:37All right.
    • 0:51:38And so, here in our coin, for example, which we were looking at before,
    • 0:51:42notice that I'm referencing something called a transform.
    • 0:51:45Transform.position.x is less than negative 25, destroy a game object.
    • 0:51:51If this is the coin, what do we think that this is accomplishing?
    • 0:51:57AUDIENCE: It goes off the screen [INAUDIBLE]??
    • 0:51:59COLTON OGDEN: Yep.
    • 0:52:00So the transform, recall, was our component
    • 0:52:06that encapsulates our rotation, scale, and position.
    • 0:52:09So we can just say, if transform.position.x is less
    • 0:52:13than negative 25, destroy game object.
    • 0:52:17Because we're spawning the coins dynamically.
    • 0:52:19When they get off screen-- just like we did with the pipes, if you remember.
    • 0:52:22And I had a screenshot, actually, in that slide
    • 0:52:23that showcased what that looked like.
    • 0:52:25We can see that exact thing live here.
    • 0:52:29If I go to Layouts, two by three, and we play the game again,
    • 0:52:33and then I'll just die at some point.
    • 0:52:37But if we do this, we're seeing our scene live.
    • 0:52:42So we're following this-- yep.
    • 0:52:43See how the coin-- as soon as the building, and the plane,
    • 0:52:46and the coins all get to this point--
    • 0:52:48this is negative 25 in Unity units, not in pixels.
    • 0:52:53Everything in Unity is based on Unity units, which, by default,
    • 0:52:561 is equal to one meter, as opposed to-- we've been thus far using just pixels.
    • 0:53:02But pixels aren't viable in 3D.
    • 0:53:07[MUSIC PLAYING]
    • 0:53:10But that's effectively what that component does.
    • 0:53:12It's checking, in our Update function-- void Update--
    • 0:53:16if transform.position.x less than negative 25.
    • 0:53:20And notice that we don't actually have to declare transform
    • 0:53:23anywhere, which is interesting.
    • 0:53:26That's because MonoBehaviour, by default, gives you
    • 0:53:28access to its game objects transform just by default.
    • 0:53:32That's just something you get for free.
    • 0:53:35And then, notice gameObject-- we also haven't declared gameObject anywhere.
    • 0:53:39Because by default, we have access to gameObject.
    • 0:53:42It's the game object that this script belongs to.
    • 0:53:46That this component belongs to.
    • 0:53:48AUDIENCE: [INAUDIBLE]
    • 0:53:50COLTON OGDEN: This would be the actual--
    • 0:53:54so the interesting thing about the classes
    • 0:53:57is, you don't have to explicitly say this.
    • 0:54:00Because if you had int myNumber equals 10, and you just say, myNumber--
    • 0:54:08the difference between Lua and C# and Java is that,
    • 0:54:12it will already know what myNumber is, this is myNumber.
    • 0:54:16It will know its this objects.
    • 0:54:17AUDIENCE: Yeah.
    • 0:54:18COLTON OGDEN: You don't have to do that.
    • 0:54:23Sort of a nice little thing to save you a little bit of time.
    • 0:54:26Because you could then just say, myNumber plus equals 10.
    • 0:54:30Another nice thing about C#, by the way, which we didn't get in Lua--
    • 0:54:33you can do compound assignment operators.
    • 0:54:36So you can do plus equals, minus equals, times equals.
    • 0:54:38That's one of my little pet peeves I have with--
    • 0:54:40oh.
    • 0:54:41And notice that also, the nice thing about the fact that I
    • 0:54:43have OmniSharp-- it'll underline.
    • 0:54:45And this is just a trait of most IDEs, honestly.
    • 0:54:48So you get this with a lot of places.
    • 0:54:50But it'll tell you myNumber is not assigned, with the underlining,
    • 0:54:55and also just by hovering over it.
    • 0:54:57The named myNumber does not exist in the current context.
    • 0:55:00But I can just say, int myNumber.
    • 0:55:03And then it's gone.
    • 0:55:05A little bit more that we have to worry about,
    • 0:55:07and a little bit less that we have to worry about.
    • 0:55:09A little give and take.
    • 0:55:12But still, I think, overall, C# is going to be a lot more syntax-heavy.
    • 0:55:16You do have to worry about things like braces, and semi-colons,
    • 0:55:19and putting everything in a boilerplate.
    • 0:55:23And then, obviously, type declaration, and return type declaration.
    • 0:55:26It can be a little bit more than we've gotten used to so far.
    • 0:55:29But it's honestly not too bad, just given that you can use IDEs.
    • 0:55:34First of all, the fact that you're statically typing everything,
    • 0:55:37you can detect a lot more errors in advance.
    • 0:55:40If you're trying to do something with some type
    • 0:55:42that you're not supposed to do, like some function accepts
    • 0:55:45some object of some type, but you're passing in some other object,
    • 0:55:48you'll catch that in advance.
    • 0:55:50And so that's a really nice thing.
    • 0:55:53But yeah.
    • 0:55:54It is a give and take.
    • 0:55:57And also, IDEs will give you, like I said,
    • 0:56:00a lot of the functionality-- a lot of the autocomplete-- that
    • 0:56:03makes a lot of this more sustainable.
    • 0:56:05And it's not to say, of course, that Lua and Love2D don't have their own IDE.
    • 0:56:08Like ZeroBrane Studio is popular, from what I understand.
    • 0:56:11Haven't used it yet.
    • 0:56:12But particularly when you venture into Java, and C#, and compiled languages,
    • 0:56:16static languages-- having those features does save you a lot more time,
    • 0:56:20relatively speaking, than when you're in a dynamic language.
    • 0:56:25So that's what MonoBehaviours are.
    • 0:56:28Every component of our game effectively has-- like the helicopter
    • 0:56:32has its own script, a Heli Controller.
    • 0:56:35The coin has its own script-- the Coin Spawner, the Skyscraper Spawner,
    • 0:56:38the Skyscraper--
    • 0:56:39they all have their own scripts that drive their game behavior.
    • 0:56:42But they also have scripts and components that are part of Unity core,
    • 0:56:46as well.
    • 0:56:48Including Colliders and Triggers.
    • 0:56:50So if I'm looking in Unity--
    • 0:56:52so I'm going to go to--
    • 0:56:54and this will actually be the last thing we look at before we take a break.
    • 0:56:57But if I'm in Unity, and I'm going to go back to my default layout,
    • 0:57:03just because it's a little cramped on a 720p.
    • 0:57:06Go to my helicopter.
    • 0:57:09Helicopter's got a couple of pieces to it.
    • 0:57:11So let's actually go to where I can see it here.
    • 0:57:15So one of the awesome things I love about Unity
    • 0:57:17is, it gives you a lot of this editor magic-- this editor sort of sugar.
    • 0:57:23It shows you visually where a lot of the things are in your game world.
    • 0:57:27So the green rectangles-- anybody know what those are, or can guess?
    • 0:57:31AUDIENCE: Hit boxes?
    • 0:57:32COLTON OGDEN: Yep.
    • 0:57:33Hit boxes.
    • 0:57:34Exactly.
    • 0:57:36These are colliders.
    • 0:57:38So the blades-- it doesn't have a collider.
    • 0:57:41That blades collider is actually separate.
    • 0:57:44The box collider here is this collider right here.
    • 0:57:50And so a collider is literally just something
    • 0:57:53that collides with something else.
    • 0:57:54And you can set it to be a trigger or not.
    • 0:57:56If it's a trigger, then it actually won't trigger the OnTriggerCallback
    • 0:58:02function that we briefly saw earlier.
    • 0:58:07So the things that you want to activate triggers,
    • 0:58:10you should make those not triggers.
    • 0:58:12And then triggers, all you have to do is just click this little Trigger button.
    • 0:58:15So what a trigger is is just a region that you've determined--
    • 0:58:19or some object that you've determined-- should cause behavior
    • 0:58:22when it gets triggered.
    • 0:58:23So in this case, I've assigned--
    • 0:58:30actually, I'll just play it.
    • 0:58:33But the airplane has a trigger, right?
    • 0:58:44All of these things have colliders, whether they're triggers or not.
    • 0:58:48The helicopter-- its blades and its body--
    • 0:58:51there are two colliders, two boxes.
    • 0:58:55The coins all have colliders.
    • 0:58:57The skyscrapers will have colliders, and the airplanes have colliders.
    • 0:59:00The difference is that-- oh, and by the way, another cool thing.
    • 0:59:06It's easy to get very sidetracked, just because there's
    • 0:59:08so many cool things to talk about.
    • 0:59:10You can pause the game while it's running.
    • 0:59:12So it's paused right now, but it's in the exact state that I left it.
    • 0:59:17So there's three coins there.
    • 0:59:18I got my helicopter there.
    • 0:59:20I can freely go about the scene.
    • 0:59:21I can analyze things.
    • 0:59:23I can actually modify this in real time.
    • 0:59:26So I can change its rotation, if I want to.
    • 0:59:30Probably don't want to do that.
    • 0:59:32But I could if I want to.
    • 0:59:33I can change its position, right?
    • 0:59:35So I can move it left to right, like that.
    • 0:59:37And notice that I actually have just the body selected,
    • 0:59:39so the blades are kind of separate.
    • 0:59:42I don't even know what kind of crazy stuff
    • 0:59:43would happen if I just messed with this and just let it run.
    • 0:59:45I haven't tested it that crazily.
    • 0:59:47But you are allowed to step through.
    • 0:59:49Oh, OK.
    • 0:59:49It looks like they both just go.
    • 0:59:51Oh, yeah, because they're parented to the helicopter object.
    • 0:59:54So they're both going to align.
    • 0:59:56They're going to move at the exact same rate,
    • 0:59:58regardless of how far apart they are.
    • 1:00:02The individual objects.
    • 1:00:03But you can just step through your game's execution frame by frame,
    • 1:00:08and get a sense of--
    • 1:00:09if you're trying to pinpoint a bug, maybe, that's
    • 1:00:11position-based or something that's tricky
    • 1:00:13and you just haven't been able to find exactly what's going on.
    • 1:00:19You can look through your whole scene and all
    • 1:00:21of the fields of every object in step time,
    • 1:00:26just by stepping through-- this button here--
    • 1:00:28assuming that you're in pause mode.
    • 1:00:29And then just looking at all the components here on the right side.
    • 1:00:32Because those will all still update.
    • 1:00:34All these fields will update any time you perform
    • 1:00:37any changes in the actual scene.
    • 1:00:40So super helpful for debugging.
    • 1:00:42I know I've used it a bunch.
    • 1:00:44And then if I start again, or if I stop it,
    • 1:00:46the nice thing is, any of the changes that you
    • 1:00:49make while it's running to your object, they
    • 1:00:51don't get applied when you actually go back to the game.
    • 1:00:54So notice that I messed with the two pieces, I separated them.
    • 1:00:59And then I stopped the game.
    • 1:01:00It ended up going right back to where it was in the very beginning.
    • 1:01:04So all this gets just basically saved like a snapshot.
    • 1:01:06You can do whatever you want during your game, and then come back to it,
    • 1:01:10and it will all get reverted back to where it was.
    • 1:01:12Yeah.
    • 1:01:12TONY: So [INAUDIBLE] if you hit single player,
    • 1:01:15and I kept making changes while I'm not involved [INAUDIBLE]..
    • 1:01:20COLTON OGDEN: Yes.
    • 1:01:20So, yeah.
    • 1:01:21Tony just basically echoed what I just said, which was,
    • 1:01:24if you make changes in your game while it's running,
    • 1:01:27and you're trying to maybe tweak them such that it's perfect when you're
    • 1:01:31actually done, they don't get saved.
    • 1:01:32So you have to actually make a conscious effort to remember what you've done,
    • 1:01:36how you've changed different fields, to fix any bugs, if they do exist.
    • 1:01:40But it is something that can be disheartening or frustrating, if you
    • 1:01:45finally fix something, and then you forget what it is you changed.
    • 1:01:48And then you have to mess with it a whole bunch.
    • 1:01:50So remember all the changes you make, if they're
    • 1:01:52pertinent to your actual game's execution
    • 1:01:53and the debugging of your game.
    • 1:01:58And then there's also a console, as well, which is nice.
    • 1:02:02If you want to output things like JavaScript style on the web,
    • 1:02:08you can do console.log.
    • 1:02:09You can do the same thing with a debug call here in Unity.
    • 1:02:13I don't have any of those calls in the actual game.
    • 1:02:16But it is something that we'll look at going forward.
    • 1:02:19And it is something that can be very helpful
    • 1:02:21if you want to measure something or output something that you can't
    • 1:02:24necessarily look at in the inspector.
    • 1:02:26In the case of this game, most of anything that we want to take a look at
    • 1:02:29is visible in the inspector.
    • 1:02:30But if you have an algorithm, maybe you have a generator that's not visual,
    • 1:02:36like a level generator.
    • 1:02:37And you want to make sure that the data structure representing your level
    • 1:02:41is generating things properly, you can output everything maybe via hashmarks
    • 1:02:44or something in your console, and actually
    • 1:02:46see it that way when you're running the code,
    • 1:02:48rather than having to run the actual game and look through it that way.
    • 1:02:52Some things just are hard to model in the editor,
    • 1:02:55and still need console output.
    • 1:02:57So the console is there to help you.
    • 1:02:59And so debug.log is the function, I believe,
    • 1:03:02that you need to see all that stuff.
    • 1:03:07Right.
    • 1:03:07Colliders and triggers.
    • 1:03:08So we had a little bit of a tangent there,
    • 1:03:10but the helicopter is comprised of these three things.
    • 1:03:14But the blades collider should have ultimately
    • 1:03:16been merged with the blades object here.
    • 1:03:18But we can think of it as the blades and the body.
    • 1:03:21The reason they're separated-- well, there's two reasons they're separated.
    • 1:03:26One core reason they're separated is they're just different sizes.
    • 1:03:30So the blades are longer than the body.
    • 1:03:32And so we have, for that reason, two separate colliders.
    • 1:03:35So we're looking at the helicopter here.
    • 1:03:38We can see that the collider for the blades
    • 1:03:42extends a little bit farther than the body.
    • 1:03:44We don't want to create a box collider for the entire helicopter,
    • 1:03:48because a box collider right that goes out here, for example,
    • 1:03:52might not be super fair if we're just coming right
    • 1:03:54over a building, and our body--
    • 1:03:59maybe the building's right here, and we just miss it.
    • 1:04:01We don't want that to be collided with.
    • 1:04:03So sometimes you'll need to combine colliders
    • 1:04:05to accomplish the collision detection behavior you're looking at.
    • 1:04:09The nice thing about box colliders, which we're using here,
    • 1:04:11is that they're not very expensive, because they're just boxes.
    • 1:04:14It's easy to compute 3D box collision with other things that are 3D boxes.
    • 1:04:19And that's actually a topic in its own is,
    • 1:04:23taking a complicated model or object, and then breaking it down,
    • 1:04:27not in terms of what it looks like to be collided with,
    • 1:04:29but how you can simplify the collision detection of something,
    • 1:04:32like a character, by just modeling its arms, its body, its legs, as cylinders
    • 1:04:38or boxes, rather than complicated geometry.
    • 1:04:42You usually don't want to do peer geometry collision for anything,
    • 1:04:45because that gets really expensive.
    • 1:04:48You want to try and aim for simple shapes to be your colliders.
    • 1:04:52And Unity gives you a lot of simple shapes
    • 1:04:54by default. If you look at, for example, in our helicopter--
    • 1:04:59if you wanted to add a component-- which, by the way,
    • 1:05:01you can easily do here, just in the component inspector.
    • 1:05:05If you're looking at the bottom right, there's an Add Component button.
    • 1:05:08So you can add any of the components that you've written,
    • 1:05:12and also all the components that Unity gives you by default.
    • 1:05:15So if we look at it by collider, we can see
    • 1:05:16there's a lot of different colliders that Unity gives us for free.
    • 1:05:19Polygon collider, mesh collider, box collider, capsule collider.
    • 1:05:25I try and strive for boxes as much as I can.
    • 1:05:28Spheres aren't bad.
    • 1:05:29Spheres are usually fairly easy to calculate, as well.
    • 1:05:31But boxes are the easiest.
    • 1:05:33Capsules are pretty easy, too.
    • 1:05:35A lot of players will be capsule colliders, because characters usually
    • 1:05:39have rounded heads.
    • 1:05:40So emulating the collision for their head with a capsule makes more sense.
    • 1:05:45And we'll look at that, actually, next week, when we use a first-person
    • 1:05:48component that we can get for free.
    • 1:05:49The default collider for it is a capsule.
    • 1:05:55But the blades and the body both have their own collider.
    • 1:06:02They're not triggers.
    • 1:06:04But if we look at our prefabs--
    • 1:06:08which we'll take a look at what a prefab is shortly--
    • 1:06:10a skyscraper has a box collider which is a trigger, as we can see here.
    • 1:06:16And the coin is a trigger.
    • 1:06:18And the airplane is a trigger.
    • 1:06:20So these things all trigger, except other colliders that aren't triggers.
    • 1:06:27And if it detects a collision with a collider that's not a trigger,
    • 1:06:30it will call the OnTriggerEnter function,
    • 1:06:33which we saw is something that you can get with MonoBehaviour.
    • 1:06:36Yeah.
    • 1:06:37AUDIENCE: Could you have two values if you want to call the special
    • 1:06:41function two at the same time, you'd have the regular [INAUDIBLE]..
    • 1:06:44Is there an easier way to do that?
    • 1:06:47COLTON OGDEN: Can you give me a specific example?
    • 1:06:49AUDIENCE: Well, if I want to have a pinball game or something,
    • 1:06:53I'd want to model functioning when my ball hits something.
    • 1:06:58But at the same time, I just don't it to bounce off of stuff.
    • 1:07:01COLTON OGDEN: Oh, yeah.
    • 1:07:02AUDIENCE: So you could do that?
    • 1:07:03COLTON OGDEN: So the question was, can I implement such that, for example,
    • 1:07:09in a pinball game, if I have a ball that collides with something
    • 1:07:12and causes a trigger to occur, but also have it bounce off of something.
    • 1:07:15And you would do that with a rigid body.
    • 1:07:17So you give it a rigid body.
    • 1:07:19In this case, I actually gave a rigid body to the helicopter
    • 1:07:23because the original goal of mine was to have it be affected by gravity.
    • 1:07:26But it turned out that I actually liked it a little bit better without gravity.
    • 1:07:29So this rigid body isn't strictly necessary.
    • 1:07:32But it has a gravity component that you can
    • 1:07:34assign to it that will actually, then, calculate gravity, and pull it
    • 1:07:39down wherever-- you have a global gravity definition that's
    • 1:07:44in your Unity settings that will affect it that way.
    • 1:07:47And so what you would do is, you would give your ball a rigid body.
    • 1:07:51And other things that you want it to bounce off of those,
    • 1:07:53those also have rigid bodies.
    • 1:07:55And they can be kinematic or not, basically,
    • 1:07:59which we talked about before.
    • 1:08:00Kinematic can move, but not be affected by other objects.
    • 1:08:05And so the object that's a trigger, you still trigger code, it does something.
    • 1:08:10So your pinball machine, when it collides with something,
    • 1:08:12and it triggers that thing, it'll still trigger that code.
    • 1:08:17So whether that's increment your score, or cause something
    • 1:08:19to flash, a part of it will flash, or play a sound,
    • 1:08:22it'll do that in your OnTriggerEnter.
    • 1:08:23But your rigid body will also perform its work,
    • 1:08:26and bounce off of whatever it--
    • 1:08:28assuming that you don't destroy it with that OnTriggerEnter function,
    • 1:08:32it will bounce off of that surface, and behave in the way
    • 1:08:35that you are alluding to.
    • 1:08:37Does that make sense?
    • 1:08:40All right.
    • 1:08:41Cool.
    • 1:08:44So all these things have triggers.
    • 1:08:47The IsTrigger flag--
    • 1:08:49I mean, that's as easy as we need it to be.
    • 1:08:51So you just give a box collider.
    • 1:08:52And the nice thing about box collider, too,
    • 1:08:54is if your mesh is a box, or square, or rectangular,
    • 1:09:00it will usually just fit it perfectly to whatever you're trying to assign it to.
    • 1:09:04So in this case, I remember adding the box colliders for these skyscrapers.
    • 1:09:07It just-- because they're all rectangular, or cubical--
    • 1:09:12I don't know.
    • 1:09:12What's the rectangular 3D?
    • 1:09:14I forget the term.
    • 1:09:15What is it?
    • 1:09:16AUDIENCE: Rectangular prism.
    • 1:09:17COLTON OGDEN: Rectangular prism, yes.
    • 1:09:19Because they're all rectangular prisms, the box collector fits them.
    • 1:09:23It'll scale the right way.
    • 1:09:25When you have differently weird shaped objects,
    • 1:09:27it'll just basically be as big as it needs
    • 1:09:30to be to completely encapsulate it.
    • 1:09:32But like I said before, because the helicopter has got some weird geometry,
    • 1:09:37if we were to do that, it would by default just be this entire box here,
    • 1:09:41because this is the farthest it goes out on this particular axis.
    • 1:09:45So we want to combine meshes to produce the collision
    • 1:09:50behavior that we're looking for.
    • 1:09:52And the trigger enter bit is relevant because, if your game object is
    • 1:10:02a trigger, then once we collide with that object,
    • 1:10:09we want-- and by default, when you do OnTriggerEnter,
    • 1:10:11it will look for the collider on this object.
    • 1:10:15It's going to take in a collider other, right?
    • 1:10:18And what that is is the other collider-- the thing
    • 1:10:21that's colliding with this object, with this coin.
    • 1:10:24So the helicopter, because it's the only other object in our scene
    • 1:10:27that has a non-trigger collider.
    • 1:10:31OnTriggerEnter-- this is going to be a helicopter.
    • 1:10:33We can just say other.transform.parent, because our helicopter has children,
    • 1:10:38which have the actual colliders, and a parent has the helicopter controller
    • 1:10:42component.
    • 1:10:43We're going to GetComponent the HeliController.
    • 1:10:47So we're going to go through our that objects, that other
    • 1:10:50that collided with us.
    • 1:10:51We're going to get its transform parent.
    • 1:10:54We're going to do GetComponent, which is a function that will just look
    • 1:10:57through all of its list of components.
    • 1:10:59We specify which component we want using this identifier here.
    • 1:11:03So of class HeliController.
    • 1:11:06And these angle brackets are the generic type specifier
    • 1:11:16syntax, which basically looks for it.
    • 1:11:17You could pass in any type here, effectively,
    • 1:11:20and GetComponent will look at whatever type is in here,
    • 1:11:23and get the component of that type, specifically.
    • 1:11:25So you do have some sort of type flexibility in C#,
    • 1:11:29but you have to go the extra mile and specify it,
    • 1:11:32and implement functions that take generic arguments like this.
    • 1:11:35Which is similar to Java, and C++, and other languages that do it that way.
    • 1:11:41And then once we've gotten that component of type HeliController,
    • 1:11:45with this function call, we execute PickupCoin,
    • 1:11:50which is a function that's part of the HeliController.
    • 1:11:53Any guesses as to what PickupCoin does?
    • 1:11:59AUDIENCE: [INAUDIBLE]
    • 1:12:00COLTON OGDEN: Sorry?
    • 1:12:01AUDIENCE: Increments the coin counter and tells the coin to disappear.
    • 1:12:04COLTON OGDEN: Increments the coin counter, calls the coin to disappear.
    • 1:12:06Well, it actually doesn't call the coin to disappear, because we do that here.
    • 1:12:09AUDIENCE: Oh.
    • 1:12:10COLTON OGDEN: Destroy game object--
    • 1:12:13game object is going to be this coin that's executing this function.
    • 1:12:17There's one more thing, too.
    • 1:12:18Do you remember what happens when we pick up a coin?
    • 1:12:21Exactly.
    • 1:12:21The particle effect.
    • 1:12:22It triggers a particle effect.
    • 1:12:23We can go to the HeliController class and take a look at that.
    • 1:12:28PickupCoin.
    • 1:12:31Here, coinTotal plus equals 1.
    • 1:12:33GetComponent AudioSource.
    • 1:12:37Play.
    • 1:12:38So it's a little bit weird.
    • 1:12:39So with audio source, you can have multiple audio files.
    • 1:12:44So GetComponents AudioSource is what we need to actually get
    • 1:12:48the audio attached to this object.
    • 1:12:49And at index 0--
    • 1:12:51because there's only going to be one audio source anyway.
    • 1:12:54And then we just call Play, so that'll play the coin sound.
    • 1:12:58And then GetComponent, because there's only
    • 1:13:00going to be one particle system associated with this helicopter object.
    • 1:13:04We're going to get the particle system object.
    • 1:13:06And then we're just going to call Play on that, which will actually trigger
    • 1:13:09an emission one time of its particles.
    • 1:13:14That's in a nutshell what colliders and triggers are.
    • 1:13:18It's a lot of syntax at once, because Unity is really big.
    • 1:13:22But it's pretty simple.
    • 1:13:25Just make sure that you give the right shapes to your objects.
    • 1:13:27Make the right things triggers that you want
    • 1:13:29to cause behavior to happen when non-trigger things touch them.
    • 1:13:34And then implement OnTriggerEnter with the behavior-- the game logic--
    • 1:13:38that you need.
    • 1:13:39In the case of the skyscraper, for example, if we look at the skyscraper.
    • 1:13:43So I have a skyscraper component here.
    • 1:13:45And then if I OnTriggerEnter here, it effectively
    • 1:13:49does the same thing that the airplane does,
    • 1:13:53which is just go through the others, transform parent game object,
    • 1:14:00HeliController, and then call Explode.
    • 1:14:03And so Explode-- similar thing to what PickupCoin does,
    • 1:14:06and it triggers a particle effect.
    • 1:14:08But it also destroys the helicopter, and it tweaks the Game Over text
    • 1:14:14to turn on at that point.
    • 1:14:16So any questions as to how triggers work, or any of the syntax we've
    • 1:14:20talked about thus far?
    • 1:14:21I know that it's a lot.
    • 1:14:24It's kind of a fast tour.
    • 1:14:25But moving right along.
    • 1:14:30All right.
    • 1:14:30Oh, and here's a screenshot I took just to illustrate the green lines--
    • 1:14:34the box-- and then the orange is the actual mesh of the helicopter.
    • 1:14:40So we're going take a break.
    • 1:14:41And then when we get back, we're gonna talk about prefabs
    • 1:14:44and spawning them, and dive a little bit deeper
    • 1:14:47into some of the other parts of the project.
    • 1:14:49All right.
    • 1:14:50Welcome back to GD50 Lecture 8.
    • 1:14:52This is Helicopter Game 3D.
    • 1:14:53So before the break, we were talking about colliders and triggers,
    • 1:14:57and also just getting our hands used to using MonoBehaviours, and the editor,
    • 1:15:01and all sorts of things.
    • 1:15:03But we haven't really taken a look at prefabs,
    • 1:15:05which is a major part of this game.
    • 1:15:08So the coins, the skyscrapers, the airplanes--
    • 1:15:12those are all prefabricated assets that we have gotten
    • 1:15:16ready for spawning into our scene.
    • 1:15:19And we're going to take a look at how that actually works.
    • 1:15:22So here's a list of--
    • 1:15:24in our editor view-- all the different prefabs that we have.
    • 1:15:27So we can see airplane, blades, and body are prefabs.
    • 1:15:31The coin, all the skyscrapers.
    • 1:15:33There are three different kinds of skyscrapers.
    • 1:15:35And then the helicopter.
    • 1:15:37The helicopter itself we're not using as a prefab,
    • 1:15:39because I've already created it in the scene,
    • 1:15:40and it never gets instantiated dynamically.
    • 1:15:42But we could easily make it so, because I have
    • 1:15:45created a prefab with the helicopter.
    • 1:15:49So when we're looking at the scene here, we
    • 1:15:53notice that we have just the helicopter, and we have the background.
    • 1:15:57But there's no skyscrapers, there's no coins, and there's no airplanes.
    • 1:16:01Well, we do have our skyscraper spawner, the coin spawner, and the airplane
    • 1:16:07spawner.
    • 1:16:07And the three of those are just empty game objects,
    • 1:16:10but they have associated with them these spawner scripts.
    • 1:16:13And the spawner scripts, we've written ourself.
    • 1:16:16And then, once we've written them, we just simply add component here,
    • 1:16:19and then chosen the appropriate spawner.
    • 1:16:22And so what those do--
    • 1:16:24if we look in our code actually, and we go, for example, to the airplane
    • 1:16:28spawner, we have a Start method.
    • 1:16:33We have an Update method.
    • 1:16:34Notice that the Update method doesn't do anything, paradoxically,
    • 1:16:38because the airplane spawner is running over time.
    • 1:16:42We are spawning airplanes over time.
    • 1:16:45But the way that we do things over time asynchronously in Unity
    • 1:16:48is a little bit different than anything that we've done so far.
    • 1:16:51So this Start method here, we see that we're calling
    • 1:16:54this function called StartCoroutine.
    • 1:16:57And that function takes in a function called SpawnAirplanes.
    • 1:17:01And so at a high level, a coroutine is effectively a function
    • 1:17:06that yields control every time it's called.
    • 1:17:09So it'll run, and then, rather than go through its entire body of code,
    • 1:17:15and then end or return some value, and have that just be the end of it,
    • 1:17:19it'll actually yield, when you use the keyword Yield.
    • 1:17:25And depending on what you've done with that Yield,
    • 1:17:30it'll pause for some length of time, or do something for some length of time,
    • 1:17:34rather than end that function call.
    • 1:17:37So this SpawnAirplanes function here--
    • 1:17:39notice that it has a while true.
    • 1:17:41And so while true is not usually something that you want in a game,
    • 1:17:45because that's just going to lock your game forever.
    • 1:17:49But in the case of a coroutine, a coroutine is going to run,
    • 1:17:54but then it's going to yield control back
    • 1:17:56to whatever called it for some length of time,
    • 1:17:58or depending on how we've programmed it.
    • 1:18:00In this case, you can see here--
    • 1:18:02yield return new WaitForSeconds Random.Range 3, 10.
    • 1:18:07Does anybody have an idea of what that does?
    • 1:18:10Yeah.
    • 1:18:10AUDIENCE: The logic [INAUDIBLE] waits for between 3 and 10 seconds,
    • 1:18:15and continues.
    • 1:18:16COLTON OGDEN: It does.
    • 1:18:19It yields for 3 to 10 seconds, and then continues its execution.
    • 1:18:22That's exactly right.
    • 1:18:23Did you have a question?
    • 1:18:24AUDIENCE: I was thinking, why do you have three different skyscrapers set
    • 1:18:27up?
    • 1:18:28Couldn't you just have one skyscraper and change [INAUDIBLE]??
    • 1:18:32COLTON OGDEN: You could do that.
    • 1:18:33Yeah.
    • 1:18:34I guess for the sake of demonstrating prefabs.
    • 1:18:36And also, it's a little bit complex more complicated to get
    • 1:18:38into dynamic material setting, and changing materials in code.
    • 1:18:42But yeah.
    • 1:18:43You could effectively just create one skyscraper with one base color,
    • 1:18:50and then dynamically change its material.
    • 1:18:56But also to illustrate having multiple different prefabs
    • 1:18:59assigned to an object, that you can then choose at random
    • 1:19:02to generate in the game scene.
    • 1:19:03They might not necessarily be skyscrapers
    • 1:19:05that will have the exact same color.
    • 1:19:07It could be a goblin, or a orc, or a troll, or something.
    • 1:19:12And they're all different prefabs that we've created.
    • 1:19:15But you can put them in a list, and then dynamically choose
    • 1:19:18which one we want at random.
    • 1:19:20So a few different reasons.
    • 1:19:21But yeah.
    • 1:19:21In a situation where everything is just effectively differentiated
    • 1:19:25by a single color and a material change, you
    • 1:19:26could dynamically swap that as needed.
    • 1:19:33This code routine that we've started-- this function that
    • 1:19:36effectively can pause itself, even though it's being called while true
    • 1:19:42is in play.
    • 1:19:45It yields control with this Yield keyword.
    • 1:19:47And what it does is, it allows us to call something over and over again,
    • 1:19:51but then pause for some length of time.
    • 1:19:53Right?
    • 1:19:53We don't have to maintain a counter for spawn time in here.
    • 1:19:57Which we could do.
    • 1:19:57We could do float spawn time equals 0, right?
    • 1:20:01And then float spawn increment equals like 1,000.
    • 1:20:06And then while spawn time is less than spawn increment--
    • 1:20:13we could say in Update, if spawn increment.
    • 1:20:16Or we would do spawn time plus equals time.delta time first,
    • 1:20:20to get the length of time that's passed since the last frame.
    • 1:20:22And then we would say, if spawn time is greater
    • 1:20:26than spawn increment, instantiate a new airplane.
    • 1:20:32And then set spawn time back to 0.
    • 1:20:37And then just rinse and repeat this over and over again.
    • 1:20:40But coroutines take out this need, much like timer
    • 1:20:44did, for having anything that you keep track of with a specific timer.
    • 1:20:49You can do a whole bunch of different things with coroutines.
    • 1:20:51One of them, in this case that we're doing,
    • 1:20:53is just pausing for some length of time to do something.
    • 1:20:57In this case, we want to wait for some time
    • 1:21:00in between each instantiation of an airplane.
    • 1:21:07So we'll just yield control back to our game,
    • 1:21:10because we want to break out of this while true.
    • 1:21:12But we don't want to break out of it and completely break out of this function.
    • 1:21:16We want this to keep going over and over again.
    • 1:21:19So we see here, this Instantiate function is
    • 1:21:23where the actual instantiation happens.
    • 1:21:25And Instantiate takes in a prefab--
    • 1:21:29so a game object.
    • 1:21:30So in this case, we have a prefabs list here.
    • 1:21:35GameObject public, GameObject array called prefabs.
    • 1:21:39So this can take in any number of prefabs that we want it to.
    • 1:21:44We're going to return a range between 0 and length.
    • 1:21:48And then also, we want it to spawn.
    • 1:21:52We give it a position that we want to spawn in.
    • 1:21:54So Instantiate-- it takes in an object, it takes in a position,
    • 1:21:58and it takes in a rotation.
    • 1:21:59In this case, we want to give it this position.
    • 1:22:02So it's a Vector3--
    • 1:22:03it's an x, y, and a z--
    • 1:22:05at 26.
    • 1:22:06So off the right edge of the screen 7 to 10.
    • 1:22:09So within a range of verticality up towards the top.
    • 1:22:14And then at 11 on the z-axis, which is aligned with our helicopter
    • 1:22:17and the skyscrapers.
    • 1:22:21And then this Quaternion.Euler--
    • 1:22:25so 3D rotation, the math behind it is pretty complex.
    • 1:22:30And I don't know it well at all.
    • 1:22:32But Quaternion.Euler allows us to think in degrees,
    • 1:22:35and actually perform a 3D rotation on something fairly easily.
    • 1:22:40So if you want to rotate something in 3D, Quaternion.Euler.
    • 1:22:43Negative 90 degrees on the, I believe it's z, x, y.
    • 1:22:46In this case, the way that the default rotation of the airplane is,
    • 1:22:50we want to set it to negative 90, negative 90, 0.
    • 1:22:54You could also set up your prefab in a way such
    • 1:22:58that you don't need to pass this in.
    • 1:23:00You could do Quaternion.Identity in that case.
    • 1:23:03But this is just to illustrate how, if you want to rotate something
    • 1:23:06in code, how you would do it.
    • 1:23:07So Quaternion.Euler is the way that you rotate something in 3D.
    • 1:23:13So Instantiate-- global function that you
    • 1:23:15can call anywhere you want to, as long as you just
    • 1:23:18give it a actual object or prefab that it knows how to instantiate.
    • 1:23:23And then WaitForSeconds-- another global object,
    • 1:23:25which is a asynchronous object that will allow
    • 1:23:28us to yield for this length of time.
    • 1:23:31You pass in the length of time here.
    • 1:23:33It takes it in seconds, because WaitForSeconds.
    • 1:23:35And then, as soon as this length of time has passed,
    • 1:23:39it's going to come back up here into this while true instruction,
    • 1:23:42and then instantiate again.
    • 1:23:44We don't have to keep track of a time or anything-- any weird boilerplate.
    • 1:23:47We just have to call StartCoroutine here.
    • 1:23:51And notice that we explicitly have to call StartCoroutine routine in order
    • 1:23:54to trigger a coroutine function.
    • 1:23:58And to do that, it returns what's called an IEnumerator.
    • 1:24:02And so a lot of these details, you don't need to necessarily know
    • 1:24:05the low-level details of.
    • 1:24:06I certainly don't know all the low-level details of everything
    • 1:24:10that happens in Unity.
    • 1:24:11But just know if you want asynchronous behavior,
    • 1:24:13your function needs to return an IEnumerator,
    • 1:24:15which C# knows is a generator function which will yield control
    • 1:24:22at predetermined times.
    • 1:24:24And it will manage it for you.
    • 1:24:27And to trigger it, you need to StartCoroutine,
    • 1:24:29which is a function that Unity has defined for you.
    • 1:24:33So any questions as to how this works at a high level, at least?
    • 1:24:38AUDIENCE: I'm a little confused on the syntax for Yield.
    • 1:24:40Does the Yield return--
    • 1:24:42COLTON OGDEN: Yes.
    • 1:24:44Yield takes in something, and you get a new to instantiate a new WaitForSecond.
    • 1:24:51It's just the way the syntax is for yielding an object.
    • 1:24:56Yield--
    • 1:24:56AUDIENCE: What is it returning back?
    • 1:24:58COLTON OGDEN: It's returning this to the Yield instruction.
    • 1:25:00And the Yield instruction is then yielding that.
    • 1:25:05It is a little bit weird, though.
    • 1:25:06But you only really have to--
    • 1:25:09this is a common pattern that you'll see.
    • 1:25:11And so you'll just get used to it.
    • 1:25:16And honestly, this is probably one of the more syntactically difficult things
    • 1:25:20about Unity.
    • 1:25:20So I mean, as soon as you understand this,
    • 1:25:22pretty much anything else is fairly easy at that point.
    • 1:25:25I would say this is one of the weirder sides.
    • 1:25:28Because in Lua, and Love2D, and those kinds of environments,
    • 1:25:32it's a little bit easier to do this sort of thing with as much syntax.
    • 1:25:37C#, being a statically-typed environment, to get the same behavior,
    • 1:25:42you have to go a little bit further.
    • 1:25:46Do things their way.
    • 1:25:48But that's getting asynchronous behavior to work in C#.
    • 1:25:54And in Unity, typically, in order to avoid messy state management,
    • 1:26:01you will use coroutines, which are IEnumerators, often
    • 1:26:06with the WaitForSeconds object.
    • 1:26:09And just make sure to trigger them with StartCoroutine.
    • 1:26:14And then call that function as if it were an object.
    • 1:26:17Just like that.
    • 1:26:20And the behavior for the airplane spawner, the coin spawner,
    • 1:26:25and so forth, they're all fairly similar.
    • 1:26:27So StartCoroutine SpawnCoins.
    • 1:26:31And then while true.
    • 1:26:32So coins-- this row just spawns a random number of coins vertically.
    • 1:26:36So you can have one, or you can maybe have a couple.
    • 1:26:40And then for each of those, instantiate them
    • 1:26:42at a random position on the y-axis.
    • 1:26:46Here, random negative 10 to 10.
    • 1:26:49In this case, Quaternion.Identity, because we don't want
    • 1:26:52to rotate them any differently than they already are, which I alluded to before.
    • 1:26:58So Quaternion.Identity just means no rotation applied to the object.
    • 1:27:01So whatever its base rotation is as a prefab.
    • 1:27:05So it'll be whatever it is when you see it in the editor,
    • 1:27:08and when you create a new one, that's going to be its default rotation.
    • 1:27:12So basically the equivalent of, don't rotate this by anything.
    • 1:27:18And then, same as we saw before, yields a new WaitForSeconds.
    • 1:27:25In this case, 1 to 5, so a little bit more frequently than the airplane,
    • 1:27:29on average.
    • 1:27:30More coins.
    • 1:27:31As the airplane, I believe, was 3 to 10, so every 3 to 10 seconds.
    • 1:27:37And that's basically that.
    • 1:27:39And then we StartCoroutine, just like we did before with the airplane spawner.
    • 1:27:44And then lastly, the skyscraper spawner.
    • 1:27:47In this case, we only have one coin prefab,
    • 1:27:52we only have one airplane prefab, but we have three skyscraper prefabs.
    • 1:27:57And so the actual Random.Range here comes into play,
    • 1:28:01because that's how we get the different color skyscrapers spawning at random.
    • 1:28:05And like I said before, this can be extrapolated
    • 1:28:07to whatever sort of game environment you want,
    • 1:28:09where you have multiple types of objects that
    • 1:28:11are more complicated than just a color swap,
    • 1:28:13and you want to choose them at random.
    • 1:28:17We're doing all the same things that we did before.
    • 1:28:20And also, here, we can see that they have a random chance
    • 1:28:251 in 4, so a 25% chance of increasing the speed.
    • 1:28:30So skyscraper spawner actually has-- and this is relevant to the assignment--
    • 1:28:35skyscraper spawner has a float called speed here, which is, by default, 10.
    • 1:28:41And this drives the scroll speed of the skyscrapers, the coins,
    • 1:28:46and the airplanes.
    • 1:28:48And so when we call it static, do we know what that means?
    • 1:28:53Yeah?
    • 1:28:53AUDIENCE: Well, it's the same for all [INAUDIBLE] objects [INAUDIBLE]..
    • 1:29:00COLTON OGDEN: Yes.
    • 1:29:01So no matter how many skyscraper spawners we create,
    • 1:29:07they're all going to share this field speed,
    • 1:29:10and it's always going to be equal to the same amount across all instances.
    • 1:29:13So static means that it's part of the class.
    • 1:29:15It belongs to the SkyscraperSpawner class.
    • 1:29:18It does not belong to a SkyscraperSpawner object.
    • 1:29:21And so we don't ever really want to change that ourselves in this game.
    • 1:29:26But the airplane, for example, notice that in our Update function
    • 1:29:32here, if the transform.position.x is less than negative 25,
    • 1:29:37we should destroy the airplane.
    • 1:29:38So when it goes off screen, we should destroy it.
    • 1:29:41But if not, then we want to translate this object
    • 1:29:47on the x-axis by negative SkyscraperSpawner.speed times 2 times
    • 1:29:52Time.deltaTime.
    • 1:29:54So we're translating it on the x-axis, and we're
    • 1:29:57using the SkyscraperSpawner.speed as our core multiplier.
    • 1:30:00And then if we look at coin--
    • 1:30:03same thing.
    • 1:30:08I should ask, what is one design consideration
    • 1:30:11if we're looking at this--
    • 1:30:12all these components?
    • 1:30:13And let's say we're trying to get as decoupled as we
    • 1:30:17can, and well-engineered as we can.
    • 1:30:19What is a consideration that we can, noticing that, for example,
    • 1:30:23this exists in coin, and this exists in airplane?
    • 1:30:33AUDIENCE: What's the question again?
    • 1:30:35COLTON OGDEN: So how could we better engineer this?
    • 1:30:37Notice that we have--
    • 1:30:39and taking into consideration this component model in Unity--
    • 1:30:43what could we do with, for example, this?
    • 1:30:45AUDIENCE: So that Unity better [INAUDIBLE]..
    • 1:30:50COLTON OGDEN: Well, I'm thinking that, because the airplane and the coin--
    • 1:30:53well, first of all, it wouldn't belong in the spawner,
    • 1:30:55because the spawner's job is to spawn coins.
    • 1:30:58But the coins and the airplanes-- they have their behavior, right?
    • 1:31:00They have their update behavior.
    • 1:31:03But they're all doing kind of the same thing, which is scrolling to the left,
    • 1:31:06and then de-spawning at negative 25.
    • 1:31:09So a design consideration here would be, maybe we have a scroll component,
    • 1:31:13right?
    • 1:31:15Or a scroll and destroy component.
    • 1:31:17Or just a scroll component with an optional destroy flag.
    • 1:31:20And then we just put this on anything that we want to automatically scroll
    • 1:31:23to the left screen and de-spawn, rather than having
    • 1:31:25to code this in every single class.
    • 1:31:28So if you're ever looking through your code,
    • 1:31:30and you're seeing, for example, this and this being the exact same, especially
    • 1:31:39in Unity, because of how flexible components are,
    • 1:31:42try and think about how you can make it into its own component.
    • 1:31:46AUDIENCE: So where would you put the coins [INAUDIBLE]??
    • 1:31:48COLTON OGDEN: You make it yourself.
    • 1:31:50So if we went into here, into our Scripts thing, and just
    • 1:31:53made a new script.
    • 1:31:56And then we called it Scrollable.
    • 1:31:59And then we double-click it, it'll open up in our editor
    • 1:32:02that we've chosen in our preferences.
    • 1:32:04By default, it's going be Visual Studio with the newer versions.
    • 1:32:07But now we have a new scrollable behavior.
    • 1:32:09And then all we need to do--
    • 1:32:10we would say, oops--
    • 1:32:12not that.
    • 1:32:13If-- once again, I can't type.
    • 1:32:17Transform.position.x is less than negative 25,
    • 1:32:23destroy game object, right?
    • 1:32:25And so this is the exact same thing as all that behavior that we saw before.
    • 1:32:30So now we can take all of that out of coin--
    • 1:32:35we can take this out, and we can take this out here, and then
    • 1:32:38just add to the airplane and to the coin prefabs,
    • 1:32:42we'd just add this new Scrollable prefab,
    • 1:32:44and it'll take care of that for us.
    • 1:32:45Yeah.
    • 1:32:46AUDIENCE: How would you add that?
    • 1:32:48COLTON OGDEN: So if we're going back to Unity--
    • 1:32:50so the question is, how would you add the component to the prefab?
    • 1:32:54So in our prefabs, note that we have airplane, we have coin,
    • 1:32:57and we have all the skyscrapers.
    • 1:32:58So these are all prefabs.
    • 1:33:00Oh, and I haven't actually detailed how to create
    • 1:33:02a prefab, which I apologize for.
    • 1:33:04So a prefab-- all you need to do is create an object in your scene.
    • 1:33:08For example, I did it with this helicopter.
    • 1:33:10So I'm going to delete the helicopter, because this is just the helicopter
    • 1:33:13prefab.
    • 1:33:14It's not going to actually delete the helicopter from our scene.
    • 1:33:17But if I take this helicopter here, and then I drag it in here,
    • 1:33:24notice that now we have a prefab here.
    • 1:33:29We could take this helicopter out, and just add a new one right there.
    • 1:33:33So now I have two helicopters.
    • 1:33:36That's all a prefab is.
    • 1:33:37It's just something that you've made in your scene
    • 1:33:40that you want to replicate or duplicate in the future, ideally through code.
    • 1:33:44And notice it's showing here in our hierarchy view.
    • 1:33:50But obviously you don't want that.
    • 1:33:53But that's how you create a prefab is, you find something
    • 1:33:57that you've configured in your game scene, and then in your code,
    • 1:34:01you're allowed to then instantiate that prefab,
    • 1:34:04assuming that you've made that prefab a member of whatever class
    • 1:34:10instantiates it.
    • 1:34:11So in this case, the airplane spawner.
    • 1:34:13So notice that we call Instantiate here, like we saw, before on line 24.
    • 1:34:18But it's looking at prefabs.
    • 1:34:21It's a list, and it's looking at a random range between 0
    • 1:34:24and the length of the prefabs.
    • 1:34:27You have to declare a public GameObject list prefabs here.
    • 1:34:31And then, once we do that, and we go to our airplane spawner here,
    • 1:34:35notice that we have this prefabs list here.
    • 1:34:38So we actually get a editor view of that code, that data structure.
    • 1:34:44And we can just add prefabs that we want to.
    • 1:34:48And if we change the size to 2, then we can add a second prefab.
    • 1:34:54Or if we make the size 10, then we can put 10 different airplanes there.
    • 1:34:59But we only have one airplane that I modeled, so I was going to make it 1.
    • 1:35:02But this is the same thing.
    • 1:35:05This GameObject list is that same list, only
    • 1:35:08that's the view we have of it in the editor.
    • 1:35:10And it's just a different way of looking at the data.
    • 1:35:13And that's the nice thing about Unity is that, if you make
    • 1:35:16any of your fields public, like this.
    • 1:35:19If I did public int someNumber, right?
    • 1:35:24And I save that, and I go back here, my airplane spawner
    • 1:35:27should get a someNumber right here.
    • 1:35:32And then I can just set someNumber to whatever I want.
    • 1:35:34It doesn't do anything right now, because someNumber
    • 1:35:36doesn't affect the script.
    • 1:35:37But this is a nice way to take the burden from you out of the code.
    • 1:35:44You're not experimenting with code.
    • 1:35:46You're not tweaking some variable in your script.
    • 1:35:49SomeNumber 10, run me, OK-- someNumber 12, run it.
    • 1:35:52You can just assign it here in your actual editor view,
    • 1:35:56and then just tweak it as you want.
    • 1:35:58So I can just scroll through it.
    • 1:35:59I can start the game and I can pause the game.
    • 1:36:03AUDIENCE: So is it that you just make it public?
    • 1:36:05COLTON OGDEN: You have to make it public.
    • 1:36:06Exactly.
    • 1:36:07AUDIENCE: Oh, then that shows in.
    • 1:36:08COLTON OGDEN: Yep.
    • 1:36:09And so I can just do this.
    • 1:36:10And then I should be able to--
    • 1:36:11I can just change this now, if I wanted to, to 67.
    • 1:36:14And so if that actually had some sort of effect on my game world--
    • 1:36:18if my game relied on that number being meaningful--
    • 1:36:21this would update the scene.
    • 1:36:22And so you can make whatever-- you can debug this way,
    • 1:36:25or you can customize your components more this way.
    • 1:36:29But it's just a tremendous amount of flexibility.
    • 1:36:33And so that's how we're instantiating this from this list of prefabs.
    • 1:36:37It's a list of game objects.
    • 1:36:39We've made it explicit to Unity.
    • 1:36:42The editor's going to know, OK, these are game objects.
    • 1:36:45And so prefabs are game objects.
    • 1:36:47So we can just put any of these into this field
    • 1:36:51here, this element 0 field, or however many fields we have.
    • 1:36:55And it will, in the code, randomly choose one of those,
    • 1:36:59and then instantiate it.
    • 1:37:01So any questions as to how prefabs work, or instantiation,
    • 1:37:04or anything like that?
    • 1:37:07OK.
    • 1:37:11AUDIENCE: Does each prefab have a unique number or not?
    • 1:37:14COLTON OGDEN: Does each prefab have a unique number?
    • 1:37:16Not a unique number.
    • 1:37:18They just are all assets in your folder here.
    • 1:37:21They have some kind of identifier to Unity that's hidden from you.
    • 1:37:26It might be visible from you if you look.
    • 1:37:28They might have some sort of generated ID or something like that, so
    • 1:37:31that it knows, underneath the scenes.
    • 1:37:33But it's not something that you worry about in your actual code.
    • 1:37:38We've created a list here that's just--
    • 1:37:41it will expect some number.
    • 1:37:43It doesn't know how many.
    • 1:37:44And then, in the editor, you can actually tell it how many.
    • 1:37:50Because every list that you make visible in
    • 1:37:55the editor will have this size field.
    • 1:37:58And that's just part of the editor's abstraction.
    • 1:38:00The editor has abstractions for a lot of different objects.
    • 1:38:04You can create a lot of different objects in your MonoBehaviours,
    • 1:38:07and make them public, and Unity will have a different view for them.
    • 1:38:12Things like color pickers, and stuff like that.
    • 1:38:14I don't know the exact object offhand, but if you make a public color
    • 1:38:17picker in your MonoBehaviour or something like that,
    • 1:38:20you'll actually get a color picker here that you can choose a color for,
    • 1:38:23which is pretty awesome.
    • 1:38:24And there's a lot of different customized views.
    • 1:38:30I think, actually, the directional light might be an example.
    • 1:38:33See this color here?
    • 1:38:34This is somewhere in code.
    • 1:38:37There's a public color something.
    • 1:38:40And then in the editor, when you're actually editing it,
    • 1:38:42you can choose the color.
    • 1:38:43And Unity gives you the option to make it wherever you want.
    • 1:38:46And notice it's actually affecting the background there.
    • 1:38:50One of the really big strengths of Unity,
    • 1:38:52and a reason to really make your components customizable,
    • 1:38:56is this one-to-one mapping between your data, your code,
    • 1:39:01and your editor view of the data.
    • 1:39:05Take the burden away from you programming it,
    • 1:39:07which you're more prone to make mistakes, too,
    • 1:39:10and also waste a lot of time.
    • 1:39:12And then just be able to modify.
    • 1:39:14How much faster is it for me to just say,
    • 1:39:16I want this red color, rather than color.r equals something,
    • 1:39:20and then color.g equals something, color.b equals something.
    • 1:39:23And then assign it that way.
    • 1:39:24So that's just a simple example to illustrate it.
    • 1:39:26But there's a tremendous amount of potential involved
    • 1:39:29in making your components customizable.
    • 1:39:33And so that's what I did here.
    • 1:39:34Because I wanted the skyscraper spawner to spawn not just one skyscraper
    • 1:39:43but several skyscrapers, I created this public prefabs list,
    • 1:39:48that I can then populate from Unity here.
    • 1:39:50And say, OK, this object, this object, and this object.
    • 1:39:53Put that into the skyscraper spawner here, in these slots.
    • 1:39:56And then my code knows to instantiate it, randomly picking one of those.
    • 1:40:02Yeah.
    • 1:40:02AUDIENCE: In the example earlier, how would you
    • 1:40:04actually go about making something scrollable now that you've made that?
    • 1:40:09Would you just add component to the coin?
    • 1:40:12COLTON OGDEN: How would you go about making something scrollable now that
    • 1:40:15you've--
    • 1:40:15AUDIENCE: You declared that Scrollable class, right?
    • 1:40:18COLTON OGDEN: Oh, yeah.
    • 1:40:19So I have a Scrollable script here.
    • 1:40:24Oh, do you mean the infinite scrolling background, or the scrollable object?
    • 1:40:28AUDIENCE: The one where you define it as being destroyed when it's [INAUDIBLE]..
    • 1:40:31COLTON OGDEN: Oh, yeah.
    • 1:40:32So in order to do that-- so we've made the Scrollable script here.
    • 1:40:35So you would just go to-- in this case, since we're
    • 1:40:38instantiating all of the coins, and skyscrapers, and airplanes as prefabs,
    • 1:40:42you actually edit the prefab itself.
    • 1:40:44So I'd go to this coin prefab.
    • 1:40:46I'd add component here at the bottom.
    • 1:40:48And I would add Scrollable there, which is a script.
    • 1:40:51And you can tell it's yours, because it says script there.
    • 1:40:54Just like coin here is a script, and rotate script is a script.
    • 1:40:57That's actually an old script that I didn't use anymore,
    • 1:41:01because I just made it part of the coin itself.
    • 1:41:05But this is another part of what makes the coin class, by the way,
    • 1:41:08is this transform.rotate x, y, and z, either relative
    • 1:41:14to itself or to the world space.
    • 1:41:16In this case, it shows the world space, because I want
    • 1:41:18it to rotate on the world's y-axis.
    • 1:41:20But if you rotate an object, its own x, y, z still exist.
    • 1:41:24And so you can have something rotate about its own x, y,
    • 1:41:26and z, regardless of its rotation in the world.
    • 1:41:29And so I want the coin to always rotate.
    • 1:41:31So 5 degrees on the y-axis here.
    • 1:41:35So this is another part that you could take and make it its own script--
    • 1:41:40just a rotatable script.
    • 1:41:42Auto rotate script.
    • 1:41:43And then just make these public fields, like public x, public y, public z.
    • 1:41:47And then you could change those in the editor,
    • 1:41:49and then actually customize your objects without having to go into the code
    • 1:41:54itself.
    • 1:41:56AUDIENCE: So you don't have to do any collisions, actually, yourself.
    • 1:42:00You just click the button and type in the Collide function.
    • 1:42:04COLTON OGDEN: Yeah.
    • 1:42:04You don't have to do any of the collision yourself,
    • 1:42:06because Unity comes with a 3D physics engine.
    • 1:42:09You have to tell it what to do when the collisions happen.
    • 1:42:12But you don't have to actually code the 3D physics engine yourself, which
    • 1:42:16is a tremendous amount of work.
    • 1:42:19One of the big selling points, definitely,
    • 1:42:21for doing any 3D things in Unity.
    • 1:42:23I mean, a lot of engines now have 3D engines for free.
    • 1:42:26There was a time when it was less prevalent.
    • 1:42:29AUDIENCE: How would you know what you collided with?
    • 1:42:31COLTON OGDEN: Because there is a collider that it gets.
    • 1:42:38Where is it again?
    • 1:42:39Is it the skyscraper, for example?
    • 1:42:41So every skyscraper, when it collides with something,
    • 1:42:43this OnTriggerEnter gets passed in this collider other.
    • 1:42:47And so that's going to be the object that you collided with.
    • 1:42:53You can assign a name to an object, and then get its name, as well, in code,
    • 1:42:56if you needed to do that.
    • 1:42:58In this case, we wanted to know whether it's the helicopter or not.
    • 1:43:01So we got the HeliController from it.
    • 1:43:04But in our game, it's kind of a special case,
    • 1:43:06because there's only one type of object that
    • 1:43:08has a collider that's a non-trigger, and that's the helicopter.
    • 1:43:11So we can assume that this exists when we do get a collision.
    • 1:43:15But otherwise, we probably want to say, get component of HeliController,
    • 1:43:20and then test it for equal to null.
    • 1:43:22And if it's equal to null, then we want to not do something.
    • 1:43:26If we tried to call explode on a null object,
    • 1:43:29that's going to be a null pointer exception.
    • 1:43:31And then you're going to crash your game.
    • 1:43:33But in this case, we're guaranteed for that not to happen.
    • 1:43:36Because, like I said, the only collider that
    • 1:43:38can collide with this that's not a trigger is the helicopter object.
    • 1:43:42So does that makes sense?
    • 1:43:45AUDIENCE: Sounds like a physics problem with an exploding element.
    • 1:43:48COLTON OGDEN: Oh, yeah.
    • 1:43:49Yeah.
    • 1:43:50That's all too real.
    • 1:43:55In this case, though, all explode is is, thankfully, just destroy game object
    • 1:43:59and then start a particle effect.
    • 1:44:00So any more questions as to how instantiation,
    • 1:44:04prefabs, using the Unity editor, interacting with your model
    • 1:44:08behaviors, public variables?
    • 1:44:10Yeah.
    • 1:44:11AUDIENCE: You get processes, you first enter the data in that to there,
    • 1:44:15and then it runs the code to load the data,
    • 1:44:19or can you also put value data in the editor?
    • 1:44:23COLTON OGDEN: You cannot define--
    • 1:44:24so the question is, do you first create the data in the editor,
    • 1:44:27and then the code, and then tie them together that way?
    • 1:44:31In order to get a new component, you will have to create the class first--
    • 1:44:34the model behavior that you want--
    • 1:44:37and give it the public fields that it needs for the editor to actually read.
    • 1:44:41So the editor reads your script, looks through all the public fields,
    • 1:44:45and then will create the necessary GUI elements in the editor
    • 1:44:47to interact with the code.
    • 1:44:50But this needs to exist.
    • 1:44:51All this code needs to exist.
    • 1:44:52Anything that has these public variables that you want accessible in the editor
    • 1:44:56needs to exist in code first, and then you
    • 1:44:59have the power to use it in the editor.
    • 1:45:00And then it's customizable at that point.
    • 1:45:04Any more questions?
    • 1:45:08All right.
    • 1:45:09So that's the prefabs.
    • 1:45:11So we looked at texture scrolling before.
    • 1:45:13And we're going to go kind of quickly through this.
    • 1:45:15But all texture showing was, if we recall,
    • 1:45:18was I have a scrolling background class here.
    • 1:45:21It's got a scroll speed.
    • 1:45:22So if we wanted to, since it's public, we can edit it in the editor
    • 1:45:25and make it faster or slower.
    • 1:45:29But if we maintain a reference to our renderer.
    • 1:45:31Every object has a renderer-- mesh renderer, typically, for 3D objects.
    • 1:45:35And the renderer has a material associated with it.
    • 1:45:39Everything in Unity has a material.
    • 1:45:43And material doesn't necessarily have a texture.
    • 1:45:45But in this case, our background does have a texture,
    • 1:45:48and it's going to be called MainTex by default.
    • 1:45:51That's the main texture, if we want to assign a texture
    • 1:45:53to see visually on a material.
    • 1:45:55So material can just be a color often, but it can also
    • 1:45:59be a color and also a texture.
    • 1:46:02So in this case, the background is a texture.
    • 1:46:04It does have a texture assigned to it.
    • 1:46:05And notice that if we go to the background,
    • 1:46:09and then here is where we actually create.
    • 1:46:13So this is a material here.
    • 1:46:15It's got a shader.
    • 1:46:16So we're not going to talk too much about what shaders are.
    • 1:46:19We've talked about them briefly.
    • 1:46:20In Unity, you can go quite a bit farther with them.
    • 1:46:24Well, technically speaking, I guess you could go equally far with Love2D--
    • 1:46:282D shaders and 3D shaders, at least in vertex and fragment shaders.
    • 1:46:34But for all intents and purposes, we're not
    • 1:46:37going to go into detail on shaders today.
    • 1:46:40But they're very similar.
    • 1:46:42In this case, every material has a shader in Unity,
    • 1:46:47in order for it to render.
    • 1:46:48Because anything that renders needs to be shaded in Unity.
    • 1:46:52But notice that here we have a texture.
    • 1:46:54So this is that main texture thing that we saw before.
    • 1:46:57And then this is the bump map here.
    • 1:46:58We don't have a bump map, because our texture isn't bumpy.
    • 1:47:01It doesn't have any contour detail or anything like that.
    • 1:47:04But you can just select a texture here.
    • 1:47:06So I could give it that texture if I wanted to.
    • 1:47:08Or I have another couple of textures here.
    • 1:47:13This texture here.
    • 1:47:14It doesn't matter which texture you choose, but you can choose a texture.
    • 1:47:18And then that material will then, it will calculate,
    • 1:47:21based on the mesh, how to draw that texture best to it.
    • 1:47:25And you can set every material's texture offset via its SetTextureOffset
    • 1:47:32function on the x and the y-axis.
    • 1:47:34And that'll shift it, effectively accomplishing
    • 1:47:38what a scrolling background needs.
    • 1:47:41It'll draw it, and then it'll basically wrap around to the other side.
    • 1:47:44So that's how we get the infinite scrolling texture.
    • 1:47:48We just set its texture offset.
    • 1:47:51We specific call SetTextureOffset on the main texture,
    • 1:47:54and then we pass in a Vector 2.
    • 1:47:55So just two numbers--
    • 1:47:57offset and 0.
    • 1:47:58Because we don't want to touch the y-axis, so it was 0, and then offset
    • 1:48:01is just some value that increases over time.
    • 1:48:04And then Time.time, recall--
    • 1:48:06time since the beginning of the game has started.
    • 1:48:08Time.delta time-- time since the last frame.
    • 1:48:11And so we can just do one calculation in here and update every time,
    • 1:48:15and then multiply it times scroll speed to get
    • 1:48:17the scroll amount that we want here.
    • 1:48:19And I've set it to 0.1 just for a semi-slow effect.
    • 1:48:23But in the editor, if we look at our scrolling background, which is here.
    • 1:48:32And then I've made it public, so I could just easily make this 1.
    • 1:48:36And I don't know how fast it's going to be, but 10 times faster.
    • 1:48:39So probably pretty fast.
    • 1:48:41Yep.
    • 1:48:42So it's hauling.
    • 1:48:45But yeah.
    • 1:48:45All that is is a shifting how it maps the texture onto the 3D surface.
    • 1:48:50And this 3D surface, to be clear, is just a plane.
    • 1:48:53So just a plane.
    • 1:48:55And notice that it doesn't get rendered from the back.
    • 1:48:57So anything which is a polygon has one side that gets shaded
    • 1:49:02and one side that does not get shaded.
    • 1:49:05So if you see invisibility on one side, and not invisibility on one side,
    • 1:49:09that's not a bug.
    • 1:49:10That's a feature.
    • 1:49:12That's the texture scrolling side of things.
    • 1:49:14Anybody have any questions as to how that works?
    • 1:49:18We won't really need it for much going forward.
    • 1:49:20It's not part of the assignment.
    • 1:49:22But it ties in to what we've done before.
    • 1:49:24So I thought it would be interesting to cover.
    • 1:49:27Last thing we'll look at is audio.
    • 1:49:28Audio is pretty easy.
    • 1:49:30All you need in Unity to do audio is an audio source and an audio listener.
    • 1:49:37So a source plays audio.
    • 1:49:39So James, if you are an audio source, I'd be an audio listener.
    • 1:49:44And I'm listening for audio and playing it back
    • 1:49:46to the speakers when I hear any sort of source of audio in the game world.
    • 1:49:52So you can have infinite audio sources, but ideally one audio listener.
    • 1:49:56And it's usually whatever main camera that you're drawing with.
    • 1:50:02And then sounds in Unity can be either 2D or 3D.
    • 1:50:05In this case, all the sounds that I've put into this game are 2D.
    • 1:50:10And that's just this spatial blend here.
    • 1:50:12Notice that there's a 2D to 3D slide.
    • 1:50:15And so that'll calculate, based on where the sound is,
    • 1:50:17how it sounds in the game space.
    • 1:50:19And it's based on how far away it is, and what side of you it is.
    • 1:50:23And so the main camera has the audio source for the music.
    • 1:50:27And so it just starts the music right away.
    • 1:50:29Notice that we didn't have to code any of this.
    • 1:50:31I just attached an audio source to the camera.
    • 1:50:34And then there's a Play On Awake checkbox, and a Loop checkbox.
    • 1:50:38So normally we've done like--
    • 1:50:40at the start of our game code, set looping to true, and then
    • 1:50:43play the source.
    • 1:50:44In this case, we'd have to do none of those things.
    • 1:50:46This is just given to us by Unity by default.
    • 1:50:49AUDIENCE: You put the audio on the camera?
    • 1:50:51COLTON OGDEN: Yep.
    • 1:50:51AUDIENCE: You could put it on anything.
    • 1:50:53COLTON OGDEN: You could put it on anything you want to.
    • 1:50:54AUDIENCE: The sound is relative to that object.
    • 1:50:56COLTON OGDEN: The sound is relative to that object, yeah.
    • 1:51:01That's audio.
    • 1:51:01It's pretty simple.
    • 1:51:03I mean, it's an art form when it comes to how
    • 1:51:05you want to position things in your game world,
    • 1:51:06and how you want them to sound, and whatnot.
    • 1:51:09And you can get more complicated with it.
    • 1:51:10But that's how you would do basic 2D, in this case, audio.
    • 1:51:14But you could easily also do 3D audio just
    • 1:51:16by making this set to 0 from 0 to 1.
    • 1:51:19And you can make it more or less 3D, too.
    • 1:51:21If it's not all the way to 1, it'll somewhat be 2D.
    • 1:51:24So you'll hear some of it no matter what, and some of it will be 3D.
    • 1:51:27And then setting it to 1, it'll be purely 3D.
    • 1:51:29So if it gets far enough away, you won't hear it at all.
    • 1:51:35The explosion sound, as well, gets triggered.
    • 1:51:40And so this happens in the--
    • 1:51:41I forget exactly offhand where it gets triggered.
    • 1:51:49I believe it's in the HelicopterExplode function?
    • 1:51:55Oh, yes.
    • 1:52:01I created an object in the scene that has an audio source for the explosion
    • 1:52:04sound.
    • 1:52:05And because I made this public, I can just put it on this object.
    • 1:52:08And so there's a reference to that audio source at all times.
    • 1:52:12And so I trigger explosionSound.play whenever we call this Explode method
    • 1:52:16on the HeliController.
    • 1:52:17For the reason that I didn't put it on this object, because we destroy
    • 1:52:20this object as soon as we get into a collision.
    • 1:52:24And so I didn't want to put the explosion sound
    • 1:52:27audio source on this object, because it would get destroyed in there.
    • 1:52:30It would not play audio, effectively, as soon as we destroy it.
    • 1:52:33So we have to have it somewhere else on the scene.
    • 1:52:35I could have also just made the object invisible, but I didn't.
    • 1:52:40I destroyed it.
    • 1:52:44And so, yeah.
    • 1:52:46That's this explosion sound object which, if we look at the helicopter,
    • 1:52:51in the HeliController, which is all the way down here.
    • 1:52:57Notice that it has a reference to an explosion particle
    • 1:53:01system and an explosion sound.
    • 1:53:03And we just have to click and drag the object effectively from here to here
    • 1:53:08to pair the two of them.
    • 1:53:09And then the script that this is referring
    • 1:53:11to will always have a reference to those, as long as these
    • 1:53:14are set to something.
    • 1:53:15And notice that we also have coin total we've made public.
    • 1:53:18So I guess I could experiment with it.
    • 1:53:19And then speed-- we made this public so that you can make the helicopter
    • 1:53:22faster, if you wanted to, or slower.
    • 1:53:25And so you'll find it often useful to make a lot of these fields public
    • 1:53:30just for you to experiment with.
    • 1:53:32And then there's never really harm in doing so,
    • 1:53:34because folks aren't going to be able to actually see this in the editor
    • 1:53:39when they download your game.
    • 1:53:40So make as much public as you want for debugging purposes,
    • 1:53:43and just have fun with it.
    • 1:53:46But that's audio.
    • 1:53:46Audio sources produce the sound.
    • 1:53:48Audio listeners listen to the sound.
    • 1:53:50And actually make it go through your computer speakers
    • 1:53:53or whatever your default audio system is.
    • 1:53:57And here's just a showcase of the two on the camera.
    • 1:54:01And that's audio.
    • 1:54:03So any questions as to how the audio works at all?
    • 1:54:08All right.
    • 1:54:09A couple of last things before we close out here.
    • 1:54:11So the Asset Store is probably one of the biggest things about Unity
    • 1:54:14that sells it.
    • 1:54:16So oftentimes, it's a lot easier just to get something,
    • 1:54:20whether it's a library, if you're programming, or something else,
    • 1:54:23get something that's implemented for you,
    • 1:54:25so that you don't have to implement it yourself.
    • 1:54:29In this case, there's an RPG Systems for Rapid Development
    • 1:54:32something, Visual Scripting system, looks similar to Unreal.
    • 1:54:36There's a ton of things in the Asset Store-- models, scripts, audio, editor
    • 1:54:43tool kits.
    • 1:54:44A lot of cool things.
    • 1:54:45A lot of it's free, if you want to experiment.
    • 1:54:48So a lot of the assets that I got to mess with in this game here
    • 1:54:52are free, like the coin and some of the other stuff that's bundled with it.
    • 1:54:56There's a lot of really cool things and really cool systems
    • 1:54:58to help you for $10 or $20.
    • 1:55:00You can spend a little bit of money, and then
    • 1:55:02get like 25% of your game done right away.
    • 1:55:06And then you can actually get closer to shipping it.
    • 1:55:08So I think it's hugely valuable to be looking at the Asset Store
    • 1:55:12and thinking about how you can save your time that way,
    • 1:55:15if you're trying to actually ship a game and get to market.
    • 1:55:18So definitely look through the Asset Store.
    • 1:55:21See if there's anything that will make your life easier
    • 1:55:24when it comes to developing games.
    • 1:55:25Because I know that I've used it several times, and I rarely regret doing so.
    • 1:55:30So Assignment 8 is going to be pretty simple.
    • 1:55:35So for the second part, there's a bug in the game
    • 1:55:39where, if you die over and over again, the scroll speed never resets.
    • 1:55:45So it is keeping faster, and faster, and faster, and faster forever.
    • 1:55:48But it's a one line fix.
    • 1:55:50And I want you guys to find where to fix it, given that we know,
    • 1:55:54given what we've seen today.
    • 1:55:55And there's a hint here about static variables.
    • 1:55:57So it will also be detailed in the spec as well.
    • 1:56:01But this is an easy part.
    • 1:56:03This part's fairly easy, too, because all it really is
    • 1:56:05is taking the kind of the same stuff we've looked at--
    • 1:56:08the coin generator and coins--
    • 1:56:10and then making gems that spawn in addition to the coins at a rarer rate.
    • 1:56:16And these gems should be worth five coins.
    • 1:56:19And so when you collide with the gems, just add 5 to the coin total.
    • 1:56:22And if you collide with a coin, add 1 to the coin total.
    • 1:56:25And that's basically it for Assignment 8.
    • 1:56:27So next time, we're going to dive into first-person games in Unity.
    • 1:56:31So we'll look at some of the features that we get for free.
    • 1:56:35We're going to implement a simple maze-like game where you can navigate.
    • 1:56:39And it will be dark and kind of scary, similar
    • 1:56:41to a game called Dreadhalls, which is a mobile VR game.
    • 1:56:43And we'll actually test out Unity's VR, and try and get a VR headset in here
    • 1:56:48so people can check that out.
    • 1:56:51Cool.
    • 1:56:51Thanks a lot.
    • 1:56:52I'll see you guys next time.
  • CS50.ai
Shortcuts
Before using a shortcut, click at least once on the video itself (to give it "focus") after closing this window.
Play/Pause spacebar or k
Rewind 10 seconds left arrow or j
Fast forward 10 seconds right arrow or l
Previous frame (while paused) ,
Next frame (while paused) .
Decrease playback rate <
Increase playback rate >
Toggle captions on/off c
Toggle mute m
Toggle full screen f or double-click video