Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Unity Basics!
You have completed Unity Basics!
Preview
Letβs give the player some challenge and create our pipe obstacles and get them moving across the screen.
Unity 6 Documentation
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
Okay, we got our player moving,
now it's time to start
0:01
adding the challenge to our game.
0:03
If we look back at our completed preview,
we see that these obstacles consist of
0:05
two pipes, one on top, and one on bottom,
with a gap in between them.
0:09
Also, they both move together as one, so
0:14
we know they need to stay connected
somehow.
0:16
So let's create a new square game object,
0:20
and name it bottom pipe.
0:27
I'll reset the transform,
0:31
and I'll use the shortcut T
to get our Rect tool
0:34
and scale its Y a bit.
0:37
We know that we're going
to want our player
0:41
to collide with this object,
so let's add a box collider 2D.
0:43
Now, instead of creating the top
one from scratch,
0:49
we can simply select
this bottom pipe in the hierarchy
0:51
and duplicate
it with Command or Control D.
0:54
Let's rename it to Top Pipe,
0:59
and get the Move tool with the shortcut W.
1:03
Let's move it up a bit
so there's a close enough gap
1:06
for the player to kind of arch through.
1:08
Again,
we can fine tune the sizes and gaps later.
1:13
Now, to keep these objects
connected in a sense,
1:16
we can nest them as children
to another game object.
1:19
Let's do that.
1:22
Now, because of my OCD,
I'm going to move the bottom
1:23
pipe to the bottom, and then I'll hold
shift and select both pipes.
1:26
Let's right click and select create
1:31
empty parent.
1:33
Now they're both sibling game objects.
1:37
Let's name
this parent object pipes, plural.
1:39
Now if we select this parent
and move it on its X axis,
1:43
you'll see they both move along with it,
1:46
staying in their places
relative to each other. Perfect!
1:48
Since we
1:52
don't want gravity and physics
for these, we'll directly
1:53
manipulate its transform's position
in our code to move them.
1:56
And we know that we'll want to manipulate
the transform of this parent object,
2:00
not the individual pipe objects within it,
so that they move together.
2:04
So let's head into our scripts
folder and create
2:08
a new one.
2:11
Let's name it PipesMover.
2:16
Let's attach it to the parent pipes
2:20
object and open it up.
2:25
We want this to continuously move
2:30
left across the screen, so again,
using Update is a perfect approach.
2:32
Also, as I mentioned earlier,
since every game
2:36
object will have a transform component,
we don't need to get a reference to it
2:39
like we had to with the
Rigidbody on our player earlier.
2:43
So let's go straight into Update
and type transform.
2:46
Make sure you use a lowercase t.
2:49
If it's capitalized, it will use it
as the data type, the transform class,
2:51
not a reference
to our transform component.
2:55
Let's type dot,
and the property we want is position.
2:58
The transform's position is of type
Vector3.
3:03
A Vector3 in Unity is a structure
that represents a point or direction
3:06
in 3D space using three float
values for x, y, and z coordinates.
3:10
Remember our transform position in the
inspector window has an x, y, and z value.
3:16
Even though we're working in 2D, sometimes
3:21
we still need to specify things
as a Vector3 like this.
3:23
So let's type equals,
and what we want to do is every frame,
3:27
so every time update is called, assign
this a new Vector3 value,
3:31
bringing it further to the left
slightly each time.
3:35
We do this by typing the new keyword,
followed by Vector3
3:39
and a set of parentheses.
3:43
Within the parentheses,
we need to specify the three
3:46
float values for each coordinate,
but we want it to be relative
3:48
to wherever it currently is
when this frame started.
3:52
So we can type transform.position.x.
3:56
I'm going to copy this,
4:02
add a comma,
4:06
and paste
4:09
this for the y, changing that x to a y,
4:10
and and the same for the Z value.
4:13
This is telling Unity to just get whatever
the current transform positions
4:18
are and just use them again
here, essentially not changing them.
4:22
So as is, this won't affect anything.
4:25
Right now, we only want to move this
on its X axis, so let's get back to that.
4:28
Remember, these are float values,
so we can perform math operations on them.
4:33
And if you remember,
when moving objects to the left in Unity,
4:38
the number gets smaller,
hits zero and goes negative.
4:42
So we know we want to use subtraction
but what do we want to subtract from it?
4:45
Well this is what we get to decide
as how fast we want to move them.
4:50
The more we subtract the faster
they'll move across the screen.
4:54
This sounds like
4:57
another situation where it'll be
nice to have this available in the Unity
4:58
editor to easily adjust,
so let's create a variable for it.
5:02
Up top,
let's create a new serialized field,
5:06
private, float, and call it moveSpeed.
5:11
We can give it a default value of say 10f.
5:15
Now we can say
5:22
transform.position.x minus move speed.
5:23
Let's save this and see what happens.
5:28
Wow, it moved so fast
I didn't even see it!
5:35
This is because of how many frames
are running per second.
5:39
Now we could change this move
speed value to something insanely small.
5:43
But there's another hidden issue arising.
5:47
Everybody's
machine runs at different speeds.
5:50
Let's say I have an older laptop,
5:53
and it's going to run this game
at a wimpy 30 frames per second.
5:55
But my friend has a brand new high-end
desktop.
5:58
It's going to run this game at 150 frames
per second.
6:02
His pipes are going
to move much faster than mine,
6:05
because this update method is getting
called way more times per second.
6:08
Let's go back to our code to fix this.
6:12
After we
6:15
subtract move speed from our current
x position,
6:15
let's also multiply this by Time
with a capital T,
6:18
dot deltaTime.
6:21
Time.deltaTime is the
interval, or time, in seconds
6:25
from the last frame that completed
to the current one in this Update call.
6:29
So you can imagine that
the time in between frames
6:33
is an extremely small fraction
of a number.
6:36
It'll be different on different machines.
6:39
It will even be different per
frame on the same machine, as
6:41
things aren't always super consistent.
6:45
So, due to the order of operations,
this code is going to multiply our move
6:47
speed by this tiny number first,
then subtract it from our X position.
6:52
It'll be slightly different each frame,
but what this will do is keep things
6:57
consistent across different machines
for a smooth experience for everyone.
7:00
Let's save this and try it out.
7:05
Much better. It's still a bit fast
for my taste.
7:12
I'm going to stop this and change
my moveSpeed to 5. Cool.
7:15
Now no need to follow me here
but I'm going to dock my game window
7:23
to the side again.
7:26
If we play again
7:29
and watch the scene window, we'll see that
these pipes never really go away.
7:30
They just keep moving left forever.
7:34
Now with this, eventually,
there are going to be
7:36
a lot of unused pipes
moving along taking up processing power.
7:38
So what we want to do is destroy them
once they're off the screen.
7:43
Let's find a position that will work to do
this.
7:47
Let's select the pipes object, use
the move tool with W, and slide it over.
7:49
I think negative 13 will work great.
7:55
Let's go back to our code.
7:59
So after we move our pipes,
we want to check on every frame
8:02
if our x position is negative 13,
or whatever number you decided on.
8:06
You can also make this
a serialized variable
8:11
and adjust it in the editor,
but I'm not too worried about this one.
8:13
As long as it's off the screen,
it works for me.
8:17
So below our movement code,
let's write a conditional.
8:20
if transform.position.x
We could just put in equals,
8:24
but it's generally a safe practice,
if you're subtracting, to check
8:30
if it's less than or equal to negative 13,
or whatever number you chose.
8:34
Just in case things are moving fast
and something slips
8:38
through the cracks, missing the very frame
it hits our number, we're safe.
8:41
So if this is true,
8:46
we want to destroy with a capital D,
and in the parentheses
8:47
we write game
object, lowercase g, uppercase O.
8:51
With a capital G, again, it's going to
think we're talking about a data type.
8:55
But with a lowercase g,
8:59
this is referencing the game object
that this script is attached to.
9:01
And since our individual pipes
are children
9:05
objects to this object,
those will also be destroyed.
9:07
Let's save and test it out.
9:11
And there it goes,
completely deleted from our scene.
9:21
And don't worry,
if we press stop, they'll come back.
9:24
So we've got our pipes moving.
9:29
But getting our player to fly through one
set of pipes makes for a very fast game.
9:30
So in the next video,
9:35
we'll learn how we can
continuously spawn sets of pipes for
9:36
the player to fly through.
9:39
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up