Placeholder Image

字幕表 動画を再生する

  • COLTON OGDEN: All right.

  • Welcome, everybody, to CS50 on Twitch.

  • My name is Colton Ogden and today we're going to be taking a look at--

  • to depart from prior streams we're going to transfer or transition from 2D

  • and using Love and Lua to 3D and using Unity and C# today.

  • So a little bit of a transition from a dynamic

  • to a sort of statically typed languages and object

  • oriented programming languages, but should be a good time.

  • Some people in the chat already here.

  • So I see [? Bavik ?] is here.

  • So hello [? Bavik. ?] Good to see you again.

  • [INAUDIBLE] good to see you.

  • ForSunlight, good to see you.

  • We've got a bunch of people here.

  • [INAUDIBLE], nice to see you.

  • Thanks for joining us today.

  • Ann100, thanks for coming in again from Peru.

  • Good to see you, as well.

  • Yeah, we've got a lot of people in here already.

  • A lot of people are interested in Unity.

  • So if you're unfamiliar--

  • I'm going to transition to my desktop here--

  • I have a couple of things going on here.

  • I've got Unity in the background, but if you don't have Unity already,

  • you're going to want to go to Unity3D.com and then if you click

  • on this button that says--

  • I'll make it a little bit bigger so we can see a little bit better

  • here and zoom in--

  • it probably looks something similar to this if you're looking at this video

  • maybe in the future, should still be somewhat similar.

  • But on the front page is a Get Unity button

  • that takes you to a page where you can choose which version of Unity you want.

  • There's different versions.

  • There's a plus, a pro, and a personal.

  • Plus and Pro would be for if you're working for a company,

  • or not even necessarily a company-- well,

  • I guess probably it would be in a company situation,

  • but a small or a large company.

  • Or if you're just a hobbyist or making below a certain threshold of income,

  • you can go to the personal option.

  • Try Personal and then it will ask you to accept the terms and conditions

  • and then download the installer for your operating system,

  • or what's called Unity Hub, which is a fairly new thing that they've

  • done which allows you to actually maintain multiple different versions.

  • [? Bavik ?] says, "wow, yeah, I wish we could

  • get a certificate similar to professional development."

  • 42Force, "hello Colton."

  • Hello 42Force, good to see you.

  • And Reema7 says, "Unity star."

  • Reema7, I don't believe I've seen you yet, so thank you for joining us today.

  • Got a fair number of people here already.

  • So yeah, it should be a fairly painless process, no matter what operating

  • system you're running.

  • But definitely go here.

  • Go to the front page.

  • Click the blue button.

  • Follow the instructions.

  • Download Unity Hub or the installer for your operating system.

  • I chose Unity Hub, just cause I think that's where

  • they're sort of trending towards.

  • They've made a lot of changes in the last year or so with Unity,

  • and that is one of them.

  • Once you have that up and running, which should be relatively

  • painless, although it might take a long time because Unity is rather large

  • and also comes with a bunch of different packages

  • for building games for different platforms, like for Android, for WebGL,

  • for Xbox, PS4, all sorts of different platforms.

  • Unity is amazing in that respect.

  • So it may take you a little bit of time.

  • But it's very much well worth it.

  • So once you do have Unity Hub installed, it

  • should look something like similar to this when you first open it up.

  • It'll ask you to log in, so you will need a Unity account, as well.

  • So I believe the Unity sign up link is fairly painless.

  • Looks like id.unity.com will allow you to actually create a Unity ID.

  • You will need to specify a username and a password and email or password

  • and then you will need to log in on your machine in order to use it.

  • But it is a free account and relatively easy to setup,

  • just like Unity personal is free and rather painless to set up.

  • 42Force says, "from Manila in the Philippines.

  • Had to stay up and catch you again."

  • Thanks so much for staying up.

  • We're trying to make the streams a little bit earlier,

  • especially on the Friday streams where we do

  • the longer ones, the game dev ones.

  • So hence why we're starting at 1:00 today.

  • Often we start at 3:00.

  • So thanks for staying up.

  • I'm not sure what time it is in the Philippines.

  • Philippines time.

  • Right now it is 2:00 AM in the Philippines?

  • OK, wow.

  • Well, thank you very much for staying up that late to tune in today.

  • And feel free to go to sleep.

  • We will post the video later on YouTube.

  • And if you're watching on YouTube, you can tune in live at twitch.tv/CS50TV,

  • which will probably be in the YouTube description.

  • So once you have Unity Hub all set up, you have a Unity ID,

  • you've downloaded Unity Hub for your operating system

  • and it's taken you probably a half hour or so because it's a large download,

  • it'll look something like this when you go to create a new project.

  • So there's different tabs up here, all the projects that you have.

  • It has some tutorials baked in so that you can actually

  • walk through some preset projects, and then a bunch of different versions.

  • If you decide to-- maybe you have different Unity projects that have

  • different compatibilities--

  • you can go to the installs thing here.

  • You can also go to a new project, open a project, settings,

  • look at your account, blah, blah, blah.

  • The important thing is the new project because that's

  • what we're going to do today.

  • We're going to build a project from scratch.

  • We're going to look at pong in 3D today.

  • And actually, let me make sure my mixer is set appropriately.

  • It is not.

  • So I should-- now I should sound a little bit better.

  • I forgot to turn off my mixer.

  • So now I should sound a little crisper and not as weighty, I guess.

  • There shouldn't be as much background noise.

  • Let me know if that sounds any better.

  • It looks like now my volume might need to be turned up a little bit, actually.

  • So I'm going to do that, as well.

  • And then if all is good, we should be set to go.

  • 42Force says, "thanks for checking."

  • I was genuinely curious.

  • I wasn't aware that it was that far east or west,

  • depending on how you look at it.

  • KeithSCH says, "hello from the UK."

  • Hello, Keith.

  • Thanks so much for joining us today.

  • Ann says, "it's lunchtime here."

  • It's about lunchtime here, as well.

  • OK, awesome.

  • This is worth to watch live, very engaging lectures as always.

  • Thank you so much.

  • I appreciate it.

  • That's why I love twitch so much.

  • We can have a sort of back and forth.

  • And maybe today we'll cooperate on sort of implementing this project.

  • So what are we doing today?

  • Well, we're going to make a version of pong.

  • So if you're familiar with what pong is, we teach it in my games course.

  • It looks something similar to this.

  • The image is not quite working the way that I wanted it to.

  • It looks like they changed their Google Images UI today, which is hilarious.

  • But it looks something similar--

  • and you can't see because of the chat, as well--

  • but it looks something similar to this where

  • you have a paddle on the left, paddle on the right,

  • or vice versa, because I'm currently flipped.

  • And the goal is to sort of make the ball bounce past your opponent's paddle

  • and strike some area beyond where it exists.

  • And that will trigger a point for you on your side of the screen

  • where you can see there's a score written there, four and two.

  • And it'll be something very similar to what we did today,

  • except we're going to do this in 3D instead of 2D

  • because Unity is, first and foremost, a 3D engine,

  • although it is a 2D engine, as well.

  • 2D was not something it originally came with many years ago.

  • But as of the last few years, it's had quite a good solid set of 2D features.

  • But it's fun to explore it in 3D.

  • So that's what we're going to do today.

  • We're going to make a 3D version and we're

  • going to implement it from scratch.

  • I do have some notes that I took when I implemented it just

  • in case I do hit a stumbling block.

  • But we should be fine.

  • It's a fairly easy project to undertake, even as a completely beginner at Unity.

  • Although we will be doing some coding today.

  • So the nice thing about Unity is it does allow

  • you to not have to code as much as, say, Lua

  • and Love 2D, which is what we were doing the other day,

  • because that is a purely code-based framework.

  • It has no built-in graphical tools.

  • Unity is much more of all encompassing editor.

  • And we'll take a look at the editor tools and see what that looks like.

  • OK, I missed a few comments here.

  • Ann says, "yes, it sounds better."

  • Awesome, thank you so much.

  • [INAUDIBLE] says, "sounds better, yes."

  • ForSunlight, "our green tech teacher taught

  • how to make a real pong game in class, and I'm learning the virtual form."

  • A real pong game, that sounds like it would be much more difficult.

  • Do you mean, like, in hardware or, like, a physical-- like, how to make a--

  • like, actual paddles and a table?

  • Nobody ask long questions today.

  • There's nobody to read them.

  • I will do my best to read every question that comes through,

  • even the long ones, even the long ones today, just for you guys.

  • Agree.

  • "Played pong is an arcade game back in the '60s," says Keith.

  • Yeah, no, it's been around for a long time.

  • But it's such a great game to use as a teaching tool

  • because it has all the basics and it's still somewhat fun.

  • It's a nice, like, entry level piece of software to write, a game to write.

  • And we use it in my games course as the first game that we teach.

  • I'm going to come over here to the other laptop

  • and just plug my games course shamelessly.

  • CS50.edx.org/games.

  • We teach how to use Lua and Love 2D as well as Unity in that course.

  • And it's online on EdX for free.

  • The first game that we do in Lua and Love 2D is pong.

  • But today we're going to be doing it in Unity in 3D,

  • so it's going to be even better.

  • "Can't be sure, [INAUDIBLE]"" says Bavik [INAUDIBLE]..

  • OK, so I'm in my Unity Hub thing here.

  • I'm going to get rid of chrome here just because it's a little bit distracting.

  • I'm in 1080p today, as well, just because the 720p in Unity,

  • it can be a little bit cramped.

  • So we've expanded the size of today's background a little bit.

  • There's no CS50 dot--

  • or twitch.tv/CS50TV in the bottom left today.

  • I might find a transparent overlay I can plug over it.

  • But if you're watching on YouTube, twitch.tv/CS50TV again.

  • And that'll be the last time that I plug it.

  • So I'm going to specify a project name, 3D pong.

  • Just going to save it in my home directory,

  • which is the default location that Unity will store all of your projects.

  • You can specify whatever folder you want.

  • If you keep all of them in your home directory,

  • it's probably going to be a little bit crowded,

  • but I'm not too worried about it right now,

  • just because I'm not using this as a full production machine,

  • more just like teaching tool.

  • But if you have, let's say, maybe slash Unity projects in your home directory

  • or whatnot, that's a great place to put projects.

  • We're doing 3D template not 2D template.

  • You can choose between 3D, 2D, 3D with extras,

  • high definition RP, all these things.

  • Most of those are all brand new to the Unity beta series.

  • And if you download Unity today, or at least soon,

  • compared to where this video is released,

  • it'll probably be a beta version of Unity.

  • Unity is in this sort of continuous beta process.

  • And they've started naming their versions.

  • Previously it was Unity 5.

  • Now they started naming it after the year and they suffix

  • the year with B some number, which is the current beta.

  • But the betas are all very stable, basically the same thing

  • as a release, an RC or Release Candidate type of software.

  • We're not going to use analytics because that's just too much.

  • And once we do that, we click the nice blue button,

  • we should get Unity starting up and doing all of its stuff.

  • And our project will be up and running shortly.

  • ForSunlight says, "physical one but not metals."

  • OK, interesting.

  • That's pretty cool.

  • I am not so great with physical stuff, using tools and hardware

  • and things like that.

  • I'm much more comfortable with software, but if push comes to shove,

  • we can always figure it out, right?

  • But yeah, as you can see, Unity takes a little bit of time

  • to initialize your project.

  • It has a lot of stuff it needs to import and compile to get running.

  • But this only needs to happen one time as it initializes your project.

  • And then thereafter, it'll be faster.

  • I'm impressed everyday what they make as projects.

  • I am nominating the teacher for STEM so everyone can use her projects.

  • Yeah, sounds super cool.

  • Super awesome.

  • You should plug the-- if you have pictures or anything of that project,

  • definitely plug it.

  • So it says my Unity version is a little bit behind.

  • I'm on beta 5.

  • I think currently it's on beta 9, 2018.

  • But it doesn't matter because we're not using any features that

  • are specific to the betas.

  • If I'm being perfectly honest, I don't even

  • know what the beta 9 features are versus beta 5,

  • just because I haven't paid super close attention.

  • But this is Unity.

  • Let me expand this a little bit.

  • So the chat is blocking stuff that's not super important yet,

  • although I may end up shrinking or disabling chat

  • at some point because we probably will need all the real estate we

  • can get on the screen, or at least I might turn it off intermittently.

  • Unfortunately, it clears every time I do that so I can't actually

  • bring it back in full.

  • But we might end up not needing it for a lot of the chat, anyway.

  • So I'll keep reading out the questions.

  • But this is the Unity editor.

  • So it's by default made my hierarchy view a little large.

  • Don't need it to be that big.

  • But we can see here we have a few different things.

  • So this is quite a bit different than using anything or implementing anything

  • in Love 2D or Lua, because those are all just programming environments.

  • They're frameworks that you trigger with function calls, effectively.

  • This is a whole built-in-- or it's a whole sort of all in one editor, right?

  • We have what's called a scene view up here.

  • So if I right click and I rotate my mouse,

  • I can look around the scene, which is currently empty, or at least

  • mostly empty.

  • I have a couple of objects.

  • I have a camera, which you can see on the left,

  • and I have a light source, which you can see on the right.

  • Below my scene view, I have a game view.

  • So that's where I can actually see a rendered frame of what my game will

  • look like when I actually run it, which is nice so that I don't actually

  • have to keep running my game.

  • If I just want to see that something visually is changing

  • or that my camera is aligned correctly, it renders continuously.

  • Not 60 frames per second, necessarily, but if you update your scene

  • it will reflect in the game view.

  • And you can see it's named game here, although it might be a little bit hard

  • to see because it's a really tiny interface.

  • And then the Scene tab up here.

  • And then there's also the Asset Store tab, which we probably

  • won't look at today, but in the future we can definitely take a look at that.

  • Reamof7 says.

  • "I'm so excited.

  • Did that roll the ball tutorial and was so lost."

  • Yeah, well, if you have any questions as we're going through today's code,

  • definitely let me know.

  • Today's code will be similar to that.

  • It's been a while since I've looked up the Unity roll a ball code,

  • but most of that actually should be fairly similar to the things we

  • talk about today, things like rigid bodies and using basic game objects.

  • Yeah, should be more or less similar.

  • So we have our scene.

  • We have our game view.

  • We have what's called our hierarchy.

  • So this is what shows everything in our scene.

  • So like I said earlier, we have a main camera and a directional light.

  • Can I make this any bigger, by chance?

  • Let me just see.

  • It's a little small, but I'm not sure if that's something we can easily change.

  • Zoom, maybe?

  • Can we do that?

  • Oh, that just zooms the--

  • I think that just zoomed the game view.

  • But this is the hierarchy here.

  • And you should be able to-- if you're watching this in 1080,

  • you'll be able to see it just fine because I'm actually

  • shooting it in 1080.

  • But this is the hierarchy which shows all of our objects.

  • So like I said, this is the camera on the left.

  • This is the light source on the right.

  • And the camera is obviously what is going to be rendering our scene.

  • It's like we have an actual world that we're using now.

  • And you can think of it as a physical camera.

  • And you can actually change it.

  • So if I were to go over to this camera, I can actually click on it

  • and edit its transform.

  • So notice that I clicked this button up here at the very top left,

  • this little arrow thing right up here.

  • And what that allows me to do is it triggers these three

  • arrows, these three colored arrows, which

  • tells me I can move this object along any of these arrows.

  • So these are all different axes.

  • So now we're not in 2D where we have just x and a y.

  • We're actually in 3D.

  • So we have x and y and then we also have z,

  • which you can sort of think of as going towards you--

  • towards or away from you in space, right?

  • And you can arrange your world such that x accomplishes that function, as well.

  • But the trend typically is to have x and y be sort of the frame like this,

  • and then z to be the vector that points between you and the game world, right?

  • So it's that extra third dimension.

  • And so if I drag one of these arrows, you

  • can see that I'm actually moving the camera up and down.

  • And I can do that.

  • I can move it left and right, as well.

  • And it's not actually going to change anything in the scene,

  • or at least visibly, because we don't have any objects in the scene.

  • We don't have a point of reference.

  • But I could easily go over to my object hierarchy,

  • for example, right click, go to 3D object cube.

  • Notice that now I actually do have a 3D object.

  • And I could actually move this around with its transform,

  • just like I was doing with the camera.

  • And you can see that the game view is actually rendering this in real time

  • every time I change the object it's changing what's rendered to the screen.

  • And so if I move the camera, just like I was moving the object,

  • now it has the same effect where things are changing based

  • upon where the camera's position is.

  • And the camera can also rotate, as well.

  • So maybe I don't necessarily want to just move it.

  • I want to actually change what angle it's looking at.

  • I can do that with this command up here.

  • Notice that up at the very top left I have that button that I click to move.

  • Next to that on the right of that is an actual rotation tool

  • which allows you to not only translate on a given axis

  • but rotate on a given axis, as well.

  • So super flexible, allows you to position everything the way

  • that you want.

  • Want to get everything sort of back there.

  • All right, let me just take a look at the chat,

  • make sure I didn't miss anything.

  • "Hello from Bangladesh," says [INAUDIBLE]..

  • Good to have you, [INAUDIBLE].

  • I'm not sure if you've been here before.

  • I don't recognize the name, but I'm glad to have you today with us.

  • Thanks so much for joining.

  • So, pong in 3D.

  • So we've covered-- so the scene view.

  • We've covered the game view.

  • We've covered the object hierarchy.

  • We can add objects.

  • We can move them.

  • We can rotate them.

  • That's sort of the foundation of what we do, right?

  • Any scene that we have is going to have models

  • that are in our view that get rendered that can maybe rotate around,

  • that can move around, interact with each other.

  • And obviously we're going to want to do some programming of certain things

  • in order for them to have more complex functionality,

  • for example we want to be able to move our paddles in real time, for example.

  • We want the ball to bounce off of surfaces.

  • So we're going to need to tell it how--

  • we're going to need to give it the right components or tools in order

  • for which to detect sort of collisions between other objects

  • and those sorts of things.

  • But we'll dig into that a little bit.

  • I'm going to finish off our tour here of the object-- or the editor view

  • real quick by just seeing this tab over here.

  • And I disabled the chat so that it's not sort of covering up

  • what I'm trying to demonstrate.

  • We can bring it back if we don't need it as much in a little bit.

  • But this is sort of a file system view of your project

  • so that you don't have to do the tedious sort of file management

  • that you would often have to do in something like Lua or Love 2D.

  • Let's say I want to add a graphics--

  • or I want to add a sound file to my project.

  • I'm going to need to generate the sound file, put it somewhere,

  • which I still would have to do with Unity.

  • But at that point, I still have to manage it in the file system.

  • If I want to move it around or do anything with it outside of Lua or Love

  • 2D, I'm going to have to manually go into Finder or File Explorer,

  • if I'm on Windows, or whatever the default sort of window manager

  • is in Linux or other operating systems.

  • But in Unity, you actually get a file system view within the editor itself.

  • And you can move files around and this becomes very helpful

  • as we start digging into using resources amongst our game objects.

  • For example, if we want to assign a sound to a paddle

  • or to a character moving around the scene,

  • we can just click and drag the sound file

  • in our actual hierarchy-- or our file system

  • or project view here directly onto our game object.

  • We don't have to do anything in code.

  • You don't have to link those things in code rather than in our file system.

  • It's super nice, super handy, super integrated.

  • And then the last big thing that you see by default is on the right here,

  • this thing called the inspector.

  • And if I click on my main camera, for example,

  • you can see the inspector populates with what are called components.

  • And these components are responsible for all behavior in Unity.

  • So for example, everything has a transform component

  • by default, which is what gives it a position, a rotation, and a scale.

  • So whenever we actually manipulate, for example, this transform on the y-axis,

  • it's actually changing values if you see in the position field

  • there on the right.

  • And if I were to move it along the x-axis, you get the same thing.

  • It's now manipulating the exposition.

  • And those are all sort of text fields that you can manipulate or edit

  • yourself.

  • So if I were to say this is going to be position two,

  • notice that it instantly moved to 2 on the x-axis, 2 Unity units, which

  • by default is approximately 1 meter.

  • So you have the not only fine-grained control

  • via using the actual sliders, the arrows themselves, in the scene view,

  • but also manipulating them as by entering them manually in these fields.

  • And you can also manipulate them programmatically through scripts.

  • The camera, as an example, also has a camera component

  • which allows it to render to either itself

  • or to something else, which is super nice.

  • For example, you can render it to a texture

  • and have something like a TV in your scene

  • that's actually getting the input of another camera in your scene.

  • But by default, whatever your main camera is

  • is just going to render to your default graphics

  • device, which is your graphics card, which

  • will be broadcasting to your monitor.

  • And you can do various things.

  • You can have the camera have a skybox as it's background.

  • So notice that in the game view down here,

  • we have sort of this sky view behind our cube.

  • But if I wanted it, for example, just to be a solid color,

  • I can just click solid color there and maybe make it white or make it black

  • or make it blue, any of those, and it changes as well.

  • If I, for example, wanted a more simple aesthetic--

  • and we actually will do that.

  • We will do that later.

  • We'll have a background color of maybe some gray-ish

  • and then the rest of our scene will sort of

  • be black and white, similar to the actual pong, but obviously in 3D.

  • But these are components.

  • These are going to be what's responsible for all of the behavior in our game.

  • Now, today's stream is probably going to be about three hours long

  • as we implement pong.

  • I would say if we do go over, it possibly might go to four hours,

  • depending on if we go into any sort of side tangents

  • or if we want to do a particular deep dive on some subjects,

  • depending on the complexity, of course, of the topic.

  • But I'm going to estimate three hours, potentially four hours.

  • But it will be a from scratch, fairly encompassing tutorial.

  • So I think that is the-- that's more or less sort

  • of the basic gist of the default editor settings and the default panels

  • and sections.

  • We'll see more as we continue implementing a lot of this game.

  • But I think the next step will be to actually think about,

  • what are the pieces of our game and how to implement them there.

  • So I'm thinking pong, it needs paddles.

  • It needs a ball.

  • So what I probably want to do is have maybe a couple of rectangular,

  • cube-like, I guess, rectangular prisms to be our paddles, and then a ball.

  • We can use a sphere to be our ball.

  • And Unity thankfully makes this fairly easy to just add by default.

  • So this cube I wanted to delete here.

  • And I'm going to set my camera back to its default position.

  • Udon Master says, "would it be a 3D pong but works only on the 2D axis?"

  • Yes.

  • So today we're going to implement a 3D--

  • it's going to be a 2.5 D version of Pong, where everything is in 3D,

  • and we can see it in 3D, and we can see perspective.

  • We can see how--

  • we can rotate our scene around and see it working that way.

  • But we're only going to be able to move left and right, just

  • like the original pong game lets us move.

  • And it's going to therefore still be constrained effectively

  • to a two-dimensional axis.

  • The paddles themselves are more a one-dimensional axis.

  • The ball itself will be moving in 2D.

  • And so therefore that's more what gives it the 2D feel.

  • But yes, good question.

  • OK, so I'm going to go ahead and start adding some placeholders for what

  • I want in my scene.

  • They're not placeholders as much as they are just

  • kind of shells for what we'll be implementing later.

  • But let's say I want a cube.

  • I'm going to-- let's say this is going to be paddle one.

  • And notice that I gave it a name here in the scene or the object hierarchy, just

  • to let me know what that object's purpose in life is.

  • So it's paddle one.

  • I'm going to go up here to where I have the Hand tool, the Move tool,

  • the Rotation which you looked at earlier.

  • There's also something called the Scaling tool.

  • I'm going to click on that.

  • I'm going to shrink this down a little bit on the y-axis.

  • Notice it's just sort of flattening the paddle.

  • I'm going to do this, as well.

  • So I get kind of a--

  • kind of a paddle view here.

  • Now, if you right click and you use WASD,

  • you can actually move around your scene like in a game.

  • You can actually move the camera in three dimensions, more

  • like you're flying around, which is kind of nice, rather than necessarily

  • having to click and rotate around.

  • I like using WASD so I can move backwards, forwards, et cetera.

  • This paddle is more or less good.

  • I'm going to just flatten it a little bit more.

  • And then do I want to extend it?

  • Maybe I'll extend it a little bit on this direction.

  • I'm going to come out here.

  • I'm going to go back to moving it.

  • So the nice thing is you can actually use

  • QWERT to change how you're manipulating the transform, whether you're just

  • moving the hand around the scene, whether you're

  • moving the actual thing itself, whether you're rotating it,

  • whether you're scaling it.

  • So I'm going to hit w to actually move it.

  • I'm going to move it over here.

  • And I'm going to sort of set my scene up the way that I think I might want it.

  • So I have that paddle there.

  • I'm going to move it a little bit over here.

  • I'm going to make sure my paddle is selected.

  • I'm going to Command-D to duplicate it.

  • I'm going to call it paddle two.

  • And it's going to be in the exact same location as the paddle

  • that I just made, but I'm going to kind of just

  • move my view over here a little bit.

  • I'm going to just drag it right over like that.

  • I'm not using any, necessarily, hard-coded placements for these.

  • But I could if I wanted to.

  • I could say the Z on this one, maybe it should be negative 5.

  • And then the Z on the other one should be, let's say, 5, right?

  • So they're about-- what would that be?

  • That would be about 10 units apart.

  • So they're exactly 10 units apart at this point.

  • But we're just eyeballing it.

  • We don't necessarily care too much.

  • I have two paddles now.

  • They're kind of in opposite views of each other.

  • It's a little bit hard to see, so I'm just going to do that.

  • Now, the nice thing that you can do is if you have your camera selected

  • and I go over to--

  • I believe it is game object.

  • And then you do Align With View, you can actually

  • do that and now the camera is rendering exactly how we're looking at the scene.

  • So this is super handy if you want to look around and find

  • just the perfect angle but you don't want

  • to manually move your camera around.

  • You make sure your camera is selected, go to Game Object,

  • go to Align With View.

  • Super handy.

  • I'm going to go back here just a little bit.

  • I'm going to add another thing to my scene.

  • I'm going to create a 3D object.

  • I'm going to make a plane here.

  • So it's about the fifth or so option.

  • And so now this is going to be sort of my ground object.

  • Let's make sure that it's--

  • so it's going to be something like that, right?

  • Probably going to need to scale it out just a little bit.

  • So I'm going to hit r to scale on the z just a little bit.

  • It's a little bit hard to see, unfortunately.

  • So why don't we do something with color?

  • So right now we have a few different game object types.

  • But they're all white.

  • It's hard to kind of see which one is which.

  • And the way that Unity does colors and makes things look differently--

  • beyond colors, also just different ways to light things and make things

  • look like they have different textures associated with them--

  • is through materials.

  • So in my assets, I have a sub folder in assets called scenes.

  • I'm actually going to go to my assets.

  • I'm going to right click it.

  • Create a new folder.

  • And I'm going to call this materials.

  • And so what this will do is now I have a couple of folders within assets.

  • In materials, I'm going to make sure that's selected.

  • I'm going to right-click that.

  • I'm going to go to Create a New Material.

  • And notice that the icon is sort of like this sphere.

  • So it just, at a glance, tells me, oh, this is going to be a material.

  • This isn't a script.

  • This isn't an image.

  • This isn't an audio file.

  • This is a material, which means that you can assign this

  • to an object in your scene and give it some sort of color

  • or some sort of texture.

  • I'm going to call this--

  • we'll call this the board mat.

  • And then I'm going to go over to this little color picker

  • thing on the right where the inspector is,

  • next to where it says albedo, which is just sort of like the light reflection

  • parameter of your material.

  • And notice that it pulls up this little color widget which is super handy.

  • I'm going to make that a sort of dark gray color.

  • And nothing has changed in my scene because I haven't actually

  • assigned my material to anything yet.

  • So I'm going to click on that material.

  • And this is something nice about Unity.

  • You can just click and drag from your scene into--

  • from your inspector onto the scene.

  • And now the material, it highlights in advance

  • to tell you how it's going to change.

  • And then it actually changes.

  • Now, the problem is that I believe the paddles are underneath the--

  • yeah, they're underneath the plane.

  • So I'm going to make sure that the paddles go above the plane.

  • So I'm going to--

  • I'm just going to lower the plane down.

  • So I'm going to hit W again, lowered this just a little bit.

  • And now notice that we can see our paddles against the background,

  • as opposed to everything just being white.

  • Now, I don't quite like how big the board is.

  • I want the palace to kind of touch just up against the--

  • just up against the edges.

  • So I'm just going to do that.

  • This might be a little bit too close for comfort for the game, but we'll see.

  • We'll fine tune it as we need to.

  • And yeah, that's our play field all set up.

  • Now, the directional light is casting a shadow, which is kind of cool.

  • So a directional light-- and we haven't talked about lighting yet--

  • is a light source that just means illuminate

  • the entire scene like sunlight.

  • So no matter where you put it, it's not going

  • to change how it actually behaves.

  • So if I were to just move this anywhere, like

  • if I move up or down, on its local x-axis, on its local y-axis,

  • notice that it doesn't actually change the shadows at all.

  • So if we're looking at the shadows there and I move this,

  • the shadows don't change whatsoever because it

  • doesn't matter what position your directional light is.

  • It's a global light source.

  • So it's going to behave the exact same on every object

  • no matter where it's located.

  • I'm probably just going to leave it as is because I kind of like the--

  • I kind of like how the shadows sort of add a little extra layer

  • just as-- you demonstrate to us even more that we're in 3D.

  • I'm going to--

  • I think I'm going to make the background darker, though.

  • So I'm going to set the background not to skybox but to solid color and not

  • to blue because it's a little hard in the eyes,

  • but to kind of this darker color, this darker gray.

  • And so now when we render our game on the bottom left,

  • we're actually seeing a fairly easy to view shot of all of our objects.

  • We have our paddles nice and cleanly set against our board, which is nice

  • and cleanly set against our background.

  • So everything is working pretty nicely.

  • If anybody has any questions thus far on Unity,

  • definitely toss them in the chat.

  • I'll be looking at it.

  • But yeah, that's getting all the placeholders in there for now.

  • The next step I think would probably be to have maybe our paddles moving

  • back and forth.

  • I guess before we can do that, we can also just add the ball to our scene,

  • right?

  • I'm also going to rename the plane to board.

  • It doesn't matter too much.

  • But I'm going to create a 3D object.

  • I'm going to create a sphere.

  • It's quite a bit too large.

  • It's a very large pong ball.

  • I'm going to set this roughly in the middle

  • here, so right about there, right about here-ish.

  • I'm going to shrink it down quite a bit because it is rather large.

  • And I'm going to go over to my scale.

  • I'm just going to set all these to 0.2 manually

  • so I don't have to do it myself.

  • Is that too small, maybe?

  • We can do-- maybe we'll do 0.3, how's that?

  • We'll do 0.3 on every axis so that we get a uniform scale because if we-- we

  • can scale different numbers on different axes

  • and that will have the effect of elongating the ball.

  • So if, for example, if my y is still 1--

  • [COUGHS]

  • Excuse me.

  • Not y, 0.3.

  • If we set the z, for example, to 3, we can

  • see that we get this very elongated ball that looks like a very distorted oval.

  • So you can scale differently among different axes.

  • But to get a uniform shrink on your object,

  • you want to scale the same amount on every axis.

  • So I'm setting 0.3, 0.3, 0.3 on a scale, on my ball.

  • And that's roughly a good size, I think.

  • Let me just get out of the transform view

  • so we can see what our scene looks like.

  • And if I were to run my game, which I can do, absolutely do--

  • you click the Play button at the very top.

  • And now it's actually rendering the game in real time,

  • like properly, as opposed to just changing the game view

  • when we make changes to the scene.

  • But nothing is changing.

  • Nothing is happening.

  • This is our game, right here.

  • But this is actually running like an actual game.

  • It's running 60 frames per second or however close it can get to that.

  • But it's completely non-interactive because we haven't programmed

  • any interactions within our objects.

  • They don't have any sort of physics so they're not falling.

  • They're not doing anything.

  • So what I want to do is start thinking about how to implement

  • some interaction amongst the--

  • amongst the paddles, or how to actually let them

  • move left or right in the scene.

  • [? MachaBean ?] says, "best of luck."

  • Thanks, [? MachaBean. ?] Much appreciated.

  • Yeah, we're off to a good start.

  • "The light reflection is so cool," says Astley.

  • Yes, agree, definitely.

  • And there's a million different things you

  • can do with textures to make all kinds of different cool effects,

  • things called shaders which will change how light interacts with your objects

  • to give them different sort of artificial details

  • or different abstract colorizations.

  • It's a lot of cool stuff you can do with shaders.

  • Reema7 says, "now the good stuff is happening."

  • Yeah, we're getting there.

  • We're getting there.

  • Slowly but surely.

  • All right, so now we can start taking a look

  • at how to add new behaviors to our scene using what are called components,

  • which we talked about earlier.

  • We looked at some components that were on the camera.

  • If we look at our paddle, paddle one, for example,

  • we can see that it has components, as well.

  • It has this thing called a mesh filter, which allows it to actually contain

  • all of the vertices for our mesh.

  • It has a mesh renderer, which has the code necessary to take those vertices

  • and actually render it to the screen.

  • It has a thing called a box collider, which

  • comes by default on every 3D object that you

  • add to the scene, which allows it to collide

  • with other objects for collision detection.

  • And it has a material, which all objects by default

  • get the Unity default material, which is this white sort of semi-shiny

  • looking material.

  • But we want to say if I press left or right on the keyboard I

  • want my paddle to move left or right, which we

  • can do through the power of scripting.

  • And so this is where we get into C# and the actual programming side of Unity

  • and implementing our own what are called mono behaviors.

  • You can think of mono behaviors and components

  • as sort of being the same thing.

  • And they just named mono behaviors because C# on Mac needs what's called

  • the mono framework, which allows it to actually run C# dot net applications,

  • which traditionally are Windows-only.

  • And Unity actually started off as a Mac-only game engine,

  • but over the course of time became very much a multi operating system game

  • engine.

  • So how do we implement our own component from scratch?

  • So I'm going to go to my assets folder.

  • I'm going to create a new folder here, call it

  • scripts just to keep everything fairly organized.

  • So this is a good way to stay organized.

  • But you could do things however you want,

  • as long as you sort of impose your own sort of consistent scheme

  • for keeping your files in the right way.

  • In my scripts folder, I'm going to right click.

  • I'm going to create a C# script.

  • Notice that that came up on the menu there.

  • And then I'm going to call this paddle.

  • And so the paddle script is going to be anything

  • that encapsulates the behavior of paddles and how they should operate.

  • So if I double click on paddle, the script that I just created,

  • notice that it opens up my default text editor, which in my case

  • is VSCode, Visual Studio Code.

  • I believe by default now it is Visual Studio proper, so actual Visual Studio,

  • which is a larger and more feature-rich IDE for actually debugging and running

  • your applications.

  • My editor-- I thought I disabled this, but it has these--

  • I have what's called Omnisharp, which is an extension that will allow it

  • to actually give you a lot of real time sort of analysis of your program

  • if you're running a C# application.

  • And it analyzes the solution file and does real-time debugging and reference

  • checking.

  • I'm going to disable the reference code lens because it's kind of obnoxious.

  • Notice that that took away all those reference words that were here before.

  • I'm going to zoom in a little bit so you can see a little bit better.

  • Make sure this is all over there.

  • Turn the chat back on because now we'll actually have the ability

  • to see it on our text editor.

  • And then close this bottom thing here.

  • So if we're looking at this, this is the default structure for a Unity script,

  • a C# script in Unity.

  • And this is C# syntax.

  • It's very similar to Java, if you're familiar with Java

  • and you've ever programmed in it.

  • But basically, we have these-- it's based around the idea of a class.

  • So everything in C#, everything in Java, is a class,

  • which is just a representation of some object type that should exist and it

  • allows us to build beyond things like ints and floats and strings,

  • things that you see in other programming languages to represent basic number

  • and data types.

  • We can actually implement the idea of an object called

  • a paddle and all of the data and functions that

  • should be ascribed to it.

  • So the ability to, for example, move, or whatever data

  • it needs to keep track of how to move.

  • Zodiac says hi.

  • Hi, Zodiac.

  • Good to see you again.

  • So noticed that this is what's called a public class.

  • So it's available anywhere in our application because it's public.

  • If it were private, it would not be available.

  • We are using all of these things by default up

  • here, using system.collections, using system.collections.generic, using

  • Unity Engine.

  • These are things that you get imported for you for free that basically tell

  • your script, I'm going to use data inside

  • of these namespaces called system.collections,

  • system.collections.generic, and so on and so forth,

  • that have some code already written for me

  • so that I can include those into my own script.

  • "So you'll create another class for the ball?" says Astley?

  • Yes.

  • We will create another class for the ball, and a few other ones, as needed.

  • And we'll actually create a separate one for the-- if we have time,

  • we'll do some AI for the paddle and create

  • a separate script for the paddle.

  • [? Bavik ?] says, "yes, exactly."

  • You can create a class for pretty much anything you want to,

  • and you can create classes that aren't even necessarily mono behaviors.

  • So what a mono behavior is, is that's something specific to Unity.

  • And that basically means that this script can become a component.

  • You'll be able to actually see it in the inspector

  • and be able to manipulate it with the fields

  • that we were looking at earlier, for example, the transform, how

  • we were able to change the position, rotation,

  • and scale of that transform ourselves.

  • We can actually change that here.

  • But we can also, when we've made it a public class and we've created these

  • public variables-- for example, if I said public int score, like that--

  • basically we're saying this integer called score is going to be publicly

  • available, meaning that because we're using a mono behavior,

  • because this is a Unity component-- mono behavior, Unity component--

  • we'll have access to this score variable within our editor itself.

  • So real quick, we'll take a look at that.

  • So if I go back to my game here, it will compile any changes

  • that you make to a script.

  • It will compile for you as soon as you get back into the game.

  • I'm going to go to my paddle one.

  • I'm going to go down here to this-- where the inspector is,

  • and thankfully the chat is just above it.

  • But if I click this add component thing here,

  • notice that it brings up a little search dialog.

  • I can actually click--

  • I can look for paddle, which it added it to my sort of list

  • that I could choose from.

  • Click paddle.

  • And then you won't be able to see it because the chat is there.

  • But if I disable the chat, you can see that I actually

  • have access to score here, and I can set that to whatever I want.

  • For example, if I set that to 10, now the score is 10.

  • We're not doing anything with the score.

  • It's just a piece of data.

  • But that allows us to have access to a lot of things

  • that, instead of needing to change them in code, maybe

  • we want to just make them accessible in the editor

  • and change them ourselves there.

  • So back to VS Code, that's what you get for making

  • any of these pieces of data public.

  • Different from public class, this is specifically

  • related to making anything within your component public, right?

  • And notice that unlike Lua, which allowed us to just say score equals 0,

  • image equals image, we actually have to specify the type of the data.

  • We can't just say score and have C# figure out what score is.

  • We have to say it's an int.

  • It's an integer, meaning that it has to be

  • a whole number, negative or positive, and that will be our score, as opposed

  • to an image, as opposed to a floating point

  • value, which has a decimal point, as opposed to infinite data types that you

  • can make of your own type.

  • So beyond the variables that you can actually put into your component,

  • you can also see that it comes with a couple of default functions, default

  • methods, in this case start and update.

  • And so what start does is this is a block of code.

  • It's empty by default because Unity doesn't know how you want to use it.

  • But basically it says at the very beginning of the game

  • when this object is what's called instantiated-- meaning created

  • from nothing, in object terms, object-oriented terms.

  • When we create this object, it's going to call the start method

  • and run it just one time, at the very beginning of its lifecycle.

  • And then we have this function called update.

  • And what update does--

  • and again, it's empty because Unity doesn't

  • know how we want to use the object.

  • It's meant for us to write it ourselves.

  • We want to, in this function, specify everything

  • that this component should do every single frame of execution, which

  • typically is one sixtieth of a second, if we're

  • running our game on a computer that's capable of running it without lagging,

  • in which case the frames might be--

  • it might run it at a--

  • maybe every two frames, every three frames update would then get called.

  • MetalEagle says, "transform is a CSS style to rotate things on a web page.

  • I find it neat that the wording is similar."

  • Yeah, no, absolutely.

  • And it all sort of comes from geometry and linear algebra,

  • the idea of a transform, applying to something in Euclidean space.

  • And our cart--

  • I sort of get the terms mixed up.

  • A Cartesian coordinate system, Euclidean space, all that sort of thing.

  • [? Bavik Knight ?] says, "strongly-typed language."

  • Yes, C# is a strongly-typed language, in which we have to specify,

  • rather than letting it figure out what the data is, what it means,

  • how we should treat it.

  • It needs to be explicitly told.

  • And this allows it to perform more optimization as related to that data.

  • And it actually compiles it down to an intermediary format

  • for what's called the common language run time, the CLR, which

  • is sort of similar to the JVM, which is the Java Virtual Machine, which

  • is a layer closer to machine code but still a little bit above machine code.

  • All right, so that's the anatomy of a basic component.

  • Now, what we want to do is I want to be able to say if I press left or right,

  • I should move my paddle, you know, left or right, right?

  • So if I say if input.getAccess--

  • or rather, I'll just say get key left, which

  • means if I'm using this thing called input, capital I, which is something

  • that Unity gives you.

  • And it has a function called getKey.

  • This is sort of like love.keyPressed, if you're familiar with the other streams

  • that we did on Lua.

  • But basically, I can say if I'm getting the key left,

  • I want to do this thing called transform.translate.

  • And let's say I want to move--

  • make sure that I'm on the right axis.

  • So I'm on the x-axis.

  • I want to move it left, right?

  • And we could see up at the top right, it gives us

  • a indication of where negative and positive are, positive and negative

  • are.

  • So in this case, positive on the x is to the right and negative on the x

  • is going to be to the left.

  • So I want to move my--

  • I want to move my paddle to the left some amount when I hit left,

  • a literal left key on the keyboard.

  • Notice that I took that as a string very similar

  • in spirit to how we did things with love.keyPress.

  • And I took a key which had a string type.

  • So it takes a vector.

  • So let's say new vector 3.

  • And then let's say negative 3, 0, 0.

  • So what this will do is it will perform a translation,

  • just like we did with ourselves in the Unity editor

  • by clicking on its three dimensional transform object in the scene view,

  • this will do the same thing but allow us to do it in code.

  • And I can say else if input dot getKeyRight transform dot translate.

  • And notice that C# is a little bit different than other programming

  • languages in that functions and methods are typically capitalized.

  • This is a stylistic thing that C# does, which is very different from most other

  • languages.

  • But this is something that you will see a lot when diving into C#.

  • And it's also a very idiomatic in C# to make sure that your curly brackets are

  • on the next line as opposed to how we typically do things in, like, say,

  • JavaScript or even Java.

  • You have your curly bracket on the same line as your method.

  • Now, you can change these rules as you see fit.

  • But it is common practice in the world of C# to do things this way.

  • So we will try to stick with that trend, just for consistency.

  • But if you're working by yourself, you can kind of

  • adhere to whatever your own--

  • whatever your own preferences are.

  • [INAUDIBLE] says, "translate is another CSS style for a web page."

  • Yes, I am somewhat familiar with both of those.

  • I don't dig into CSS a lot, but you'll see that nominclature

  • around quite a bit when dealing with anything

  • related to sort of moving objects around the screen.

  • CSS and most game frameworks, they all rely on the same terminology.

  • I'm going to go into my other else if block here.

  • And then notice that when I called transform.translate,

  • there are a few things going on here.

  • So first off, this lowercase transform is lowercase because it is a field.

  • It is a private--

  • well, it is a public piece of information associated with every game

  • object and every component has access to it,

  • which just means whatever the transform is of this current game object.

  • So if we assign this paddle script to one of our paddles, either one,

  • we'll have access when we call this update

  • function on whatever that specific game object's transform is.

  • So you will get transform sort of for free, which is nice.

  • You don't have to--

  • notice that we didn't declare anywhere in our script,

  • but we have access to it, just because that's a feature of mono behaviors.

  • They are given a reference to that transform for free.

  • We looked at what translate was and then the translate function itself

  • takes as an argument a new vector 3.

  • So the new keyword basically says, let's instantiate this new object,

  • a brand new object of a specific type-- in this case, it's a vector 3--

  • and a vector 3 is essentially just three values stored together as one.

  • And typically x, y, and z.

  • And because we wanted to move our object left or right

  • and that mapped to the x-axis in our scene, the parameter that we populated

  • in our vector 3 was negative 3.

  • If we press left, which went to the x-axis, and then positive 3.

  • If we pressed right, also on the x-axis.

  • JewishRambo says, "why vector 3?"

  • Just covered that.

  • A vector 3 is just a x, y, z pair, and that's

  • what the transform.translate function accepts as its argument.

  • And that's a function that is written in Unity.

  • It's something that Unity has defined in advance and that's what it expects.

  • And that's another thing about strongly typed languages

  • is they expect very specific arguments as opposed

  • to languages like Lua or Python, which allow you to basically give it

  • whatever you want.

  • You have to make sure that you give it the right data type

  • or it will give you an error.

  • In Unity, it will say there was a compilation error.

  • [INAUDIBLE] says "3D vector?"

  • Yep, a 3D vector, z, y, z.

  • [INAUDIBLE] says, "makes sense."

  • And so if I were to go back to my application, back to Unity,

  • and I have a paddle just on this first--

  • or a paddle component just on this first script.

  • And the second paddle does not have the script.

  • So if I were to run this and my code is correct, if I hit left or right,

  • notice that it just goes insanely fast.

  • It's working.

  • So if I hit left, it goes left.

  • If I hit right, it goes right.

  • But it's going way too fast.

  • And that's because it's going 3 Unity meters per frame,

  • which is not the desired behavior.

  • We want it to move effectively 3 meters per second, or negative 3 meters

  • per second, which is a bit more of a rational scale

  • at which to move our paddles.

  • And this is something that's a result of--

  • this is something that we can fix using what's

  • called delta time, which is something that we have actually

  • looked at in Love 2D which is the amount of time that

  • has elapsed since the last frame.

  • And so Unity thankfully gives us access to this very easily.

  • We can just do something as simple as our negative 3 in our x

  • parameter of our vector 3 here we can say times time dot delta time,

  • times time dot delata time.

  • And so we're scaling now that 3, the negative 3 and the 3, by however many--

  • however much time in seconds has elapsed since the last frame,

  • which should be about 0.0016 or 0.016, something similar to that.

  • Just like we did before, If you watch the prior streams on Lua

  • and Love [? TD, ?] update takes a parameter called

  • delta time, which we multiply by anything that we

  • want to move over the course of time.

  • Translations typically should abide by this,

  • or you will be moving in meters, not in meters

  • per second, which is the ideal amount that you should be moving your objects.

  • So if I go back to Unity and I run this again,

  • it's going to compile it for a second, but as soon as we're ready to go,

  • notice that now the paddle is actually moving at a much more reasonable rate.

  • And if I press left or right, only the paddle that had the paddle component

  • is updating.

  • The other paddle doesn't have any components of our own

  • on it, so it's just staying there completely still.

  • So super easy to get some basic paddle movement.

  • Now, the paddle is not constrained at all,

  • aside from being constrained on the x-axis,

  • because that's the only thing it's looking at.

  • So we need to decide how do we actually block

  • the paddle from moving beyond the left and right edge of the screen, right?

  • And so we could do this with--

  • we could do this in a couple of ways.

  • But typically what you'll do is you'll use a physics engine

  • to compute collisions between objects.

  • And the way that we're going to do that is with what's called a rigid body.

  • And if you-- by the way, if anybody has any questions on the code

  • that we went through or how I got it to work, how we use time.deltaTime,

  • again, time is this thing that Unity gives you for free.

  • It's part of this using Unity engine up here.

  • Same thing with input.

  • Input and time are both static objects that you

  • have access to different fields on that get updated for you.

  • They both are basically--

  • Unity feeds them information as it's running.

  • And you can access that information at any given time

  • just by referencing capital time or capital input

  • and then whatever the function is that you need.

  • So let's put a few more objects in our scene.

  • I'm going to go back here.

  • I'm going to create a few different things.

  • So I'm going to create some 3D objects.

  • I'm going to create a cube.

  • I'm going to move this cube over to the left boundary of my game.

  • I'll just make sure that it's more or less in the right spot.

  • Needs to be like that.

  • And then I'm just on the edge, just like that.

  • And this is going to be basically just the--

  • Andre says, "hi Colton.

  • Just curious, why using get key rather than get axis?"

  • In this case, get axis would work fine, too.

  • There is something that we could do which

  • is kind of handy, in that we could actually

  • expose the different keys for our paddles so that I could say--

  • if I were to say, for example, public string horizontal, vertical,

  • and then I were to say input.getKey horizontal--

  • or rather, sorry, they're both horizontal.

  • If I were to just say left right and then I were to say this is left

  • and this is right--

  • so we made this.

  • We made these two variables here called public string left and right.

  • And we could probably do this with get access as well.

  • Get access is ultimately a more flexible solution

  • if you're going to publish your game on multiple different platforms.

  • Get axis basically relies on you specifying in your Unity settings what

  • each axis maps to, for example horizontal being

  • a set of different buttons, and the--

  • for example, if you're on a console, get axis will map to your control stick.

  • You can also say that it's also A and D, if you want to move left and right.

  • And it's also left and right.

  • You can specify all these things.

  • But in this case, I'm going to say--

  • I'm going to make the left and right a little bit more flexible

  • so that I can map them to different objects and have exposure in the editor

  • and a little bit more fine grained control.

  • So now I can say public string left right, just like that.

  • And there's probably a way to do this in get axis, as well.

  • But I'm going to go over to my paddle now,

  • paddle one, and if I write in here left and right.

  • Now if I run this, it should have the exact same behavior

  • as before where I can move left and right.

  • But if I go over to my other paddle, paddle two, which doesn't have a paddle

  • component, I add a paddle component, and then I

  • say left should be a and right should be d on that one.

  • And then I hit--

  • save my scene-- and then I hit play.

  • I can go left or right on that one and then A and D on the other one.

  • I've essentially modularized-- or not modularized, but I've--

  • what's the word I'm looking for?

  • Factored out the button presses between my paddles

  • such that I can flexibly sort of set them however I want to.

  • And you could ultimately do something like get axis left and right, as well.

  • And that would have the same effect, and would probably

  • be a little bit more flexible.

  • But no real super fantastic reason, I guess, in the end.

  • But just because that is kind of an easier way to also think about it.

  • Get axis is a little bit more of a higher level abstraction on input

  • that requires you to specify some things yourself in the settings

  • and requires you to kind of dig around a little bit.

  • We can maybe take a look at that in a future stream.

  • Oh, yes, and a good point, says Andre, about get axis for the sort of touch

  • and go behavior.

  • You can set it so where get axis--

  • basically, get axis gives you a value between 0 and 1,

  • which allows you to scale--

  • or I guess negative 1 and 1, I believe--

  • which allows you to scale the value such that if you're using a control

  • stick, for example, which we're not here--

  • and that's another reason why we're not doing it because I'm just

  • using a keyboard as input.

  • But you can actually scale, then depending

  • on how much they're pressing on the control stick, you can--

  • or the mouse-- you can make the movement more or less.

  • Because you're just going to do a multiplication of that

  • get axis result on top of the--

  • you're going to multiply your get axis value against the speed at which you

  • want to move, where ours was negative 3 and 3 on the x-axis.

  • But yes, excellent point, Andre.

  • If we were doing something for a console game or for a--

  • like, a shooter, for example, or some other input source,

  • I would say get axis is definitely the way to go.

  • We're just doing the keyboard for today.

  • WhipStreak says, "I was late.

  • Sorry.

  • But I'm here now."

  • WhipStreak, did you say your name was Nate?

  • I think you said that last time you were here, right?

  • I apologize if I'm getting that mixed up with somebody else.

  • Trying to remember the folks that come here regularly.

  • But thanks for joining in.

  • Glad to see you.

  • [? Asley ?] says, "when you put in left or right,

  • you didn't specify the arrow keys.

  • So how did it know how to use them?"

  • I got the a and d--

  • So if we're in our paddle one--

  • so notice that here I said left and right here where I wrote them--

  • I wrote literally left and right, which map to strings.

  • So remember that instead of having everything hardcoded here-- because

  • previously I just basically said the literal string left,

  • which means that no matter which paddle has this component, left will move it.

  • I wanted to make it more flexible.

  • So I declared these public strings up at the very top here,

  • left and right, which because we declared them as public,

  • they get exposed in Unity in our component here.

  • So it's a little bit hard to see because of the chat.

  • I'm going to move the chat up a little bit,

  • just so we can maybe see a little bit easier, just like that.

  • So the left and right, in this case, I wrote them in myself

  • as the values of those variables instead of hard coding them.

  • I was able to do that differently on paddle 2 because instead

  • of saying left and right, I wrote A and D.

  • So I just basically did the same thing I did

  • with paddle one hardcoded by writing left and right here for paddle one.

  • And then I changed it for paddle two to demonstrate why

  • it's nice to have that in a variable.

  • So now I can have two paddles, but I can make

  • them both move independently because previously, since left and right were

  • hard coded, if I pressed left and right, they would both move

  • in conjunction with one another.

  • But the keyboard presses are, in fact, simulated over time.

  • Yeah, because they're going to be called--

  • get key is going to be called every frame if that's

  • what you're referring to, Andre.

  • Jewish Rambo, can you put in a good word for me to get into Harvard.

  • Unfortunately, I have no say over that.

  • I apologize.

  • If I did, I definitely would.

  • I am but a humble technologist with no hands into the actual hiring--

  • not hiring, but what is it?

  • Blanking on the word.

  • The process by which to get in as a student.

  • "Got it.

  • Thank you," says Astley.

  • Absolutely.

  • So now we have movement of our paddles.

  • And the AI will sort of be a different version of this, but kind of similar.

  • Admissions-- that's the one.

  • Sorry, yeah.

  • I wish I could.

  • I unfortunately-- literally zero involvement

  • in the admissions process and zero influence.

  • I wish I could.

  • But we've made our input work.

  • So now the next step is what I was doing was

  • I was sort of creating these boundaries for our game, for our for our walls.

  • So I want to create the left and the right walls of our pong game

  • because if you play the game, in pong, when the ball bounces

  • off of the walls that aren't where the paddles are-- so normally

  • it's oriented such that the paddels are on the left and right

  • and the walls are the top and the bottom.

  • So if it hits those walls, and actually, that's how it looks like in the screen

  • there.

  • If it hits the left the top and the bottom--

  • or the left and the right, depending on how you're looking at it,

  • where the paddles aren't--

  • then it should just bounce and go back into the game space.

  • But if it were to go past either of the paddles like a goal,

  • then it should trigger adding one to the other person's score, right?

  • So I'm going to make the walls right now.

  • So what I'm going to do is I'm going to go into R to scale my cube.

  • I'm going to scale it all the way such that it's taking up the entire wall

  • there.

  • Good enough.

  • And then I'm going to call this wall wall left.

  • I'm going to then go over to the mesh renderer component.

  • I'm going to disable the chat so you can see.

  • But the mesh renderer component is over here on the right side.

  • If I click on this checkbox right here, it'll actually disable that component.

  • And so this is a nice way if you want certain components to turn on or off,

  • given certain programmatic behavior, you can do that here manually,

  • or you can do it via code.

  • So you can say dot enabled equals true or false,

  • and that will disable that component.

  • I want the wall to work, but just like in pong,

  • I don't want to actually see the wall.

  • So I'm just going to disable the mesh renderer.

  • It's still there.

  • And it still has this box collider which is very important.

  • That's actually what we're going to need.

  • But it's not being rendered.

  • So I'm going to duplicate that.

  • I'm going to come over here.

  • I'm going to move it over to the right just like that.

  • I'm going to title it wall right.

  • And notice that now I have two walls that

  • are the right sizes of our game space.

  • They're invisible, so we won't see them.

  • But when we actually do some more work on our game,

  • we can have the ball bounce off of those walls as we need to.

  • And we do that because it has this thing called a box collider.

  • So we're effectively only using the cube for its box collider, essentially.

  • I'm going to save my scene.

  • Make sure you save your scene.

  • So by default, you remember that I do have a scene here.

  • And it gives you a sample scene as your default scene.

  • And a scene is just a collection of game objects,

  • just like this, put together in your object hierarchy

  • with all of their components set in a particular way.

  • And this allows you to preset, for example, a game view or a menu view

  • or something else and to be able to change amongst them super easily

  • or to have various levels that you may have preset--

  • level one, level two, level three, Waterworld, Fireworld,

  • whatever you want.

  • So you can just simply arrange all of them as scenes

  • and then just load them in and out as you need to.

  • We're not going to do any scene changing today,

  • although we can certainly look into it in the future for something

  • more complicated.

  • We're going to be able to do all that we want to do in just one scene here.

  • So I'm going to do one more thing.

  • I'm going to create another 3D object.

  • Actually, I can just do it with these.

  • So I'm going to duplicate the wall left.

  • I'm going to move it over here.

  • I'm going to rotate it along the y, just like that.

  • Make sure that it is set to negative 90, just like that.

  • I'm going to then move it over here just past the edge of the screen, just

  • like that.

  • I'm going to call this player two goal.

  • I'm going to duplicate that, call that player one goal, move that over here,

  • make sure that I'm in the right spot.

  • Looks like it's perfect.

  • And then now we have our goals set up such

  • that we have our left and our right walls and then we have our goals.

  • If it collides with the left and the right walls, the ball should bounce.

  • And we should also-- our paddle should also not

  • be able to move past it, which we can set.

  • And when it hits one of the goals, the goals

  • aren't actually going to behave like colliders.

  • They're going to behave like what are called triggers.

  • So if I were to go to my player one goal and player two goal,

  • notice they have both of them selected.

  • I hit Command click.

  • You can do this with Control click.

  • And I click on this is trigger thing down here in the box collider.

  • Now those goals are going to function as what are called triggers.

  • And we'll take a look at what that means in a little bit.

  • Effectively what it means is we can say when something collides with this,

  • do something, as opposed to let it behave like a wall

  • where it will just interact with things physically.

  • A trigger is something that can be very flexible.

  • It can be a zone where maybe you trigger the next level loading.

  • Or it could be this goal area where when the ball hits it,

  • it triggers the ball going back to the center of the screen and one person's

  • score incrementing.

  • A trigger is very flexible, and not the same thing, necessarily, as a collider

  • functioning in the context of physics.

  • Andre says, "what I meant was get axis simulates a key press so

  • that on holding down the key right arrow,

  • the values go from 0 to 1 over the course of something

  • like 1/10 of a second rather than the instantaneous value of one of get key."

  • Is that the case?

  • So if you hold down--

  • oh, I see.

  • Such that it will have a sort of like smooth behavior,

  • if that's that you're talking about?

  • That's cool, actually.

  • That could be handy if we wanted to do a more fluid movement of the paddle.

  • We could maybe take a look at that in a little bit, mess

  • around with a little bit, because that would

  • be a-- that's a nice little touch.

  • Pong itself doesn't-- their actual vanilla pong doesn't have, I think,

  • this notion of smooth scrolling.

  • I think it's very discrete in that it just moved when you

  • rotated the paddle or manipulated the--

  • when you pressed whatever-- whatever interface--

  • because there are a million different versions of Pong

  • for constants and stuff.

  • I don't think it was smooth scrolling by default.

  • But that would be a nice touch to have for a 3D version.

  • Astley says, "Unity makes everything so much easier, as far as I can see,

  • that it kind of feels like cheating."

  • Yeah, I think that's sort of the goal, right?

  • You don't want making a game to be to be a process that works against you.

  • You kind of want to eliminate as much friction as possible.

  • So having a very nice interface, being able to see things live update,

  • having a bunch of built-in components that have

  • all this awesome functionality is very nice.

  • I'm a big fan.

  • And I'm not a Unity expert.

  • I know my way around it to a certain degree.

  • But it's a very fun and rewarding process.

  • So I'm looking forward to some more streams of it in the future.

  • JPGuy says, "Colton and the chat, what's up?"

  • Good to see you, JP.

  • We're just doing some Unity programming here.

  • We've set up our scene.

  • We've done a little bit of coding, as you can see, and some C#.

  • We have the paddles moving.

  • So if I were to move the paddles left and right here,

  • so I have my bottom paddle.

  • So notice that bottom is the game view and up top is the scene view.

  • And the nice thing about the scene view is the game is running right now.

  • But I can actually move my scene over here if I wanted to and still play.

  • In that case, I got--

  • the focus was still on the scene view, so it was still moving around.

  • But the paddle I can still see is moving in the scene view.

  • And I have free God mode view of the scene camera, which is super nice.

  • And often you'll see this referenced in games and engines

  • as a debug camera, which will allow you to actually, in real time,

  • navigate the scene with complete flexibility, which

  • is great for debugging things that you would normally not

  • be able to see super easily with a first person controller or a third person

  • controller.

  • We showed this, actually, in my games course when we did--

  • what was it?

  • A 3D maze where we wanted to generate the 3D maze

  • and actually see that it was generating correctly.

  • But the character was a first person character.

  • And if you're using the first person character in your game

  • and testing it that way, you're not going

  • to know that the maze was generated a specific way because you kind of need

  • to see what the maze looks like from super up top, right?

  • So that's what the scene view lets us do very flexibly.

  • JP says, "oh, awesome.

  • I didn't know Unity did that."

  • Well, yeah, definitely.

  • Tune in for the rest of this.

  • This is going to be a fun ride.

  • So I'm going to stop rendering the game engine, or the game view, rather,

  • and think about how I want to get the ball moving.

  • So the ball, if I click on it, ball is currently called sphere.

  • I'm going to rename it to ball just so that it's more semantically meaningful.

  • The ball comes with a sphere collider, which is super nice.

  • The different objects come with all sort of different colliders.

  • And the collider is shaped differently and calculates physics

  • and calculates collisions a little bit differently.

  • The thing that we need to start doing to actually allow our objects to interact

  • physically is introduce rigid bodies.

  • So I'm going to add a new component to the sphere called a rigid body.

  • And what a rigid body is is something that

  • tells the physics engine to perform frame-by-frame calculations

  • of the rigid body.

  • And you can see that it gives you options to select things

  • like mass and drag, angular drag, all different sorts of things,

  • whether affects effects it or not.

  • Which, gravity should not affect our ball,

  • so I'm going to click the checkbox off on that.

  • And gravity by default in Unity is along the y-axis.

  • So it's up in our game world.

  • So like it is in real life.

  • But you can change that, if you want to, in your Unity project settings.

  • If you want gravity to apply on the z or the x-axis,

  • you're more than welcome to do so.

  • It's fairly non-standard, but it works.

  • Right now I'm also going to add a rigid body to my paddle.

  • So a rigid body also not affected by gravity.

  • Want to check that off.

  • And I'm going to add another rigid body to my other paddle.

  • So now our three main objects that are interacting with each other

  • have these rigid bodies, which the physics engine

  • will be able to look at frame by frame and do calculations on,

  • which is super handy.

  • So again, click off the checkbox on the use gravity.

  • JP [INAUDIBLE] says, "will you extend this

  • to have a true 3D pong in all three directions limited

  • within a box sort of boundary?"

  • That'd be cool.

  • Maybe.

  • We could make it maybe mess around with it in the future.

  • I don't know about today, because I think

  • we're going to take up the full stream just implementing the basic 2D version.

  • But I could see that being viable.

  • In this case, if we--

  • cause gravity would be disabled.

  • We could make a top boundary and a-- but we're

  • going to do some constraints on different axes.

  • So if we disabled certain constraints and then enabled extra button presses,

  • we could certainly do that--

  • up, left, down, and right and WASD could then move the different paddles.

  • It wouldn't be terribly complex, but I don't

  • think we'll have time today to fully dig into that.

  • But maybe in the future just to mess around.

  • Voice keeps cracking.

  • Get some water.

  • That's an awesome idea, though.

  • I'd be happy to explore it.

  • The JPGuy says, "the 2D version looks complicated enough

  • to casually create in a stream."

  • Yeah.

  • I mean, it's not terribly complicated, but I

  • want to explain as much as I can so that people following along,

  • if they've never, ever used Unity, actually can understand everything

  • that I'm doing.

  • And so that's going to take up a little bit more of the time, I think.

  • Because if we were building this with people

  • that knew all this stuff already, we could probably

  • whip this up pretty fast.

  • But this assumes, like, day 0 Unity exposure.

  • And I think that's important.

  • I think that we should definitely take our time.

  • ForSunlight says, "like me."

  • Yes, awesome.

  • Hopefully everything has been clear so far.

  • Definitely toss questions in the chat if there's anything that's not clear

  • and I'm more than happy to elaborate on it.

  • All right.

  • So where were we?

  • "Thank you for day 0," says ForSunlight.

  • You're welcome.

  • Absolutely.

  • And you'll forgive me for having the chat disabled on the screen right

  • now just because the Unity editor is pretty busy

  • and needs a lot of screen real estate to be

  • able to see everything that's going on.

  • When we get back to coding, we can turn it back on.

  • 42Force says, "yes, me too."

  • Yes, awesome.

  • I'm glad there's so many folks here joining in that have never used Unity.

  • And I hope that today's examples will prove interesting and/or

  • inspiring enough to keep going.

  • Twitch Hello World says, "for something as simple

  • as the left and right movement of the paddle, is there something in the GUI

  • that does it, out of curiosity?"

  • No, not in the sense of us being able to move them on key press,

  • to the best of my knowledge.

  • I think even with state-- with using the Unity animator state machines I

  • don't think that that's super--

  • I mean, it's not obvious to me that that's something that we get for free.

  • I'd have to dig into it a little bit to see.

  • But I don't think that's something you'd want to necessarily implement,

  • even if that were the case, because I think at that point

  • you're getting into sort of somewhat unorthodox use cases

  • for using for using Unity.

  • Generally, when you look at examples in the Unity documentation-- which,

  • by the way, now is an excellent time to plug that.

  • So Unity manual.

  • So if you just type in Unity manual in Chrome or whatever browser,

  • it'll come up to this user manual.

  • And there's a ton of topics where it goes into all this stuff--

  • working in Unity, navigation, graphics, physics, all this sort of stuff

  • go into a lot of different detail.

  • Scripting, multiplayer networking.

  • There's a ton of stuff.

  • And I believe if we looked up Unity input, for example,

  • Unity scripting API input, you'll get a lot of very detailed information

  • on how it works.

  • And you can see here's an example of somebody using a basic class to get

  • whether they've pressed fire one.

  • And get button down is, I believe it's just a single press rather

  • than a continuous press.

  • So this says fire one, which in this case is,

  • I believe, the same thing as get axis, where

  • you have a prior named variable in your settings,

  • your project settings, which then says fire

  • one maps to x on the Xbox or space on the PC,

  • whatever, a little bit more flexible.

  • Then it just gives you some input there through some debug information.

  • And debug.log, that's another cool thing to look that.

  • That allows you to, in real time, display errors or any information

  • to the console, which if you type control or Command shift C,

  • you get access to this console here where you can do some live debugging

  • and display variables, just like you would

  • do a print statement, for example, in C, printf statement in C,

  • or print statement in Lua.

  • Same idea.

  • "Have you developed in the Unreal Engine before?" says JP Guy.

  • "If so, which do you prefer between Unity and Unreal?"

  • I've looked at Unreal a little bit.

  • So Unreal is a bit more--

  • it's a bit harder to get into in the proper programming sense

  • because it's C++ and it's got a lot of sort of arcane stuff, a lot of--

  • it's pretty complex, a lot of static classes

  • and variables and things of that nature, that are--

  • it's an eyeful, I guess, an eyesore when you first get into it.

  • The great thing about Unreal, though, is that it

  • allows you to use visual scripting with what are called blueprints,

  • so just as a quick little aside here.

  • You can actually code visually using these things here,

  • which are sort of node-based.

  • It's like a node-based programming language, kind of similar to Scratch,

  • I guess, if you're familiar with CS50.

  • And we teach scratch for the first week or two.

  • It allows you to, instead of coding, you can chain building blocks together.

  • And that'll sort of act as your programming language,

  • which is a lot easier than the C++ aspect of it.

  • JP The Guy says, "ew, that looks awful."

  • It's actually not bad.

  • If you compare it to the C++, you can get a sample of some of the use Unreal

  • C++ what it looks like.

  • And not all of it's terrible.

  • But there's a good number of it, a good amount of it,

  • that can be a bit overwhelming.

  • So this is a little bit hard to see.

  • Can I see that super easily?

  • In this case, it's not terribly bad.

  • But there's a lot of things that unreal does very specific to itself, which--

  • like this U class thing which goes above a class definition.

  • And it can get pretty hairy if you're not super familiar with it.

  • I much prefer the blueprints, the Unreal blueprints.

  • But if you know this the code base-- the thing about Unreal is its performance

  • is really, really good.

  • Like, it's got great cutting edge graphics compared to--

  • Unity's got good graphics, too.

  • But the nice thing about Unity is it actually will run well on a Mac.

  • Like, I'm giving you a tutorial on a Mac.

  • And giving a tutorial with Unreal on a Mac

  • would be, like, almost impossible, because it almost doesn't run on a Mac.

  • And it looks terrible even when it does.

  • So that's another thing.

  • Unity is such a nice, like, performant game

  • engine for getting into game development and even publishing game development,

  • whereas Unreal is kind of like, if you want the best of the best graphics

  • and you're into hardcore shader programming and all that stuff,

  • there's a lot of cool stuff you can do in it.

  • But Unity is much easier to get into.

  • And Unity itself has a really cool visual scripting

  • language if you're interested in that.

  • It's called Bolt. And it looks like this, so a little bit cuter looking.

  • It's in the asset store.

  • It's not free.

  • It's 70 dollars, which is the unfortunate part.

  • But it looks like this.

  • And it looks kind of nice, right?

  • Like, you can kind of see we have a game object with a function called

  • get name, which is going into whether the string contains

  • some value, whether it contains enemy, in this case.

  • And then if it does, we have a branch, which

  • is the same thing as an if statement.

  • And then if it's true, we're going to go to Add a Force of some value--

  • push force, it looks like, normalized-- which

  • I'm not entirely sure what that is off the top of my head.

  • But you can lay out your whole logic in this very nice, clean building blocks

  • manner.

  • And this I have a feeling that one day they're

  • going to make this a built-in feature of Unity.

  • They've done this with a lot of really good libraries and good tools

  • that Unity's come with.

  • But I don't know.

  • And this is for people that aren't familiar with programming

  • and want to do something more visual.

  • You have that option.

  • And this is sort of how programming in Unreal Engine is.

  • So you can sort of compare the two kind of on that basis.

  • But yeah, Unreal Engine is really cool in its own ways.

  • Unity is cool in its own ways.

  • I think you should try them both out and see which one you like better.

  • But certainly if you want to try Unreal, make

  • sure you do it on a decently-performing machine, probably a PC,

  • unless you're using a Mac Pro or something with a really good graphics

  • card.

  • Otherwise you won't be able to read it super well, unfortunately.

  • At least in my experience that has been the case.

  • And that was a long aside.

  • I apologize for that.

  • [INAUDIBLE] says, "you always need to code up something anyway

  • because Unity can't guess exactly how you would want to move your objects."

  • Correct, yeah.

  • Yeah, it's hard to sort of put that general of a--

  • hard to make something that general work for every use case.

  • Right.

  • Yes, [INAUDIBLE].

  • I figured if there were, it would give up some granularity, though.

  • I was just curious if there was a simple default to use in the GUI.

  • To the best of my knowledge, there is not.

  • Again, I'm not an expert, so there might be some way to do it

  • in an odd sort of unorthodox use case.

  • I want to say probably not, but I'm sure there's

  • a lot of things about this engine that I don't know.

  • Rema says, "it looks like the Neverwinter Night's Quest editor."

  • I'm not terribly sure.

  • Quest Editor.

  • Yeah, maybe there's a part of the-- oh, like this, maybe?

  • This thing?

  • Kind of?

  • I'm not terribly familiar, unfortunately,

  • with the Never Winternight's Quest editor,

  • but I think I see where you're coming from.

  • Andre says, "incidentally, in Unity as of 2017,

  • print is an alias for debug.log."

  • Oh, that's cool.

  • I didn't know that.

  • TIL.

  • Thanks for that bit of information.

  • OK, so we got sidetracked a little bit.

  • I apologize.

  • It's my fault. Let's take a look at--

  • it's so old you don't have to look it up.

  • Now, I've played Neverwinter Nights, but I never ever actually tried

  • to make my own content with it.

  • So it's cool that they gave you the I've heard

  • good things about how robust the tooling is on it, but anyway.

  • The ball.

  • We wanted to move the ball some direction.

  • As a default it will be random, probably.

  • And then we'll want it to bounce off of the walls

  • and then ultimately off of the paddles.

  • So if I run it, let's see if anything happens.

  • I don't think anything will happen.

  • I can move the paddles just like I was doing before.

  • Gravity is not affecting them.

  • But they do have rigid bodies on them now.

  • So they should be able to process collisions.

  • So if I were to go to the ball--

  • I'm going to go to scripts and I want to actually create a new C# script called

  • ball.

  • Let's open that up in my editor.

  • And it'll be here available-- if you're using VSCode,

  • it should pop up in the left-hand side where

  • your project view is, your scripts are.

  • I'm going to keep that disabled.

  • The ball is-- basically what we want to do is we want to say,

  • OK, when the ball starts, I want to shoot it off in some random direction.

  • And if we look at our game, we see that we probably

  • want to send it in a random 2D direction where x and z are randomized

  • and y does not get any kind of randomization, right?

  • So first off I'm just going to test this now.

  • I'm going to say on start I want to--

  • and what is it?

  • Oh, we need the rigid body.

  • We need a reference to the rigid body.

  • So this is another thing, too.

  • I want-- basically, I want to say if I'm a ball,

  • I want to make sure that I also have a rigid body, because there's not ever

  • going to be a case where my ball doesn't have a rigid body,

  • my paddles don't have rigid bodies.

  • So you can do this thing called require component.

  • And this is called an attribute.

  • This is a C# feature which gives it some metadata,

  • which with fancy runtime analysis of the object it will be able to determine,

  • OK, this class requires that not only is it going to have a ball component,

  • but I also need to have a rigid body component associated with this game

  • object.

  • So the ball essentially requires and it will--

  • it will, if you don't provide it, it will load in a rigid body.

  • So I can then say, rigid body rb, which is just a--

  • it wants to auto populate my--

  • dammit.

  • Wants to auto populate my variable declaration there,

  • which I guess maybe the more robust would be the better way to do it.

  • But I want to say--

  • I want to get a reference to my rigid body.

  • I'm going to turn the chat on, too, just in case anybody has messages,

  • since we're in the text editor view here.

  • I want to get a reference to my rigid body.

  • So it won't know what the rigid body is until the object is instantiated

  • and can actually grab that rigid body.

  • So I'm going to say rb equals get component rigid body.

  • And the angle brackets syntax here might be a little weird

  • if you haven't seen it before because the angle bracket is basically what's

  • called a-- it's a generic specifier.

  • And what it will allow you to do is you can call this get component function

  • on any data type that you want.

  • And if I were to specify some other type of mono behavior here,

  • it would give me that component, not the rigid body.

  • You can specify whatever component type, the class type,

  • you want within these angle brackets.

  • And then it takes-- it's a function, so after

  • that it still needs to call the function with these parentheses.

  • And one other thing I forgot to mention, typeof is just a way in C# for you

  • to get the actual type data for a given class name.

  • So in that case, I want the type data for what a rigid body is.

  • So if I say rb is get component rigid body,

  • it's going to look at the current game object.

  • And it's going to call get component off of whatever this object is

  • of the type rigid body.

  • And it's going to grab that and store that in my rigid body rb variable here.

  • And notice I did not declare it public.

  • I don't want it to be public.

  • This is going to be a private variable that no other script should

  • be able to get a reference to because I don't want other scripts to mess

  • with it at all.

  • This is just going to be a rigid body that I tweak within my code.

  • And the exact function call--

  • I'm not 100% sure, but thankfully I have [? IntelliSense. ?]

  • So if I were to hit rb dot, notice that it

  • populates all of my potential functions that I could call.

  • So I believe it is--

  • which one is it?

  • I want to basically shoot it in a given direction.

  • I want to apply an impulse to it.

  • I can cheat.

  • I want to see if it has the--

  • OK, it's here.

  • It's add force.

  • So if you add a force to something, it will just

  • apply some energy towards that object.

  • And it can be gradual or it can be an impulse.

  • An impulse is what we want because we want

  • to shoot in a direction at a specific time or at a specific constant speed.

  • So it takes a-- it takes the actual direction,

  • because we want it to be in a given direction, as a vector.

  • And remember that we wanted that direction to be along the x and the z

  • and not along the y because if we have some value shooting in the y direction,

  • it's going to go up or down.

  • And we want it to stay aligned perfectly within this two-dimensional plane

  • in our 3D world.

  • If we were implementing a 3D version of pong

  • in the true sense where the ball is able to go up, down

  • as well as left and right, in this case we

  • would maybe want to set an impulse along the y-axis.

  • But we're not going to do that.

  • Instead, I'm going to say 404.

  • I'm going to hardcode it.

  • And then I'm going to specify a force mode.

  • So there's different force modes.

  • So force mode dot, for example, acceleration,

  • which means that it will accelerate the object.

  • It will start off slow and move faster.

  • But I want it to have that value instantly.

  • I want it to instantly start moving at 4 units in the x direction and 4 units

  • in the z direction, which should have the result of it moving up

  • and to the right when we run our game.

  • So I'm going to--

  • actually, this is not going to go in the update function

  • because that will just consistently add a value to it every frame.

  • And it'll start going really fast.

  • I want that to just be in the start function right where it begins.

  • I don't want it to happen every frame because it would just

  • add this over and over again.

  • This would become 8, 8 on the 2nd frame, 12, 12 on the 3rd frame,

  • 16, 16, and so we're moving really, really fast.

  • "Like a Java list integer, a list," says [INAUDIBLE]..

  • Yep, same exact thing.

  • Generics just like in Java.

  • JP Guy says, "IntelliSense is life."

  • Yes, it's hard not to--

  • it's hard to go back once you've gotten used to it in VSCode.

  • It's a really nice feature, something that you just get and it just works.

  • And it's super nice.

  • OK, so we've got our component, our rigid body.

  • We've got a reference to it and we've added an impulse force to it at 4, 4.

  • And we can randomize that later, which we will do.

  • We can make it random on the negative and random on the positive direction

  • and we can make sure that it's not too small of an amount on either axis.

  • Otherwise, it'll just be going back and forth in a sort of straight line.

  • Or it just won't go at all.

  • So we can do that later.

  • But right now, we're just going to test it with some hardcoded values.

  • I'm going to save that.

  • I'm going to go back to Unity.

  • And then I'm going to run this.

  • And I'm going to make sure that my ball has

  • the ball component, which it does not.

  • So I'm going to make sure--

  • make sure when you create a component and you finish fleshing it out

  • and you want to test it that you've actually put it onto an object

  • because if you don't put it on an object,

  • there is going to be no objects calling these start and update

  • functions every frame, right?

  • So I'm going to do that.

  • I'm going to hit play.

  • And then what happens?

  • The ball, just as we wished, has moved out.

  • You can see its transform is sort of freaking out

  • and it's rotating all over the place.

  • But it did.

  • It indeed moved in the correct direction.

  • And not only that, but because we specified

  • these-- we created these walls left and right

  • and they have these things called box colliders on them, the box colliders

  • will actually affect rigid bodies just by default. So the ball

  • was able to move into a rigid body or into a box collide.

  • The rigid body-- sorry, the ball, which had a rigid body on it,

  • was able to move into the wall which had a box collider on it.

  • The box collider wasn't a rigid body because we

  • don't want those to move around and be affected by physics transformations.

  • But the ball, because it interacted with the box collider, it bounced.

  • Now, it didn't bounce correctly.

  • If you notice, it actually bounced in a really weird direction.

  • It kind of went in a straight line, which is not what we're looking for.

  • So notice that instead of bouncing out and then kind of bouncing

  • back out in kind of like the opposite vector, in the opposite direction,

  • it just kind of went into a flat line, very much defined the laws of physics.

  • So we have to fix that.

  • And we can do that using what's called a physics material to give

  • our object some proper bounciness.

  • 42Force says, "wow, [INAUDIBLE]."

  • Astley says "plus."

  • Yes.

  • Very, very exciting.

  • OK.

  • And also, it should interact with our paddles because we are--

  • because those have box colliders on them, as well.

  • JP Guy says, "checkmate, Newton."

  • Yes, exactly.

  • We're diving deep into the world of physics here.

  • And I am not a physics expert.

  • I just happen to know what the right things to manipulate

  • are to get the, in this case, the physics working.

  • So everything in your game that can interact

  • using rigid bodies with other things, other rigid bodies or other colliders,

  • will behave according to certain properties of that object,

  • certain physical properties.

  • Now, this is most pertinent in terms of today--

  • bounciness.

  • Bounciness is the factor that we want to manipulate because it didn't bounce off

  • of the wall.

  • And in fact, it hit the wall and then it just

  • proceeded to move in a straight line along the z-axis for some odd reason

  • because it doesn't have a bounce factor to it.

  • "The laws are to be broken," says The Rb Ball 2018.

  • Yeah, exactly.

  • Newton's third law of motion just didn't work there.

  • Yeah, no, it didn't, because there is not

  • enough bounciness between our ball and the walls.

  • So the ball needs--

  • it needs to be, like, completely bouncy, basically.

  • And we can do that by creating a physics material

  • and basically changing how our object works,

  • basically turning it from a metal ball to a rubber ball, kind of.

  • You can think of it that way.

  • So in my materials folder, I'm going to create

  • a physics material, which is down here, below where you see timeline.

  • I'm going to disable chat, just so we can see what's going on.

  • And it has this different little icon here where it shows a--

  • aptly shows a ball bouncing off of some surface.

  • Now, I'm going to call that bouncy mat.

  • I'm going to go over to the right where I have my inspector.

  • And I have a few different parameters I can tweak here.

  • I have dynamic friction.

  • I want that to be zero, static friction, want that to be zero--

  • basically how it loses momentum when it rubs up against stuff--

  • and then bounciness, how much it basically takes

  • its current angle of movement and reverses it

  • when it interacts with something else.

  • I'm going to set that to 1.

  • So these exist on a spectrum between 0 and 1 for all of those.

  • For the friction combine, I'm going to set that

  • to the minimum, which means it's basically

  • going to not calculate friction.

  • And for the bounce combine, I'm going to set that to maximum.

  • And the low level details of how this works I can't explain.

  • It's super tremendous detail.

  • I'm sure with enough deep diving into the physics system of Unity,

  • we could maybe explore and look at it.

  • But essentially, you can think of the friction

  • combine to be how is it averaged out, the friction between two objects

  • and how the force is changed between the object that's moving,

  • the object that has the material, and the bounce combine.

  • Basically, how does it average the bounciness of both objects,

  • and then calculate the bounce that should result.

  • In this case, we want it to be the maximum of 0 and 1.

  • In this case, because our object has 1, it'll

  • always be 1, effectively, which will always be full bounce.

  • Going to be a slippery material plus the wall.

  • Yeah, exactly.

  • But it's not going to slide against the wall because we are using it as a--

  • excuse me, as a just bouncing platform.

  • Now, another area that you would want to potentially use

  • a physics material for that kind of purpose

  • would be a ice world, for example, if you've

  • played games like Banjo-Kazooie or million different games I've done this.

  • And you're walking on ice, for example, you'll

  • slide around because the ice has a different physical material-- physics

  • material-- than, say, grass, in such that the ice has

  • no friction, or at least much less friction,

  • than the grass, which maybe has half or full friction.

  • So you can get a bunch of different kinds of use cases

  • out of manipulating your physics materials as a result of that.

  • Now, the bouncy material, I just want that to be applied to the ball.

  • So I'm going to click that, drag it over to the ball.

  • The ball now has a bouncy material reference

  • in its actual sphere collider.

  • So the collider actually maintains a reference to the physics material.

  • So it's right here.

  • And so now one other thing that we need to do

  • is if we want this to work off of the paddles

  • because the paddles are themselves rigid bodies and you when it calculates

  • bounce operations off of rigid bodies it takes their mass into consideration.

  • And if you set the mass to just be one on the paddles,

  • it actually won't bounce back off of the paddle.

  • It will flatten and start moving along the x-axis, which is not ideal at all.

  • That's completely nonsensical sort of physics behavior, in this case.

  • So what I'm going to do is in mass with both of the paddles selected

  • I'm just going to set them to 1,000.

  • And note that this doesn't actually influence

  • how we move the paddle because we're just translating it on its transform.

  • We're not applying an impulse to it.

  • If we were applying impulses to our paddles,

  • then the impulse would have zero effect on an object of 1,000 mass.

  • I'm not entirely sure what the mass unit is in Unity.

  • If anybody knows, definitely toss in the chat.

  • But suffice to say, 1,000 is 1,000 times more than one.

  • So it'll likely have 1,000 times less effective of an effect

  • if we were to use a--

  • use add force on a rigid body associated with an element of 1,000 mass units.

  • So not something that we should have to worry about with our walls

  • because they don't have rigid bodies associated with them.

  • But we should have to worry about that with our paddles.

  • Now, let's actually see if this is working.

  • Weren't able to move fast enough to get there in time.

  • So I'm going to actually bump the speed on the paddles up a little bit.

  • So we didn't make that a variable.

  • So what I'm going to do is I'm going to go back to my paddle class

  • and I'm going to say public float speed.

  • And I'm going to say--

  • I'm going to set that by default to 3.

  • You can initialize that here where your variables are, if you want to.

  • But it's going to, by default, be three.

  • And if I go back to my paddles now, because I made it a public float,

  • every paddle now has a speed parameter that I can adjust.

  • So if I click on--

  • if I go to speed and I click 5 and I go to the other paddle and I hit 5,

  • now I should be able to move fast enough to at least catch the ball.

  • Still not quite fast enough.

  • Oh, you know what it is?

  • Because I'm still referencing this value with the 3.

  • So what I need to do is say negative speed

  • and then speed here, not the negative 3 and 3 that we hardcoded before.

  • And now if I run the game and let it compile its scripts and I play,

  • we do, indeed, move faster.

  • And it does bounce the ball appropriately.

  • Except now, notice that we are getting some weird behavior with our paddles.

  • So that's completely to be expected.

  • It makes for a very alternative version of pong.

  • I don't think it'd be very easy to play.

  • But there are a couple of things that we did not take into consideration

  • before we started testing.

  • But we can see that at least the bounciness is working appropriately.

  • [? Bavik Night says ?] "1,000, is it in grams?"

  • I believe the idea is mass in kilograms, seeing

  • as gravitational acceleration by default is 9.81 units per second.

  • Yes, I believe that--

  • I believe that is correct, yeah.

  • Now that I'm thinking about it, that makes perfect sense.

  • And every square is one meter.

  • So mass would be in kilograms and force is in Newton's in a relative way.

  • So 1,000 would require a great deal of force.

  • Yes, yes, absolutely.

  • Now, our physics system freaked out a little bit, though, as you saw.

  • But that's completely to be expected because we are not

  • constraining the collisions that take place between our ball and the paddle.

  • Or we're not constraining, basically, them the axes

  • upon which our paddle can move.

  • So if I were to move this, the reason that it bounced so crazily

  • is because I'm trying to collide it against this left wall

  • and this right wall.

  • And I'm moving this massive 1,000 kilogram object just at will

  • because I programmed it--

  • I programmed to move the transform.

  • But that applies force in my game.

  • It's still applying a physics operation.

  • It takes in the transform, its speed, into consideration, and the rigid body.

  • And so we're colliding with the walls in that case, right?

  • These two walls that are invisible.

  • So what we want to do is constrain where the paddle can move

  • and how it can rotate.

  • We don't want our paddles to ever rotate.

  • And we only want them to move along the x-axis, right?

  • Thankfully, Unity makes this super easy.

  • If I go to paddle one and paddle two and I click on their constraints

  • little field there in the--

  • you should be able to see that.

  • I'm going to move a little bit over.

  • If you see the--

  • there's a constraints drop down on the rigid body, right?

  • And I can click x, y, and z for freeze position and freeze rotation.

  • And this is nice because this will allow us to say,

  • don't ever rotate on a given axis and don't ever

  • move along a given axis, right?

  • And so I probably don't want to freeze position on the x-axis

  • because that means I won't be able to move my paddles.

  • But I can certainly freeze the position on the y-axis and on the z-axis.

  • And I can freeze their rotation on every single axis

  • because they're not going to ever rotate, right?

  • The result of that is if I run the game again

  • and I try to collide, no matter what I do--

  • it looks like it still went through the--

  • did I make the--

  • might not have made that thing big-- oh, no, it's

  • the collision detection, right.

  • Another thing we have to do is make sure that we do interpolated collision

  • detection using continuous dynamic.

  • And I can't tell you the low-level details of how exactly these work.

  • But interpolated collision detection basically

  • allows us to ensure that if a certain number of frames go by or whatever,

  • where maybe we run our game at 30 frames per second or 20 frames per second

  • instead of 60 frames per second, it will calculate the collision

  • detection that it should have done for the intermediate frames.

  • It will interpolate that for us.

  • And continuous dynamic, I'm not entirely 100% sure how it differs in terms of--

  • I haven't looked at the manual.

  • But I do know that that is the more appropriate collision detection

  • for things like we're doing here.

  • And it just-- it's a little bit more fine grained.

  • But beyond that, the low level details, I'd

  • have to do some reading on the physics engine a little bit.

  • "Further reading," says JP Guy, "on the grip slip behavior of a bouncing ball.

  • A bit of overkill for a Unity game but interesting nonetheless."

  • Yeah, I'll take a look at that.

  • I had to consult--

  • what did I consult?

  • I ended up having to consult a couple of videos on this.

  • Unity has their own tutorial on making continuous bouncing ball.

  • But I didn't watch that one.

  • But now we shouldn't be able to move past our boundaries anymore.

  • Or maybe we do.

  • OK.

  • Hold on.

  • Let me figure out why it's doing that.

  • Did I start-- is it too thin?

  • Hold on.

  • I'm not sure why.

  • So I didn't do it when we were at speed 3 before.

  • I'm curious, curious as to why it's doing that.

  • So I'm going to go to--

  • so I didn't test the game at speed 5 when I was messing around

  • with implementing it.

  • I didn't test it at speed 5.

  • So I'm just going to bring the speed back down to 3 to see if that fixes it.

  • Paddle one, paddle two.

  • They're both three.

  • Let's try that again.

  • Let's see if it'll go through though the wall.

  • OK, so it doesn't go through the wall anymore, which is interesting.

  • I wonder if we make the wall a little bit larger if that has any effect.

  • Let me try that.

  • If I go in here and I go to Edit Collider and I scale them along the--

  • oops.

  • I don't want to do that.

  • Let's go over here.

  • Let's scale this just a little bit.

  • It shouldn't have this issue, so I'm not entirely sure.

  • Let's try that again.

  • I want to go back to 5, because I did 5 as a speed.

  • Let me do that.

  • Play.

  • No, it still wants to go through.

  • That's fascinating.

  • It is interpolated.

  • The good news is our paddles aren't flying

  • all over the place, which was part of the problem that we had before.

  • Interpolate is for-- sorry.

  • Let's see.

  • [INAUDIBLE] says, "interpolate is actually

  • for the motion of the rigid body to avoid

  • mismatch between physics update, which is always at 60 frames per second,

  • and graphics updates, which may vary.

  • It's supposed to fix visual glitches like jittering,

  • but doesn't always work too well."

  • Ah, OK, good.

  • Thank you for that.

  • Math08, "are you using floats?"

  • Floats for what, exactly?

  • That's a unit it uses by default. I know interpolation exterpolation

  • only from math four in college.

  • Yeah.

  • My math background is a little bit on the primitive side.

  • Continuous dynamic, did we not have continuous dynamic?

  • Try the third option for the collision--

  • paddle one, paddle two.

  • Yeah, they are on continuous dynamic.

  • So I'm not sure what that is.

  • I'm not sure why it's behaving like that.

  • They're both-- yeah, they're both continuous dynamic.

  • That's very weird.

  • I did not have this problem at all in testing.

  • Wow.

  • Thankfully the ball doesn't move through it, but man, that's bugging me.

  • Sorry.

  • I'm getting a little bit distracted by actually playing the game now,

  • which is a good thing.

  • That means we're making progress.

  • I thought mathematics was still required in Comp Sci, or am I wrong?

  • You're not wrong, necessarily.

  • I think it depends on what you want to do.

  • So one of my goals is to learn linear algebra to a very competent degree

  • because linear algebra is very widely used in 3D game development and 3D game

  • programming.

  • You don't need to necessarily know it for Unity, to use Unity,

  • but it doesn't hurt.

  • And being able to understand a lot of the underlying stuff, I think,

  • gives you an edge, which is why I want to learn it.

  • I'm not super comfortable with it.

  • Things like vectors, for example, are like a basic--

  • and matrices-- are a basic aspect of linear algebra.

  • And 3D graphics is ultimately just manipulating

  • vertices and matrices in certain ways.

  • So it's cool to know it.

  • But learning, like, to do a lot of programming,

  • you don't necessarily need to know beyond algebra and geometry.

  • "Thing is, because the interaction between translate and impulse,"

  • says Math08.

  • So we're not actually applying an impulse with our paddle.

  • So the impulse is with our ball.

  • The ball is the only one getting an impulse.

  • It is an issue with the translate, probably.

  • So I'm going to-- just because I know it works at speed 3--

  • I'm going to set the speed to 3 for now.

  • I should have tested it with higher values in advance

  • to see exactly what the issue is.

  • Continuous dynamic was supposed to fix it.

  • I can try with continuous to maybe see if that works, as well.

  • Does discreet work, maybe?

  • Discrete.

  • Let me try that, see if that works, actually.

  • Let's move-- I didn't change the setting, did I?

  • Whoops.

  • It still moves through the wall.

  • I'll do a quick Google, maybe see if that has a result.

  • Rigid body translate moves through collider.

  • I guess we could do add force.

  • I think that would work, actually, if we just changed it from to--

  • changed it from translate to add force, we could do that.

  • So if I just said paddle requires a component type of rigid body

  • and then I went to--

  • instead of doing a transform.translate, if I did--

  • first we need to get a reference to it.

  • So we're going to need rigid body, rb, equals get--

  • or we can't do an equals yet.

  • But I can say rb equals get component rigid body,

  • just like we did before with the ball.

  • And then I can say, if input get key left, we'll do rb dot add force

  • and then force mode dot impulse, right?

  • So that'll be the same thing.

  • rb dot add force.

  • Force mode dot impulse.

  • Because, yeah, to the point of what the person was saying in the thread there,

  • transform.translate is technically just teleportation.

  • So I could see why it would screw with the physics system a little bit.

  • I guess if you're at a small enough movement speed,

  • it doesn't matter too much.

  • But since we're doing this and we want to adjust the speed,

  • we probably want to take a look at that.

  • So if we go back to paddle one, paddle two, let's

  • set those both to speed 5 again.

  • And let's make sure my code works.

  • So let's see if I can move left or right, which it can't.

  • OK.

  • Interesting.

  • Oh, because the impulse is scaling off of delta time.

  • So we need to make this negative speed and regular speed

  • not scaling it by delta time because now we're going to get the--

  • we're going to get that scaling by delta time

  • because we're applying that impulse, right, or moving it

  • based on units per second or meters per second

  • just because we're using the physics system.

  • There's a lot of comments.

  • Sorry.

  • Let me zoom back up there.

  • W Wood, can you make bump stops that are separate to the walls the ball hits?

  • Can you elaborate on that?

  • Do you mean, like, obstacles in the game world?

  • Udon Master says, "vectors are life and hell too."

  • Yeah, they're definitely useful.

  • I could see--

  • I know they get pretty complicated the more you get deeper

  • into linear algebra.

  • [? Bavik ?] [? Knight, ?] "MIT OCW for the win for math."

  • Yeah, no, they have excellent courses.

  • I was watching a financial economics class at MIT ED which was really good.

  • JP Guy says, "I have a good PDF about linear algebra and game engines.

  • I'll email it to you."

  • Yeah, definitely do.

  • Definitely do.

  • Twitch Hello World lists your info on a good linear algebra class.

  • If you do a twitch session on that, it'd be so terrific, as well as

  • on robotics and arduino, hopefully.

  • Robotics would be really cool, actually.

  • I'll see if I know anybody that knows robotics.

  • Linear algebra would be interesting.

  • I certainly wouldn't be able to give, I think, a great lecture on it.

  • It would probably be me streaming learning it

  • and I don't know if that would be fun for people to watch.

  • So I might just--

  • I might maybe find somebody that knows linear algebra

  • and have them do a session on it.

  • But it'd probably have to be in the context of games

  • to make it still fairly CS applicable.

  • Oh Bavik, you absolute madman, mentioning MIT doing a Harvard stream.

  • Now, we're-- MIT and Harvard are good friends.

  • Come on.

  • [? Bavik ?] [? Knight ?] says, "they both are the best.

  • And CS50 starts from MIT's Scratch interface so it wouldn't hurt much."

  • Exactly, we are best buddies with MIT.

  • We use Scratch.

  • [INAUDIBLE] says, "you can also use move.

  • I think translate will override the collision."

  • The move function.

  • Transform dot-- is it transform.move?

  • Unity transform move?

  • Can you-- you mind specifying which function you mean, [INAUDIBLE]??

  • JP Guy says, "fair point."

  • Andre says, "yeah, rigid body--" oh, rigid body dot move.

  • OK.

  • Rigid body dot move.

  • We could do that.

  • Rigid body dot move.

  • Move position.

  • And so that will--

  • oh, you know what?

  • Yes.

  • Yeah, yeah, yeah, you're right.

  • You're right.

  • Because we're adding an impulse.

  • If we do it every frame, that would be disastrous.

  • We don't want to do that.

  • We want to do rigid body dot move.

  • Good call on that.

  • Good call on that.

  • You guys are much--

  • move position, specifically-- you guys are much more talented at this

  • than I am.

  • Move position a new vector 3.

  • It does not take a second position.

  • Now, does move position actually take--

  • oh, it's a new position.

  • So we have to take its current position, then, and figure that out.

  • Or can it take a--

  • because if we're specifying a position for it to move to,

  • then that's not the same thing as--

  • that's not the same thing as moving it along an axis, right?

  • Yeah, it moves it to a position.

  • So that means we would need a reference to whatever position is in.

  • Oh, sorry.

  • Missing some other-- missing some other comments here.

  • Something like rb dot move position transform.position

  • plus transform.write times speed times time dot delta time.

  • Yeah.

  • Yeah, that could work.

  • Let's do that.

  • So copying what [INAUDIBLE] graciously provided to us in the chat.

  • If we do rb dot move position and then transform.position--

  • whoops.

  • Not driven rec transform transfer.

  • Sometimes Intellisense works against you.

  • transform.position plus-- in this case, we want to move left,

  • so transform.left times speed times time dot delta time.

  • OK.

  • Wait.

  • Why does that-- transform does not contain a definition for left and no

  • accessible--

  • transform dot-- is it vector3.left?

  • Probably that, right?

  • And then go down here.

  • And then this would be vector3.right.

  • People are asking for that linear algebra PDF.

  • OK, so "linear algebra session would be really fun," says Astley.

  • [? Push ?] Hello World says, "yes, that would be awesome.

  • The math [INAUDIBLE] could apply linear algebra to AI and/or games.

  • And if you ask questions, as in the AI session, it is terrific."

  • Got to move the rb, not the element itself, right?

  • It should move the whole game object, correct?

  • The rigid body maintains a reference to the whole object

  • and will move the whole object.

  • Oh, yep.

  • Times negative speed.

  • Yes.

  • Correct.

  • Shout out to [INAUDIBLE] for helping us out in the chat

  • here with the clutch last minute changes to the code base.

  • Very talented Unity engineer.

  • Let's see if that works.

  • I'm not 100% sure if it will, but we'll find out.

  • OK, so hold up.

  • So it moved them, but it didn't detect collision.

  • Transform dot-- oh, this needs to be minus, right?

  • Does it?

  • No, because we're going to add--

  • this would be a negative value, right?

  • So left wasn't working, but right was working.

  • But more importantly, it wasn't actually detecting collision,

  • which is the more concerning part.

  • Yeah, so the math-- my math is not quite working out.

  • Oh, vector three dot--

  • right.

  • It has to be vector3.right always because it's going to be 1.

  • And then-- that makes sense.

  • That should work, right?

  • Fun times live coding on stream.

  • Here we go.

  • Oh, there we go.

  • That works.

  • Cool.

  • So it still passes, through.

  • It's detecting that there is something there,

  • but it will still move it past it, unfortunately.

  • So it's not-- we haven't fixed the problem.

  • Oh, because we're not using interpolation, right?

  • We changed it to discrete, I think.

  • So we go back here to interpolate, to continuous dynamic,

  • and then we try to run it.

  • Fingers crossed.

  • This should work, right?

  • Nope, still doesn't work.

  • That's funny.

  • It still detects that there's something there

  • and it wants to push back against it.

  • But it's still not quite working.

  • OK.

  • I might just revert back to the speed 3, just for the sake of demonstration.

  • And we could figure out another time.

  • "Math primer for graphics and game development by [INAUDIBLE],","

  • says JP Guy.

  • I trust you guys get this book legally, being decent human beings and all.

  • [INAUDIBLE] says, "no there's another anyway.

  • Thanks.

  • JP Guy-- "use vector3.left you don't need to negate the speed."

  • Yes, that's correct.

  • JP Guy, you get it.

  • Try setting [INAUDIBLE] to use dynamic.

  • Maybe add force, but not every update.

  • That would be a little harder, add force,

  • because then how do we determine when we want to--

  • I guess we would say we have to have a flag that basically says start impulse,

  • right?

  • And then if it intersects with the walls,

  • set the impulse to zero or whatever.

  • [INAUDIBLE] says, "put the move position inside

  • of fixed update instead of update.

  • I'm really puzzled, LOL."

  • Yeah, that could be it, actually.

  • Let's try that.

  • Void.

  • So fixed update will run for your physics every--

  • it will basically calculate this every frame rate independently, essentially,

  • which allows you to get around a lot of weird physics bugs.

  • So let's try that.

  • Ooh, that looks good.

  • All right. it was fixed update.

  • So good.

  • Good job.

  • Shoutouts to [INAUDIBLE] for that, for the clutch suggestion there.

  • So yeah, update works every frame and will

  • get called every frame that you run, depending on your frame rate.

  • But if your frame rate fluctuates, update is going to run differently.

  • It's going to run in different iterations.

  • And so it's going to--

  • basically, delta time is going to change.

  • It's going to be a larger value, which is sort of why we're

  • clipping into our walls left and right.

  • If you run it fixed update, it will ensure

  • that that gets run at a consistent amount,

  • given the amount of frames that have passed.

  • It will basically-- if you run it a fewer number of frames,

  • it will run it-- it will basically do the catch-up needed

  • to keep you on track.

  • And so that's how you can get around a lot of weird physics bugs.

  • So shoutouts to [INAUDIBLE].

  • Thank you for tossing that in there and helping us debug today.

  • [INAUDIBLE] says, "yes, JP Guy."

  • 42Force, [INAUDIBLE].

  • Awesome.

  • All right.

  • So we have our paddles moving around, which is great.

  • We got that part all set up.

  • Apologies that it took so long to figure out.

  • Now, the ball will bounce appropriately.

  • It will bounce off of the paddles and it will bounce off the walls.

  • But what we need to do--

  • and maybe I should put an annotation or something in there

  • for the YouTube video when we finally release it

  • so people can skip all that debugging, but what we want to do now

  • is basically detect whether or not someone

  • has scored against another person.

  • So we can have text labels on the left and the right side

  • which say just what our score, is right?

  • So we can do that pretty easily, or at least

  • we can mock it up pretty easily if I say go down to the UI, go to text.

  • And then I'm just going to call this player one score.

  • I'm going to create another text in my canvas here and call it player--

  • whoops-- call it player two score.

  • Now, what I did was I went to add a new object.

  • I'm going to disable the chat just for a second.

  • I went to add a new object UI text.

  • And when I did that, I got a canvas element.

  • And so the canvas is basically your UI manager for anything

  • that you use Unity's 2D UI stuff for.

  • It all goes inside of a canvas.

  • And it also added an events system to my scene,

  • which is used for touch events and other things

  • that we won't actually use today for interactive GUIs.

  • Today, all we're really interested in are some text labels.

  • So here I have a--

  • I added two text labels.

  • So one's going go on the left.

  • One is going to go in the right.

  • One is called player one score and one is called player two score.

  • I'm going to expand this a little bit.

  • Unity's UI system is a little bit strange.

  • You'll notice that in the bottom I see the text label

  • itself like it's supposed to be rendered onto the screen in 2D, right?

  • But in the actual scene, I've got some weird funkiness

  • going on where I've got this massive label here in 3D space

  • and I've got this big old rectangle.

  • And this is Unity's way of actually rendering the UI over your game.

  • It'll actually create the gigantic canvas that maps one to one, I believe,

  • with Unity units and allows it to more efficiently render

  • variable-sized GUIs, as opposed to having it sort of be here in 3D space

  • the same size as your game.

  • And what happens is Unity has a separate camera that'll actually

  • render the UI on top of whatever it is that you're

  • rendering with your main camera.

  • So if I double click on the player two score,

  • I can see it really massively in 3D.

  • And our scene is just down there way in the bottom.

  • And if I-- actually, if I grow this, the canvas should grow quite a bit.

  • So the larger your game view is, the larger your canvas.

  • You can see it shrinks accordingly.

  • So in real time, it's resizing the canvas.

  • I want to get a 2D view of what my canvas looks like.

  • So I can go up here to the very top left-- a little bit hard to see,

  • potentially.

  • But there's a button that says 2D.

  • And that allows you to switch between 2D and 3D views.

  • So I do that, I click 2D, now I'm in the 2D view of Unity.

  • And I can look around my canvas, just like I

  • would want to lay it out on the screen, as opposed

  • to it being some sort of weird 3D giant structure, right?

  • So if I move this over here-- whoops, grab the--

  • keep grabbing the light.

  • Notice that there's this fifth button here

  • on the very top left, which is the rect tool, which allows you

  • to actually manipulate GUI elements.

  • So I can move these around however I want to.

  • This is the player one score.

  • So what I want to do is I want to put this at the top left-ish.

  • And I want to put my player two score kind of at the top right-ish.

  • Just like kind of like that.

  • Going to eyeball it.

  • And I want to make them white because it's a little bit

  • hard to see currently.

  • So I'm going to go over here.

  • I'm going to make sure my player one score is selected.

  • On the right hand side, I have a color picker for the color of the text.

  • I'm just going to do that for both of those.

  • I'm going to change the size because the font size is a little bit small.

  • You can see it in the game view down below.

  • That's a preview of what I'll look like when it's rendered.

  • But it's a bit small.

  • I'm going to set the size to 32 and the size of 32.

  • Notice that the text disappeared.

  • That's because the rect is a little bit too small for the text.

  • But if I grow it out, it'll appear again.

  • I'm going to do that again right here.

  • And I'm going to set this to be left-aligned

  • and I'm going to set the right one to be right-aligned.

  • Notice that there's these little buttons here which

  • allow you to choose the formatting options for your text.

  • So it's a very flexible way to arrange your interfaces.

  • No longer do we have to necessarily do, like,

  • printf statements where we specify a padding

  • amount for rendering a given string.

  • We can just do it visually here, which is nice.

  • Now, what I want to do is I want to make sure that this label here on the left

  • is always relative to the left and doesn't have a fixed location.

  • So I can click on this little box here at the top right,

  • and it will give me a dropdown at different anchor points.

  • So I'm going to select this one right here, which is top left anchor point.

  • Notice that I got a little left--

  • a little icon that showed up up there on the very top

  • left, just to demonstrate that.

  • And I'm going to have my player two score selected

  • and I'm going to make that a top right anchor point.

  • Notice that an anchor point showed up there.

  • So no matter how I resize my game, those labels will stay relative.

  • The distance that they are now, they'll stay

  • relative to the top right and top left corners

  • of the game, which is super handy.

  • Should be able to demonstrate that.

  • You can see, as I re-scale my game, the game view, the labels,

  • they stay really close to the top left and top right corners of the game.

  • So super easy, super basic.

  • What I'm going to do is I'm going to set these both to be 0, just like that.

  • Just like that.

  • And so now I have what looks like sort of the basic idea of pong,

  • where I have the scores there.

  • But all it is is just a couple of strings with the literal character

  • zero, so not terribly useful yet.

  • What we want to do is programmatically determine whether we have basically

  • scored against our opponent and then update those scores to reflect that.

  • So what we can do--

  • I'm going to create a new class.

  • I'm going to create a new script.

  • I'm going to go to my assets, scripts.

  • I'm going to create a new one called score.

  • And if I open up score, we'll see that it's just

  • a default component as anything else.

  • I'll enable to chat again.

  • If people want to say some stuff, it'll be visible.

  • This score is going to basically just keep track of the--

  • it's basically just going to be text that gets updated.

  • Now do we actually need to have a separate score?

  • We do end up needing a score at some point.

  • But we keep track of the score in our actual paddles themselves.

  • So notice that I declared score up here.

  • And it should be set to zero by default. So the score

  • is going to be on each paddle.

  • Each paddle will keep a reference to the score.

  • And then it will update the text on each of those different text labels

  • that we just created.

  • So it will update if we end up scoring against an individual person.

  • And so what I want to do, also, is I want

  • to have a goal class, because what we're going to do,

  • in order to check to see whether we have scored against somebody,

  • is we're going to basically determine if our ball collides with a goal, right?

  • So if I go to scripts, create a new C# script called Goal,

  • and then open that up, you'll recall earlier that if we take a look

  • at our player two goal and player one goal,

  • we have box colliders on both of those, but we made sure to select the is

  • trigger checkbox here, which allows us to say this is not going to collide

  • with other rigid bodies in the physical sense that we normally do when we have

  • a box collider and a box collider with forces and they hit each other.

  • Instead, this box collider is going to disable its collision.

  • It's going to act as a trigger, which means

  • that it's going to be listening for collisions from other objects.

  • And what we can do is in our goal class we can say void on trigger

  • enter collider other.

  • And this is another function that Unity calls for us.

  • Whenever we have a trigger that collides with something else,

  • we can say I'm going to get some collider called other.

  • And I can get the information off of it.

  • And I can do something with it when I end up actually getting that collision,

  • right?

  • So the goal is going to--

  • now how did I do this before?

  • So there's going to be the scores, right?

  • The paddles are going to--

  • or rather, the-- paddles are going to maintain a reference

  • to their own score, which we're going to calculate every time we do get a goal.

  • We're going to say, if the score of paddle one is greater than 10,

  • game over.

  • Or if the score of greater than or equal to 10--

  • or if the score of paddle two is greater than or equal to 10,

  • then we also want to trigger a game over.

  • And we want to make sure that we specify which of these two players

  • was the winner, so player one or player two.

  • And then we also want to reset the ball if we get a collision,

  • if we hit the goal.

  • And we also want to make sure that we have some sort of count down--

  • 3, 2, 1, probably-- in order to give the player chance

  • to think about their next move, to basically say, oh, it's about to start.

  • I'm going to get ready.

  • And then rather than that this is the ball, always just starting instantly,

  • which can be kind of bad design, right?

  • OK.

  • So on trigger enter.

  • So if we do get it such that the goal detects-- either of the goals

  • detects that a ball was the winner, we want the other paddle's score

  • to increment, right?

  • Got to boost that APM during the countdown screen.

  • Yeah, yeah, exactly.

  • So the-- when we get into on trigger enter, when

  • our ball collides with a goal, we want the opposite paddle's score

  • to increase.

  • So we know that we're going to need a reference to a paddle.

  • We can call this probably enemy paddle, right?

  • And then we can say on trigger--

  • minimally, we can say enemy paddle dot score plus plus, right?

  • The enemy's paddle is going to increase.

  • It's going to go from 0 to 1, 1 to 2, 1 to 3, 1 to 4, blah, blah, blah.

  • And then we're going to want to reset the ball

  • and include some sort of logic that puts it in the middle

  • and it does the countdown.

  • Additionally, what we want to do is we want

  • to reflect this change in score in our UI

  • because our UI is separate from the paddles currently, right?

  • So what we can do is in our score--

  • so this is where it's important to have the actual paddle referencing

  • and manipulate our text--

  • we can say in our score, which these are our text

  • variables which have their 0, 1, 2, 3 that we just added to the UI.

  • We can say, we also want to get a reference to a paddle.

  • This is going to be our paddle.

  • And every frame I basically want to say text--

  • rather, this is going to require a component of type text, type of text,

  • right?

  • And for this, you actually need to use Unity Engine.UI.

  • So we do that, and then in our update we can say text.

  • First we need to--

  • couple things we need to do.

  • We need to create a text variable called text.

  • This will be our text component, which has the reference to our actual text

  • information.

  • In start, we want to get a reference to it.

  • Using get component which we've done before.

  • So this will get initialized on Start.

  • And then every update, we just want to keep it in line with our UI.

  • So what we can do is we can say text.text equals

  • and then paddle.score.toString.

  • And so what this will do, because our text.text--

  • so our text component itself has this field called text.

  • And within that-- that text itself is going to store a string variable.

  • It's going to have some text data that it displays in its widget, right?

  • We can't assign that just the raw score, because the score is going to be int.

  • So we need to cast it.

  • We need to-- well, not cast it.

  • Well, we need to convert it to a string using the .toString method,

  • which is available on any integer in C#.

  • And what that allows us to do is now every frame

  • we're just going to say, hey, what's our current score?

  • Update it.

  • What's our current score?

  • Update it.

  • What's our current score?

  • Update it.

  • There's fancier ways to do this such that it doesn't

  • have to ping every update using getters and setters which

  • we could take a look at.

  • But we're not going to do that.

  • It's a little bit fancier.

  • Maybe in a future video we'll take a look at that.

  • But for right now, every frame we're just going to say, what's our score?

  • What's our score?

  • What's our score?

  • And just update it every time, right?

  • So go back to Unity.

  • Go to our player one score.

  • What I want to do is I want to add a component here.

  • I'm going to add a score component.

  • And then the score component for the player one

  • is going to get a reference to the player one paddle.

  • So I'm going to drag the paddle over.

  • Notice that I just drag the object over here.

  • Because I said it's a public paddle, anything that has a paddle component

  • I can just put onto that field, right?

  • So I just click and drag, super nice and easy way

  • to create a relationship between two components, two scripts, two game

  • objects that have different scripts.

  • Player two score, same thing.

  • I'm going to add a score component.

  • I'm going to go to player two--

  • paddle two, rather.

  • Drag a reference over to it, just like that.

  • And then now every frame are going to update

  • and check to see what the score is on the paddle and then update the UI.

  • To string works for only integers in C or for any objects, like in Java?

  • It works on, I think, all objects.

  • And by default it will get some default toString function.

  • But you can overwrite it yourself, depending

  • on the object type that you have, which would give you some more flexibility.

  • JP Guy says, "couldn't you just trigger an event

  • when the ball exits the playing field, AKA flies past one of the paddles?"

  • Yeah.

  • And that's what we're going to be doing with--

  • that's what on trigger enter is.

  • It triggers an event to--

  • with our box collider, which fires the on trigger enter function, which

  • we could--

  • so if we go over to goal, on trigger enter,

  • we could get a reference to the text, which means our goal then

  • needs to have a reference to the text.

  • And if we do things that way, it'll just get

  • a little bit-- we'll have kind of, like, references

  • to a lot of objects between a lot of objects,

  • which would be somewhat more performant, and you

  • would want that for certain use cases.

  • But this case is a very light use of the update function.

  • So we won't implement it that way.

  • And we can also just use getters and setters to do it that way, too.

  • But we will need to establish more relationships between our objects

  • if we wanted to do it that way.

  • And it just a little bit more code and a little bit

  • messier for something that's not super taxing.

  • So it's not worth it, in this case.

  • But yeah, you definitely could, for any object, yeah.

  • If you write your own class and you want to string to behave differently,

  • you have to do that yourself.

  • OK.

  • So our UI widgets now have a reference to where they're pulling the data from.

  • And it gets updated every frame.

  • So what we want to do is make sure that our score actually

  • increments, which it does.

  • So we need to make sure our goals have the goal component.

  • Did I actually do that?

  • I did not.

  • So for each goal, I'm just going to add a goal component.

  • And then individually, I'm going to set their enemy paddle.

  • So remember, if player two goal is interacted with-- so in this case,

  • this goal up here--

  • I want player one's score to increase.

  • So player two goal's should have a reference to paddle one.

  • Inversely, player one goal should have a reference to paddle two cause

  • when their triggers get collided with, the other paddle's score should

  • increase, right?

  • So I'm going to hit play.

  • This should work, I think.

  • It went right to 10 for some reason.

  • Not sure why it did that.

  • Let's figure that out.

  • So why did that get-- oh, because I hardcoded 10

  • in paddle one's score earlier.

  • So I'm going to set that to 0.

  • If you write in the component, a value here,

  • it will override the default component, even when you start the game.

  • So in that case, earlier I had written 10

  • in there just for demonstration purposes.

  • But now we can see, though, that our UI is actually

  • reflecting the score, which is nice.

  • So I'm going to do that.

  • And we did see that it incremented.

  • So I'm going to let that score against player two.

  • So you'll notice that player one, his score increased,

  • his or her score increased.

  • However, the ball did not return back to the middle of the screen, which

  • is a very important thing that we need to do because pong isn't terribly

  • useful if we just get one point scored.

  • And then the ball just goes forever off into 3D space, right?

  • So on trigger enter needs to now actually have a reference to the ball.

  • So this is where coupling sort of makes sense.

  • I'm going to need our ball to know how to set itself back

  • into the middle of the game.

  • And then once it's in the middle of the game space, again, ideally eventually

  • it'll have a countdown so that it doesn't just

  • immediately go back and then move in a direction, which

  • can kind of get a little disorienting for somebody playing the game.

  • I want it to count down and then move in a direction, in a random direction,

  • ideally.

  • Right now it's still in a hardcoded direction.

  • So if I go to the ball class, the ball class should have a reference to--

  • sorry.

  • It should have a function that allows it to reset in the center.

  • So we can do that.

  • I can say-- let's just say I want a function called return

  • to center, right?

  • And that means basically, transform the position equals new vector3, 0, 0,

  • 0, right?

  • Or I think it's 0.2 and then 0.4, something like that, right?

  • Slightly above the plane.

  • And make sure that you appended f at the end of a decimal point number,

  • a floating point number, because floating point numbers by default in C#

  • are doubles.

  • But this function takes floats and the compiler

  • will distinguish between the two of them.

  • Let me see here.

  • So the ball is currently set at 0.06--

  • set that to 0--

  • 0.06, 0, and 0.05.

  • OK.

  • 0.06, 0, and 0.05.

  • So a little bit above the--

  • is that where I want it?

  • Probably want it at 0--

  • want it at 0 like maybe--

  • probably 0, 0, 0, just right in the center.

  • I'm going to do that.

  • That's easier.

  • But yeah, if you're not familiar, if you see

  • an error trying to pass in a floating point number to a function that takes

  • floats, make sure you put the F at the end of the decimal point

  • or at the end of the number, because that tells it specifically

  • cast this to a float, not a double.

  • Back into initial position as in the starting position for the ball.

  • Yep, exactly.

  • So return to center will do just that.

  • And then what I want to do is every time a goal gets a--

  • either of the goals is collided with, I want the ball--

  • or one ball-- to go to the center.

  • And maybe I don't necessarily want a ball reference on each goal script

  • such that I have to manually click and drag the ball over.

  • I could do that.

  • That'd be fine.

  • But let's say I just wanted to--

  • let's say I just wanted to call the ball--

  • just wanted to find it wherever it is in the scene

  • and then call some function on it, right?

  • So I can say game object dot find.

  • And then I give it a name.

  • So it'll be ball.

  • And then dot get component ball dot.

  • And then I can say what was the function?

  • It was called return, right?

  • Game object dot find ball dot get component of ball dot--

  • ball does have return to center, right?

  • Yep, it does.

  • Oh, because it's not public.

  • Has to be a public method if you want to call it from another function.

  • Dot return to center.

  • Should be available now.

  • Now I can call it just like that.

  • So what I've done is I've said I've called

  • the global game the static GameObject.find function, which

  • will look for a string, will look for a game object based off

  • of a string called ball, in which case I have named my game object ball.

  • This is the string it's looking for.

  • It's looking for a game object called ball.

  • Remember, these are all game objects.

  • And then they're comprised of components.

  • So it's not looking for a ball component.

  • It's looking for an object in the hierarchy called ball.

  • And then on that object, I want to call get component of type ball

  • as a function and then the new return to center

  • function that I just defined in the ball mono behavior class.

  • So now if I run this and I get a score, boom, it goes back to the middle.

  • So works perfectly fine.

  • Bavik says, "is default not public?"

  • Default is private.

  • That is correct.

  • Not public by default. So it's working.

  • And I don't think we have a--

  • we don't have any logic in place for getting to 10 at all.

  • No?

  • So this will just go on indefinitely until--

  • I guess until we reach the limit of the integer in C#,

  • which should be about 2 billion.

  • And then it'll loop back around probably to negative 2 billion,

  • which isn't what we want.

  • What we want it to do is when we get to 10,

  • we want to say basically toggle some state

  • this says now it's game over, right?

  • So let's do that.

  • I could probably do that on the ball, right?

  • I could say-- do I want to do that on the ball?

  • I have all of the notes.

  • But I want to see if I can do it--

  • we can do it from scratch here.

  • We can figure it out.

  • So the ball is an object, sort of like a global--

  • like a global state object that we could use that gets

  • a reference to both paddles.

  • And then can do the comparison that says if the score is greater than 10

  • on paddle one, increment-- or, you know, then

  • game over, the paddle is greater than two, game over.

  • The first thing that I think I want to do

  • is I want to create a new UI element called text.

  • And I want this to be my count down text.

  • And then I want a winner text, as well.

  • So what this is going to do is I'm going to have text that renders

  • when we're in a countdown state.

  • And then I want to have text that renders

  • when the winner has been determined after one or the other player

  • gets to 10 points.

  • So the winner text I'm just going to make empty.

  • I will make it 32 pixels.

  • And I will make it white, just so it's easy to see.

  • Same thing for the count down text.

  • Make it white.

  • I'm going to center both of them, 32.

  • You're not going to be visible immediately, but that's OK.

  • I'm going to do this.

  • Delete the text.

  • Grow it out.

  • And then center it.

  • And so winner text and countdown text are just set to empty strings.

  • But we can populate those ourselves.

  • Does Unity work with floats or with doubles by default?

  • Floats with default. Floats by default, rather.

  • OK.

  • So when I trigger a return to center, what

  • I want to do is trigger the countdown, as well, right?

  • I want the countdown to occur immediately before the ball--

  • as soon as the ball goes to the center.

  • And then I want there to be a 3, 2, 1.

  • And then the ball starts moving.

  • And I want the ball to stay completely still while it's in that state.

  • So probably should include it in this return to center function.

  • Almost sounds like return to sender.

  • Is the ball retaining the momentum if it crossed the goal with?

  • Yes.

  • Yes.

  • And that is another aspect of what we want to do.

  • We want to make sure that that is random each time.

  • So we can set its velocity that way.

  • And then that will have the effect of giving it a different velocity

  • every time it goes back to the center, which we could do that here, as well.

  • So let's say I want to-- and also this will be taken out and put into here,

  • the add force function that we called before.

  • Except we're not going to add force anymore.

  • We're just going to set velocity.

  • So I'm going to say rb dot velocity equals new vector 3.

  • And then I'm going to say 404 for now.

  • But what I'm going to do is we're going to randomize this.

  • So I want to make sure that this x and this z get a random value

  • every time we run the return to center function.

  • So what I can do is I can say--

  • do I want it to be an int?

  • Yeah.

  • I'll just make it an int.

  • So I'll say int velocity on the x is equal to random dot range.

  • So this is where we're going to use what's called the ternary operator.

  • So basically what I want it to do is I want

  • to be a value that's either between negative 7 and negative 4, or rather

  • negative 7 or negative 4, or 4 and 7.

  • I want it to be between those ranges.

  • I don't want it to be smaller values like 3, 2, 1, or 0, or negative 1,

  • or negative 2, or negative 3.

  • We could do that to a certain degree.

  • But it will cause our ball in certain situations

  • to move in a straight line, which could get to be kind of subpar,

  • especially because if it's in a straight line

  • it'll just keep moving in the same--

  • no, we won't be able to-- because we won't

  • have any influence over the direction currently.

  • And we won't be implementing directional influence in this tutorial.

  • But we could certainly think of ways to do that using,

  • perhaps, nested colliders or rather multiple colliders that have

  • effects on velocity when they collide.

  • But today we're just going to do simple bouncing off the walls

  • and colliders with rigid bodies.

  • And I want to make sure that the negative values and positive values

  • that I give to my x and z for the velocity fall

  • within a specific subset of numbers, right?

  • So basically what I can say is, I want to do one of two things.

  • I want to either give myself a number between negative 7 and a negative 4,

  • or a value between 4 and 7.

  • So I'm going to say random dot range of 3--

  • or rather, 1 to 3 is equal to 1.

  • Question mark.

  • And what this is basically saying is if--

  • because random dot range with integers is exclusive for the larger term,

  • this is basically going to give me a number between 1 and 2,

  • which is a 50% chance.

  • So it's like negative 7, 7 minus 3, 3.

  • Kind of.

  • Only, it's going to be--

  • I guess in vectors--

  • can we do that with a simple vector calculation?

  • Can we say negative 7 7--

  • it'd be a little bit--

  • I think a little bit more complicated with the vector math in that case.

  • But kind of, in that case.

  • We're basically saying negative 7--

  • basically it's going to be between negative 7 and negative 4, or 3 and 7,

  • 4 and 7.

  • Want to create a velocity where the vector sum is between 4 and 7.

  • The vector sum is between 4 and 7?

  • I'm not sure.

  • If you can elaborate on that.

  • I'm not sure what you mean by that.

  • In that case, you could just use Pythagoras.

  • Maybe?

  • If you can elaborate, perhaps.

  • Again, I'm not an expert mathematician by any stretch.

  • 7 less than or equal to x, [INAUDIBLE] or equal to 3

  • where 3 is less than or equal to x is less than or equal to 7.

  • Almost.

  • The first one, negative 7 less than or equal to x, less than

  • or equal to negative 4 for that one.

  • So I'll show you here.

  • I'll say random dot range 1 to 3.

  • If it's equal to 1, which is a 50% chance,

  • then we're going to say it's equal to random dot range of negative 4

  • or negative 7, or using the colon, if that's not

  • the case that that first condition was true,

  • then I'm going to set it to a random dot range between 4 and 7.

  • Right?

  • Copy that for the z.

  • And so it's a ternary statement that basically does a comparison between 1

  • and 2, flipping a coin.

  • It's either going to be negative 4 to negative 7 or 4 to 7.

  • And there might be a more elegant way to write that out mathematically.

  • Definitely toss them in chat if that's the case.

  • But this is a simple, easy way of sort of visualizing how it

  • works using a coin flip, effectively.

  • And what we can do is I can say velocity is equal to vel x and vel y, right?

  • Sorry, vel z, not vel y.

  • And transform dot position is equal to a new vector 3 0, 0, 0?

  • Yes.

  • We want that to be the case.

  • We want to reset our position to the middle, just like we did before.

  • And so now if I call this in our code, we

  • should see a random value every time when we run our game here.

  • Let's try it out.

  • Whoops.

  • So in that case--

  • whoa.

  • That was weird.

  • I was not expecting that.

  • We had some weird behavior there.

  • I'm not sure why-- oh, because we forgot to constrain our ball.

  • So another thing we want to do is we want

  • to constrain our ball such that it doesn't move along the y position.

  • So we want to freeze y position.

  • And then we freeze this rotation, as well,

  • because we don't want it to rotate.

  • We just want it to move.

  • You can also use random dot value for the coin flip,

  • gives a float between 0 and 1, so you can check for a greater than 0.5.

  • "Yeah, that's correct," says [INAUDIBLE]..

  • OK.

  • Try that.

  • There we go.

  • That's better.

  • I'm going to let it do that.

  • Return to the center.

  • Boom.

  • So it is randomizing it.

  • That's nice.

  • It's changing the velocity.

  • And it's more or less the same kind of--

  • the same kind of a 45 degree angle-ish code.

  • And that's just because we're kind of constraining

  • our range of values between 4 and 7, just

  • for the sake of ease of the tutorial.

  • If we wanted to get fancier with it, our paddles

  • would manipulate the velocity, the angle at which the ball bounces off

  • of it, such that we would get more acute and more obtuse angles.

  • But yeah, Astley says, "so the question is, like,

  • if and the colon is like else if?"

  • Yeah, it's more like if else, not else if, necessarily.

  • So basically we check this condition.

  • So this is a Boolean--

  • this whole thing here is a Boolean expression.

  • Random dot range 1 to 3 is equal to 1 because it's exclusive of this 3.

  • So it's going to return 1 to 2.

  • It'll return 1 to this number minus 1.

  • So this will be either 1 or 2.

  • And we're basically saying, if it's equal to 1--

  • so a 50% chance, maybe random--

  • then we want to do this bit of code.

  • Else, we want to do this bit of code.

  • So basically, rather, it will evaluate this expression,

  • which means it will get assigned into this because we're using

  • this equals here at the very beginning.

  • So we're equaling the whole calculation of this expression.

  • It's a ternary operator and a ternary expression.

  • So it's if else, yeah.

  • If else, not else if, though.

  • The colon case will happen no matter what.

  • There's no condition for that if the first expression evaluates to false.

  • Yeah.

  • Just a nice convenient way to write if else.

  • We could have written this whole thing out in an if else statement, as well.

  • But it's just a little bit easier to read and sort of visually see

  • what's going on that way.

  • OK.

  • So we've done that.

  • We've got our ball spawning in a random direction, which is fantastic.

  • That's what we wanted to do.

  • We froze our position so that it doesn't bounce in a weird direction, which

  • is what it did earlier.

  • That was an elegant way for real numbers in Python

  • would be like random dot random minus 1 times 7 minus Python

  • dot random minus 1 times 3.

  • Yeah.

  • It can be a little bit nasty, sometimes, dealing

  • with specific ranges of random numbers.

  • Generally, you don't want it to be in sort of split--

  • it's kind of like a piecewise function in this case, I guess you'd call it,

  • where it's split kind of amongst two different realms, two different domains

  • or ranges.

  • But yeah, usually it's not that painful.

  • It's usually just a random dot range some number, two numbers.

  • But anyway, so now we have the collisions.

  • We have the ball returning.

  • We have randomization.

  • So what we want to do is we wanted to test whether somebody has won.

  • And if they have won, we want to say it in the y.

  • So we can probably do that with the ball.

  • So what I'm thinking I'll do is I'll let the ball script have

  • a reference to the two paddles, right?

  • So public paddle, paddle one, paddle two.

  • So the ball is going to maintain a reference between both--

  • to both paddles, and can compare their score.

  • So if we say if score or if paddle one dot

  • score is greater than or equal to 10, then I

  • should probably do some sort of win condition.

  • If paddle two dot score is greater than or equal to 10, do some win condition.

  • And then otherwise, it's just going to go down after that.

  • It's going to run the rest of this code.

  • So what I can do is I can say maybe I want a reference to that text

  • from before.

  • So what I can do--

  • do I want to do that?

  • I guess I could.

  • Yeah.

  • So what I'll do is I'll actually have a reference to the text.

  • So I'll say public text when text.

  • Right?

  • And this is where we have a bunch of components talking to each other.

  • And so often you'll want to kind of figure

  • out the most elegant way to have all your stuff talk to each other.

  • This is not terrible.

  • But continuing to do this forever and ever will be not super sustainable.

  • So you want to be careful.

  • But remember, we have to include the Unity engine, not UI,

  • if we want to use a text.

  • So I'm going to say public text, win text,

  • notice that if we go down to my ball script I have a win text reference.

  • I'm going to just--

  • this win text right there.

  • I'm going to also drag in a reference to paddle one and paddle two

  • since we wrote those as public variables.

  • So now our ball is kind of like our-- almost

  • like having our whole game on itself, or at least

  • the important variables that determine whether or not we win,

  • because it has the function that returns to the center anyway.

  • So it's kind of nice to have the logic in there.

  • So every time we call return to center we

  • can basically do a calculation on the score.

  • And if we want, if someone won, we can just change the text

  • and then that's it.

  • Otherwise, we can start the countdown and go into the next--

  • go into the next step, right?

  • So what I want to do is I'm going to say if paddle one dot

  • score is greater than or equal to 10, win text dot text dot enabled--

  • or sorry, win text dot enabled is true, and win text

  • dot text is equal to player one wins.

  • Cannot use single quotes.

  • That's a bad habit from using languages like Lua.

  • But that's that, right?

  • Win text dot enabled is equal to true.

  • Win text dot text is equal to player 2 wins.

  • And that's that.

  • And again, recall we have the text set to disabled.

  • So in our UI, if I go over to winner text, for example, winner text is--

  • actually, it's not disabled.

  • So I'm going to click that to make sure it is disabled.

  • Same thing with countdown text.

  • I don't want those rendering while they don't

  • need to be, even though they will probably not have a value by default,

  • I should still keep them hidden until they need to be alive.

  • And that's what this enabled is true thing does.

  • So remember, this win text is a reference to this text component here.

  • So if I say win text dot enabled is equal to true or false,

  • it's the same thing as checking that box and saying you can or cannot display

  • it.

  • And remember, if we click or unclick any of these components, they--

  • like the mesh render, for example, for our paddle--

  • it turns it on or off and displays it or doesn't display it.

  • Depending on what kind of component that is, it can maybe do a calculation.

  • It can maybe display something.

  • So if you just want your component to be off when you start

  • and then turn on programmatically, that's

  • how you do it-- dot enabled equals true or false on the component itself.

  • [? Bavik ?] [? Knight ?] says, "yeah, the random function that you elaborated

  • on was more mathy."

  • Yes.

  • A little bit more mathy.

  • So we have our win condition set here.

  • And if it's not the case that somebody-- or that one of the two paddles has won,

  • then what we want to do is probably do this bit of code with the velocity.

  • Set the position to the middle.

  • And then probably what I want to do is--

  • this is where I want to eventually do the countdown.

  • Another thing that I want to do is as soon as somebody does win,

  • I want the game to stop, right?

  • I want it to say that they won and it's done, right?

  • So what I can do is I can say time dot time scale is equal to 0.

  • And what this will do is it basically does the equivalent of stopping time.

  • The timescale is how things move, like if you--

  • between 0 and 1.

  • So if it's 1--

  • or I guess you could--

  • I think you can go even higher than 1 to speed up time.

  • But it'll effectively slow down time if it's a number that's less than 1.

  • So you can have slow motion, or if it's 0, pause the motion.

  • So if you have a pause screen, for example,

  • you can just set the timescale to 0.

  • And what this will do is effectively stop our game

  • as soon as somebody has gotten a score of greater than 10, right?

  • And we could restart our game, too.

  • We can have somebody checking for input, one of the components checking

  • for input, and says if get key or get axis space or pause or whatever,

  • and time dot timescale is 0, and then restart the game.

  • And head back to put the ball back in the center.

  • And so on and so forth.

  • So if I run this, I'm going to let somebody get to 10 points.

  • 3, hopefully fairly quickly.

  • Boom.

  • So player two.

  • And I guess I didn't make my box large enough.

  • But it should say player two wins if I go to my player two--

  • my winner text-- and just make it a little bit larger, like that.

  • See, it's just a little too small.

  • But player two wins.

  • And notice that the game stopped.

  • The ball is frozen in the place where it was before.

  • And it demonstrates that we are, in fact, calculating

  • the logic of when somebody gets 10 points, and reflected that in our UI,

  • and in our game stake, sort of.

  • We sort of have an ad hoc game state with if statements.

  • But we could do this with the state machine,

  • if we wanted to, in a more complicated setup.

  • Today we're not going to mess with state machines at all.

  • I'm going to make that a little bit larger because changes

  • that you make to the UI aren't actually reflected when you come back

  • into the UI from the game.

  • So anytime you change something in Unity while the game is running,

  • it will go back to how it was before the game was running.

  • So you can mess with values in your game while it's

  • running to get the perfect setup for everything.

  • But just make sure to go to make note of what you've set them to

  • and set them in the editor after the game

  • has stopped running because all your changes are volatile and will disappear

  • as soon as you go back into the editor.

  • So something to be mindful of.

  • So that's why I went back and I resized the box again.

  • The countdown text I can keep as is.

  • It's a fine size.

  • But now when the player wins, one of the players

  • wins, we should actually see the full text in the middle of the screen.

  • Now we want the ball to give us a 3, 2, 1.

  • That's kind of one of the last things we want to take a look at, probably.

  • And so the way that we can do that is--

  • so the game is--

  • it takes place over--

  • the 3, 2, 1 takes place over time, right?

  • A second is going to pass between the 3 and the 2, between the 2 and the 1,

  • between the 1 and the actual ball starting off in a specific direction.

  • And so what we want to do is set the--

  • we want to set the--

  • we do this over the course of time asynchronously

  • in what's called a co-routine.

  • A co-routine is just a function that takes place sort of not technically

  • in its own thread, but you can almost think of it

  • as taking place in its own thread separately

  • from the main flow of your game.

  • And this is how you can get a lot of asynchronous behavior to work in Unity.

  • And you have to write co-routines in a very specific way in order

  • for them to work.

  • So what we can do is I can say, public i enumerator countdown.

  • And co-routines do need a count-- or a i enumerator return

  • type, which is how Unity does its co-routines.

  • And i enumerator is just a collection of things that can be iterated over

  • and Unity co-routines will be--

  • Unity co-routines will be--

  • are essentially collections of code elements

  • that it iterates over, as opposed to a collection of, say, items

  • in a list or a hash map or whatnot.

  • Remember that the change to the rect box you make in the game mode

  • will not stay.

  • Yes, yes.

  • [INAUDIBLE] to my point before, anything that you change in the game mode

  • will not be reflected in the editor when you go back.

  • By the way, Unity recommends also slowing down

  • time dot fixed delta time by the same rate

  • if you're playing around with slowing things down.

  • Yeah, that's a good point.

  • That's a good point.

  • I don't think it should cause any issues here,

  • just because we're stopping the game altogether when we end.

  • But yes, I think if we were doing physics calculations

  • and we were slowing things down by a fractional amount, especially,

  • we would want to do that.

  • We would want to slow our fixed time and our update time.

  • Good point.

  • OK, so in the case that we do want to count down everything,

  • I'm going to say--

  • let's say in our co-routine when it's finished, that's when we--

  • that's when we finally want to actually set our velocity, right?

  • So I can do that.

  • I can do that here.

  • I'm just going to set those variables in there, just like that.

  • So our countdown is actually going to do the resetting of the velocity

  • as soon it's finished.

  • Legend Snake 28's got the pog champ.

  • In the countdown function, this is where we're

  • going to do the asynchronous behavior.

  • And we're going to see how exactly that works using something called the yield

  • return.

  • And so yield return is basically a way of saying pause

  • the execution here in this function and on the next frame

  • go back to the next sort of iteration of the loop, which

  • is what it will usually be.

  • You'll usually do co-routines in some sort of a loop, right?

  • In our countdown, is it is indeed in the form of a loop.

  • So what it is going to be a--

  • we're going to set an int to num equals 3.

  • And we're going to do a 3, 2, 1 countdown, 3, 2, 1 and then countdown.

  • So what I can say is 4--

  • actually, I don't even need to do this.

  • I don't need to initialize this.

  • I can just say for int i is equal to 3, i is greater than 0, i minus minus.

  • So a countdown loop as opposed to a count

  • up loop, which is what you usually see.

  • I'm going to say--

  • I want to have a reference to some text again.

  • So win text and countdown text.

  • I want to say--

  • first of all, I want to say countdown text dot enabled is equal to true.

  • And then I want to say countdown text dot text is equal to i dot to string.

  • So it's going to be 3, 2, 1.

  • It's going to set the actual string value of that--

  • it's going to basically convert that number to a string.

  • Set that into the text of the countdown, which remember is the UI element

  • itself.

  • And then I'm going to do something called yield return new wait

  • four seconds one.

  • And what the yield return new wait for second to one does is it--

  • it's called a yield instruction.

  • And Unity has a scheduler where it looks at all co-routines that you've created

  • and basically keeps track of how long each one is supposed to execute or wait

  • until the next element in its collection is fetched from the i enumerator.

  • So basically it's just a collection of code segments.

  • In this case, the enumerator is going to be the blocks of these.

  • It's going to be kind of an abstract way of looking at code as items in a sense.

  • And it's basically going to do this.

  • Wait a second.

  • It's going to then come back to this on the--

  • after this wait for a second has finished.

  • So it's going to wait for a second after it's set the string to that variable.

  • Then as soon as that second is finished, it's going to come back to this loop.

  • It's going to decrement it to two.

  • Do it again.

  • Wait for another second.

  • Decrement it to one.

  • Wait for another second.

  • And then at zero it's going to have finished.

  • And then at the very bottom, we can yield return null, at which point

  • we also want to--

  • well, rather, what we can do is say we want no velocity.

  • I want to set the velocity to that variable, to the x,

  • z that we declared up top.

  • And so basically, this will have the effect

  • of setting our velocity of our ball to 0 when it starts.

  • So when the countdown begins, it's zero velocity.

  • It's not moving anywhere.

  • Position's in the middle, 0, 0, 0, I'm not moving anywhere.

  • And then after all of this is done, these yields--

  • remember, the second pass is in between each iteration of this loop.

  • It's going to then set the velocity correctly.

  • And then you'll return null.

  • At the very end of this function, that's when the co-routine is finished

  • executing, and then it will just--

  • it'll just be done at that point.

  • So I can say start co-routine count down.

  • So this is in the case that nobody has gotten up to 10 points.

  • I want to call this function called start co-routine.

  • This is a function that puts this co-routine

  • into the Unity scheduler, which they don't publicly

  • have the source code available for it.

  • But you can imagine it as just a list of count

  • of co-routines that are constantly being iterated through every frame

  • and looking at their wait for seconds amount

  • and seeing if the amount of time between the last frame and this frame

  • is passed.

  • And they can go on.

  • But you do need, in order to execute a co-routine,

  • you can't just say countdown like this.

  • It's not going to work.

  • You have to say start co-routine countdown.

  • And that will let Unity start managing it for you

  • and actually doing the necessary logic that you need to get it to work.

  • And so what that should do-- oh, one last thing, after that loop is

  • finished, we need to say countdown text dot enabled is equal to false.

  • And that is all we need, because then on the next iteration of countdown,

  • it'll start at three again.

  • So let's see if that works.

  • Let's see if I didn't screw it up.

  • I do need to set a reference on the ball to the countdown

  • text, which I can do like that.

  • And then if I hit start--

  • 3, 2, 1, and then the ball doesn't go.

  • Interesting.

  • Let's see where we screwed that up.

  • Oh, because I copied it.

  • I didn't actually say vel x and vel z.

  • You're going to want to do that.

  • Let's try that one more time.

  • vel x and vel z.

  • Let's go.

  • 3, 2, 1.

  • And then it goes.

  • Beautiful.

  • So in that case, I screwed up the actually getting the ball.

  • There we go.

  • That's better.

  • But yeah, so pretty all-encompassing.

  • It works pretty well.

  • "Yeah, minor bugs," says JP Guy.

  • Yeah.

  • Hate those.

  • Those are the worst.

  • That minor bug was a source of, like, a five minute hurdle on one

  • of the last streams with naming one of the maps the wrong way.

  • That was beautiful.

  • But yeah, that pretty much is it, actually.

  • I mean, the game now will go to game over.

  • And once it's hit game over, it will stop altogether, right?

  • Let me verify that that's true.

  • It should-- yep, because it will do this.

  • Time scale is going to be equal to 0.

  • And then if it's not the case that that's true,

  • that's when it goes to start co-routine for countdown.

  • But that was I think pretty much everything I wanted to talk about.

  • I'll stick around for a few more questions,

  • but that's the gist of 3D pong.

  • We have a fully working, fully two player version of pong.

  • So one person's left and right.

  • Let's see if I can play against myself.

  • No.

  • And then when somebody loses, it just says player X wins.

  • So I think that's what we're--

  • where we will cut the stream.

  • It is at the three hour mark now.

  • If anybody has other ideas for games they

  • want to maybe implement in Unity or not in Unity,

  • we can certainly take a look at that.

  • And I'm always open to more ideas.

  • I think it's super fun.

  • I would love to do more Unity in the future,

  • but I also do want to dive into some more 2D stuff.

  • So on next-- which day is it?

  • I forget.

  • I think it's next Wednesday I'm doing tic-tac-toe in Lua and Love.

  • So if you want to join us again for a little bit more basic game programming,

  • it'll just be Love 2D tic-tac-toe.

  • Udon Master says, "Space Invaders on go dot."

  • So I'm not too familiar with go dot.

  • We can maybe do Space Invaders in Lua or Unity.

  • I'm not sure if I can maybe find somebody that knows go dot.

  • JP Guy says, "good job again."

  • Thanks for streaming.

  • Thanks so much for coming in and joining us again, JP.

  • You're here very consistently.

  • Reema7 says, "new Twitch category."

  • I don't think we're the first people to do this, but yeah, it's--

  • I think this is a great use case of twitch,

  • being able to do all this live and interact

  • and just sort of build things together like it ended today in the chat,

  • helping out with the physics issue.

  • That was awesome.

  • As much as that might have been frustrating to look at,

  • I think that that was a great example of how this can be a nice collaboration

  • tool, more than it even is educational.

  • Although, this is intended to be an educational stream,

  • but we could certainly do like a more live collaboration type thing,

  • a lot of ideas.

  • So we'll see where it goes.

  • I thought you referred to this as a 2.5D game?

  • Is this referring, for example, to the creation of the paddles in 3D

  • and the way the shadows are cast, and does the user always

  • see the same fixed point of view?

  • So Twitch hello world, 2.5 D just means that it's rendered in 3D engine,

  • but we're constrained to some 2D axis.

  • So in this case, all of the behavior that we do--

  • the ball and the paddles moving--

  • that's all in 2D.

  • But it's rendered in 3D.

  • So things are casting shadows.

  • We have 3D meshes interacting with each other and 3D collision.

  • That's all occurring.

  • It's just more the way that the mechanics are constrained.

  • [INAUDIBLE] says "thank you, Colton, for the stream."

  • Thank you for coming and being a part of it.

  • Much appreciated.

  • It's my pleasure.

  • [? Bavik ?] says "thank you, this was a good one."

  • Thanks, Bavik.

  • Appreciate it.

  • Thank you for tuning in.

  • And what software do you use to stream, OBS?

  • Yes.

  • Stream Labs OBS.

  • So there's OBS proper and then stream labs OBS.

  • Stream Labs lets us do the Twitch chat integration and other fancy stuff,

  • so that's pretty nice.

  • But yeah, Stream Labs OBS.

  • Yeah, thanks, Colton, says Astley.

  • Thank you, my pleasure.

  • Reema7, "thanks for the stream.

  • Keep it up."

  • My pleasure, thank you.

  • Andre, "it's also awesomely educational.

  • The amount of time [INAUDIBLE] and I tripped over those kinds of bugs

  • is probably more than I'd like to admit."

  • Yeah, I mean, I'm going to trip over many bugs going forward.

  • And today was, you know, we had a few-- a couple of small ones.

  • To be fair, I didn't test the speed going higher

  • than three, which I should have done.

  • That was my mistake.

  • But we fixed it.

  • We collaboratively sort of powered through it.

  • It was fun.

  • Sorry, I can't read the name on that one.

  • [INAUDIBLE] says, "browser crashed, so I missed the last few minutes.

  • Thank you, Colton."

  • That's not good.

  • Which browser are you using where it crashed?

  • I'm sorry to hear that.

  • W Wood, enjoying all these streams.

  • Thanks.

  • I'm getting sound issues in each one.

  • But it might be just me.

  • Can you elaborate on the sound issues?

  • I'd like to know what they are so we can fix it for sure if it's on our end.

  • JP Guy, "what was your Twitch username again, Colton?"

  • I don't personally have a-- well, I do have a Twitch username,

  • but I don't stream personally to it.

  • But the Twitch for today--

  • oh, you know this one, I guess.

  • It's obvious.

  • But if you wanted my personal one, it's this one.

  • I don't stream yet.

  • Maybe in the future game stuff, maybe.

  • I don't know.

  • This takes up enough time to where I don't

  • feel like I'd want to necessarily go home and scream again after this.

  • I mean, maybe.

  • Playing games on steam is easy.

  • It doesn't require a whole lot of mental effort.

  • I guess it requires you to stay on, but that's a different issue.

  • PM seems easier than sending an email.

  • Oh, yeah, I guess.

  • I don't ever go on twitch for messages, though.

  • Like, I'm not signed on, so you have a better chance of emailing me.

  • So cogden@cs50.harvard.edu.

  • Email would be safer, I think.

  • "Chrome had too many tabs open, I think," says [INAUDIBLE]..

  • Yeah, Chrome is a memory hog.

  • But I mean, even I have, like, 20 open sometimes and I don't crash.

  • So I'm curious how many tabs you have open if yours is crashing.

  • Probably can't even see what they are.

  • Cuts out briefly periodically and kind of

  • sounds as if trying to switch between lab mic and camera mic.

  • That could be the bit rate of the broadcast, W Wood.

  • So if your stream quality is--

  • if it's dynamically changing the stream quality,

  • then that's typically what it sounds like.

  • You get sort of like--

  • it sounds like you're switching between a camera and a lab,

  • but what you're actually doing is you're just getting a decreased bit rate

  • and it just has the effect of sounding lamer.

  • Email was coltonoscopy, right?

  • Yeah, coltonoscopy@gmail.com, cogden@cs50.harvard.edu

  • is my work email.

  • I check my work email more often than I check my personal email during the day,

  • probably.

  • "Might just be me," says W Wood.

  • Yeah, if anybody else is getting that same issue, definitely let me know.

  • We can take a look at it.

  • CS50 mail, yeah, that would be preferred.

  • Twitch Hello World, "if you were to create scenery for this

  • and you have the art for it in 2D art files,

  • would you suggest building assets similar to how

  • you did the paddles, then bringing the art in simply to use as textures

  • on these or bringing the art files in as they are

  • and just adding effects here and there to make

  • it look consistent with the shadows cast by the ball and the paddles?"

  • Ultimately, that's artistic discretion, I think, because you're describing 2D.

  • So if you were to make 2D art textures for this, like grass for the ground,

  • for example, there is a million different ways you make that look.

  • If you're talking about models, 3D models included in the game,

  • those will cast light naturally because they're using the same lighting

  • calculations as the paddles.

  • So that's what you might want to do if you're

  • thinking of actual physical scenery that you want realistic lighting on.

  • I would probably think about doing that.

  • But for 2D, you use what are called sprites, generally.

  • And it's going to be a little bit different in that case.

  • My Chrome froze initially quite a few times.

  • The desktop app on Windows just crashes.

  • Is there a chance that in the future we could

  • see something like phasor framework with socket io for web games,

  • says Udon Master.

  • Potentially.

  • I used phasor a little bit.

  • They just recently changed to phasor 3 and they've done a lot of stuff.

  • And the documentation was, last I checked,

  • a little bit messy and kind of incomplete.

  • So I'll take a look at it and determine if that's

  • something we could take a look at and then maybe do some game development on.

  • Good suggestion.

  • Thank you for it.

  • Throat is getting a little bit sore, not terribly.

  • These are hard to do.

  • I feel like doing enough of these, eventually my voice will just give out.

  • But we're in there.

  • I'll stick around for just a couple more questions if anybody has them.

  • Again, if you're watching this on YouTube after the fact and you

  • aren't following our Twitch channel, it's twitch.tv/cs50tv.

  • We stream often.

  • I would say 4 times a week, usually, at least as of now.

  • And the plan is to continue doing so.

  • I usually do one or two streams a week, three hours on game development.

  • And we have guests talk about things like React.

  • We have GitHub.

  • We have CICD.

  • On Monday we have--

  • let me just make sure that my schedule is correct on this.

  • I'm not 100% at the moment.

  • I believe on Monday it's Kareem, Kareem the dream.

  • How do I get out of this?

  • Let's go back to this.

  • Go to Facebook.

  • Let me just make sure that my schedule is correctly,

  • because I don't have my calendar up on this computer.

  • So I go to events.

  • If you're not following our CS50 Facebook,

  • definitely follow our CS50 Facebook.

  • We have all of our events listed there.

  • So on Monday, we have Kareem is his name, Kareem the dream.

  • He's going to be talking about CI/CD, so deploying apps,

  • testing apps, including that in your GitHub workflow, if you're interested.

  • So super useful stream if you're interested in dev ops at all

  • and want a sense of how to deploy apps.

  • Probably do a demonstration of deploying something to GitHub pages or Heroku.

  • Not 100% sure what he has in store.

  • On Tuesday, CS50s Dan Coffey is going to talk about Draw 50.

  • So Draw 50 is the app that David uses in Sanders.

  • So let's go to our--

  • let's go to CS50 2018 lecture zero.

  • Plug a little CS50 here.

  • And then let's go to where David's drawing on the screen.

  • Is he drawing anywhere visually?

  • So he has this-- he has this big screen in lecture where--

  • what's a representative lecture?

  • Maybe lecture one?

  • I don't remember which lecture he actually drew on it.

  • I would love to get a little screenshot.

  • Well, anyway, he uses it as a giant digital blackboard

  • because we're using an app that Dan Coffey wrote in JavaScript

  • that allows using Paper JS and Hammer JS, allows him to write and erase

  • just like it was a giant blackboard.

  • So it's pretty cool.

  • And so Dan's going to talk about how that works on Tuesday.

  • On Wednesday, it's going to be yours truly again.

  • We'll do tic-tac-toe.

  • We'll do it in probably Unity--

  • or not Unity, in Love 2D and Love again.

  • A little bit more of a low--

  • not low-level, but a basic entry-level game style.

  • And on Friday, Linux command tutorial with Nick Wong

  • who did a video this week on--

  • I'm blanking.

  • What did we talk about?

  • Machine learning.

  • We built a binary classifier in tensor flow.

  • So all kinds of topics.

  • I do games generally, but I co-host with everybody

  • else who does all kinds of other stuff.

  • Sounds like I could do three models and simply lay the face from the 2D

  • art over it as a texture to start.

  • Thanks.

  • Yeah.

  • You would have to do something like that.

  • But it doesn't map cleanly.

  • You have to do what's called UV unwrapping

  • and you have to do that generally in a 3D software package like Blender

  • where you actually unwrap all of the faces of your mesh onto a 2D plane

  • and then put your texture onto that and sort of map them together.

  • But yeah, you could do a texture onto a simple surface and--

  • onto a simple surface that doesn't have a lot of faces,

  • and just do like a flat--

  • sort of a box or a plane unwrapping.

  • But that's not-- that's generally not what you do for models.

  • With models you do want to use UV unwrapping.

  • Bavik says, "probably with strings."

  • I think what we're going to do is we're going to use--

  • we're going to use graphics, so we'll use it like a pixelated x and a circle

  • for tic-tac-toe, and probably stay away from strings,

  • I think, just to keep it a little bit more interesting.

  • But you could do it--

  • absolutely could do it in strings at the command line, for example.

  • One of the first things I got taught in a C++ class many years ago was we did

  • a C++ command line script of tic-tac-toe.

  • So you absolutely could do it with strings.

  • But we'll be using images.

  • Yeah.

  • "Complex models have to be mapped," says Reema.

  • Yes, correct.

  • Ray declares there is no string in C in that lecture.

  • Char arrays are drawn as contiguous memory blocks.

  • Oh, that's what you're referring to.

  • Yes.

  • You're right.

  • Yeah.

  • I don't remember exactly what timecode it is, what lecture it is.

  • I M GSH, I'm not sure to pronounce that.

  • Imgsh says, "Unity related with Java?"

  • No, not at all.

  • But C# is very similar to Java.

  • And that is where the relationship sort of comes into play, I guess.

  • Or at least people think there is a relationship.

  • But yeah, Unity is completely scripted in C# in Java and C# are very,

  • very similar, at least on the surface.

  • They looked very similar.

  • Twitch Hello World says thanks.

  • No problem.

  • If anybody has any last questions, I think I'll answer them,

  • and then in a couple of minutes here we'll sign off for the day

  • and then call it a week.

  • And then next week, we'll start strong with some CI/CD with Kareem Zidane.

  • Be sure to tune in for that and for all lectures next week.

  • And keep providing us with ideas because the more ideas we have,

  • the more awesome stuff we can make.

  • I can come up with ideas, but sometimes it's nice to have a little bit of fuel

  • to work off of, you know.

  • "Thanks, this was so interesting," says Twitch Hello World.

  • Absolutely, yeah.

  • No, I love Unity.

  • I would love to dive a little bit deeper into it.

  • We did a very basic thing today, but there

  • is so much with [? cinna ?] machine and something

  • that I really like is called pro builder and using character controllers

  • and actually making worlds and making interesting gameplay mechanics,

  • making--

  • you can make a shooter, probably a kid-friendly shooter for a stream.

  • But yeah, we can do a lot of cool stuff.

  • Andre, thanks Colton.

  • This was really cool.

  • Thanks, Andre.

  • Thanks for tuning in.

  • Thanks for your assistance today while we coded.

  • I know there were a couple of small little hiccups we ran into.

  • And [INAUDIBLE],, thank you again very much for your assistance today.

  • Awesome.

  • As usual, have a great weekend, everybody.

  • Yes.

  • Yes, definitely have a great weekend everybody.

  • [INAUDIBLE] 12, "thanks for taking the time to do this."

  • My pleasure.

  • No, it's a lot of fun.

  • We could potentially do longer streams in the future.

  • I was thinking of doing, like, maybe an 8 hour stream.

  • I know that sounds kind of ridiculous, but a lot of Twitch streamers

  • do, like, 8 hour streams.

  • That would be pretty cool.

  • We could do a Python stream from scratch,

  • like somebody who has never programmed before,

  • like, walk them through Python from ground zero to like nothing.

  • That would be cool.

  • Like a long-- and they could chop it up into separate YouTube videos,

  • maybe, something like that.

  • Agree, good to see what you guys are doing with my models.

  • GG well played.

  • Have a nice weekend.

  • GG well played, Reema said.

  • Browser's acting up.

  • Freezing.

  • Have a good day.

  • See you guys next time.

  • See you, Bavik.

  • Sorry that your browser is acting up.

  • Damn, eight hours.

  • "That's hardcore," says JP Guy.

  • Yeah.

  • There's a lot to cover on just getting somebody started with Python or C.

  • You know, we don't go into a lot of depth--

  • we do go into fair depth in the lectures,

  • but we only have an hour and a half to cram a tremendous amount of material.

  • And imagine what we could do in eight hours, right?

  • Robotics, Matlab would be a good idea.

  • Yeah.

  • I'm nowhere near qualified to talk about any of that,

  • but I could maybe look around and see if somebody is into robotics.

  • It would be a little trickier with robotics,

  • just because then we have to have a camera that's filming a robot,

  • you know?

  • That could get more tricky.

  • Especially when you need, like, zoom shots and stuff like that.

  • Currently our camera is mounted onto a TV that I'm looking at as a monitor.

  • So it would be difficult, but not impossible.

  • Matlab, for sure.

  • But I have never used Matlab, so I would be the last person

  • to give a seminar on Matlab.

  • "Have a great weekend, everybody," says Astley.

  • Says [INAUDIBLE],, "I'd love to go into depth in machine learning.

  • Machine learning is super interesting."

  • Me, too.

  • I would love to go more in-depth into machine learning

  • from a more basic approach because, I mean,

  • even I was getting lost with the Nick's seminar.

  • And I mean, that's just natural, I think,

  • because machine learning is such a vast topic.

  • But machine learning from bare basics to something functional

  • would be super cool.

  • But yeah, again, I'm not qualified to do that.

  • I'm barely qualified to give game lectures.

  • I'm just kidding.

  • This was fun.

  • Whenever we hit those little tiny roadblocks on the code,

  • it's a nice opportunity to operate under pressure.

  • Just grab [INAUDIBLE] if you want to check out the basics of Matlab.

  • The syntax is identical.

  • OK.

  • Might check it out.

  • I've never had occasion to try it, but, yeah, basic.

  • I understood, like, 5% of what Nick said.

  • No, I mean, machine learning is serious, right?

  • And it's hard core.

  • But if you know machine learning, like, you're set, right?

  • I wouldn't mind learning knowing more about it, and AI.

  • AI, too, would be super cool to be super familiar with, right?

  • Right, well, it's 4:19.

  • I'm going to wrap up the stream here, I think.

  • So thanks everybody who tuned in today to our basic introduction

  • to Unity and 3D implementing pong going from 2D to 3D.

  • It was a tremendous amount of fun.

  • And I love Unity a lot.

  • I'd love to dive deeply into it.

  • I might have said this before on stream, but some

  • of the things that I've always wanted to do

  • is make an N64 era platformer, like Banjo-Kazooie or something like that.

  • So doing something like that in Unity would

  • be super cool to do on stream over, like, a multipart series.

  • JP Guy says, "machine learning and big data are probably

  • the most relevant fields right now."

  • Yeah, definitely.

  • That's what I hear.

  • It's a shame that games doesn't quite have that level of prestige,

  • but you know, we get by.

  • Games are fun, right?

  • I'd be interested in a streaming overview of algorithms and data

  • structures, architecture, and analytics respectively.

  • I hope to take those courses, though a bird's eye overview is interesting.

  • Yeah, me too.

  • I mean, I have a lot of that.

  • I wouldn't mind reviewing myself.

  • So getting people in here to actually walk us through algorithms and stuff,

  • that would be pretty cool.

  • We'd probably want to do it in code, just to kind of see it work.

  • And if we can see it visually, too, that would be interesting, as well.

  • Yeah, this is CS50 on Twitch.

  • If you're not following us on Twitch, twitch.tv/cs50tv if you're watching

  • on YouTube after the fact.

  • Colton, you must have made some games by yourself.

  • Can we see them or play them?

  • They're on the games course, the cs50.edx.org/games.

  • I've probably started a million side projects that I've never finished.

  • But the CS50.edx.org/games, which I'll plug again--

  • CS50.edx.org/games-- they're more or less complete in that they are very

  • similar to, like, the classic games.

  • They're pretty robust, games like Mario and Zelda and Pokemon and Angry Birds.

  • Those give you a representation of some cool stuff.

  • I love how unsupervised AI and intelligent agents follow up

  • to the Machine Learning Stream.

  • Nick would be the guy to ask.

  • So I'll reach out to him.

  • Again, he's doing a stream next week on Friday on Linux commands.

  • So if you're eager to jump into the CLI and get

  • a little bit more comfortable with piping and ls and cd and rm--

  • rm dash rf slash--

  • don't don't actually write that into the command prompt.

  • But if you want a tutorial on all that stuff,

  • he's going to give us one on Friday, next Friday.

  • All right, everybody.

  • Thank you so much, again, for tuning in.

  • This was CS50 on twitch.

  • This was Unity 3D.

  • I will see you all next time on Monday with Kareem the Dream, some CI/CD.

  • Have a good night.

COLTON OGDEN: All right.

字幕と単語

ワンタップで英和辞典検索 単語をクリックすると、意味が表示されます

B1 中級

3D PONG IN UNITY FROM SCRATCH - CS50 on Twitch、EP.9 (3D PONG IN UNITY FROM SCRATCH - CS50 on Twitch, EP. 9)

  • 6 0
    林宜悉 に公開 2021 年 01 月 14 日
動画の中の単語