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
One set of pipes to dodge isn’t very fun. Now we’ll learn about Prefabs and how to use them to continuously spawn our pipes.
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
So we need to continuously spawn sets
of pipes for our player to fly through.
0:01
The issue here is once our pipes
reach our endpoint,
0:05
they're completely destroyed
and we lose any way of getting them back.
0:08
To save us from extra work,
I'd like to introduce you to prefabs.
0:12
Prefabs, or prefabricated game
objects, are essentially reusable game
0:16
object templates that can be stored
as assets in your project.
0:21
They allow you to create, configure,
and store a complete game
0:25
object with all its components,
properties, and child objects,
0:29
from which you can create
multiple instances throughout your scenes.
0:33
This also allows us to instantiate them
during runtime with our code.
0:37
So to keep ourselves organized,
let's create
0:41
a new folder in our Assets
folder and name it Prefabs.
0:43
Let's double-click into it.
0:52
Unfortunately, it's extremely difficult
to create a prefab.
0:54
First, we click and drag our game object
into our folder.
0:58
So let's take our entire pipes
object and drag it in.
1:01
And wait...
1:05
That's it. Super easy!
1:07
You can see it's now
appearing with blue text in our hierarchy,
1:09
signifying that this is a prefab instance.
1:12
Perfect!
1:15
So just so you know, if you ever need
to make changes to a prefab as a whole,
1:16
and not just a singular instance,
you can double click it
1:21
from your project window and it'll open it
up as its own personal editing space.
1:24
So you can make changes here
and those changes will automatically take
1:29
effect in every instance of this object
that you have in your scenes.
1:33
To get back, click this little back
arrow up at the top left here.
1:37
Alright, we've got a prefab.
1:42
Since these pipes are getting destroyed,
we can't add this continuous
1:44
spawning logic directly to them
because once they're gone, they're gone.
1:47
We need something that persists
in our scene to act as a manager
1:51
responsible
for spawning these pipes over time.
1:55
So in our hierarchy,
let's create a new game object.
1:59
And since this won't be anything
the player of the game will see
2:02
or interact with,
we'll just do an empty game object.
2:05
Let's name it Pipes Manager.
2:09
For my OCD,
I'm going to reset the transform.
2:13
And just as a personal
organizational preference,
2:16
I like to keep these kind of manager
objects up top in the hierarchy.
2:19
So I'm going to move it
right up beneath the camera, being careful
2:23
not to nest it as a child to the camera.
2:26
Let's go into our scripts folder,
2:30
create a new script,
2:33
name it PipesSpawner
2:37
and attach it to this game object.
2:43
Alright, let's open it up.
2:50
So, this may seem a little tricky
initially,
2:52
but it's an approach I end up using in
almost every single game I create.
2:54
And all things,
it'll get easier with repetition.
2:58
What we need is a timer.
3:02
And what we want
is to specify a length of time
3:04
that we want the game
to wait in between spawning our pipes.
3:07
We want to count down
from that length of time to 0.
3:11
When it hits 0, we spawn pipes and reset
3:14
the timer back
to our specified length of time.
3:17
So let's create a variable for the length
we want to wait.
3:20
Let's serialize it so we can adjust it
in the editor with SerializeField.
3:24
It'll be private.
3:29
We want this to be of type float.
3:30
Let's name it timeBetweenSpawns,
3:33
and let's give it a default value of 5f,
3:36
which will basically be 5 seconds.
3:39
Now, we don't want to subtract
from this variable
3:42
itself, as we'll need it
each time we reset our timer.
3:44
So let's create
another variable to be our actual timer.
3:47
This one doesn't need to be serialized,
3:52
so private float
and let's just name it timer.
3:54
We don't need to declare this
with a value here.
3:59
In Start, right when
the scene begins, we'll assign
4:01
the value of our time
between spawns to this timer.
4:04
So essentially, timer will be equal
4:08
to five seconds right away.
4:10
Now in Update, we want to subtract
time from it until it hits zero.
4:14
So let's say timer minus equals
Time.deltaTime.
4:18
This minus equals is shorthand for saying
4:23
timer equals timer minus Time.deltaTime.
4:26
Okay, now beneath this,
4:30
we'll check
if timer is less than or equal to,
4:34
adding
that safety net again of less than, 0f.
4:38
If this is
4:43
true, we want to spawn some pipes
and reset the timer.
4:43
I'll just add a comment for now.
4:47
And to reset the timer,
we can simply copy this line
4:49
from Start again.
4:52
timer equals timeBetweenSpawns.
4:55
For now, let's Debug.Log a message
5:00
to make sure it's working.
5:03
Okay let save and test it out.
5:08
Okay, we can see it's
5:22
logging every 5 seconds, and it's
incrementing this counter on the right.
5:24
This does seem a bit slow, though.
5:28
I'm going to change it
to 2 in the inspector.
5:30
Okay, so now
5:35
we need to actually instantiate
some pipes into the scene.
5:36
Back in the code,
we need a reference to our pipes prefab
5:39
so that our script knows exactly
what we're trying to instantiate.
5:43
Earlier, I mentioned
5:46
there are two common ways to reference
objects or components in Unity.
5:47
This is the second way.
5:51
Let's create a new variable.
5:54
Let's serialize it
with SerializeField, private,
5:56
And this is going to be of type
GameObject, with a capital G.
6:00
Remember, the lowercase
g is in reference to the game object
6:04
this script is attached to.
6:07
This is the class of type GameObject.
6:09
Let's name it pipesPrefab.
6:12
Let's save and go back to Unity.
6:15
You see now
6:19
we have this empty slot,
and it's looking for some game object.
6:20
Let's go into our Prefabs folder and drag
this Prefab into our slot here.
6:24
Awesome!
6:29
We could absolutely write all the code
we need to do this
6:31
right in this conditional, but
I think this is a good point to finally
6:34
create our own method
to keep things readable and clean.
6:37
So down below Update,
but still inside of our class's curly
6:41
braces, let's create a new method
called SpawnPipes, in Pascal case.
6:44
C sharp always wants your method names
to start with a capital letter.
6:49
As you see above with
6:54
Start and Update,
we also need to provide a return type.
6:55
These methods are using the void keyword
7:00
because they're not returning anything
to whatever method is calling them.
7:01
We don't need to return anything either,
so let's just write void.
7:05
Methods also require an access modifier,
7:09
but like our variables, they default to
private if not specified.
7:12
So these methods up here,
technically, are private this.
7:16
And my variables,
I always to write this to be clear.
7:20
That's up to you though.
7:23
So the Unity method we're
7:29
looking for here is named instantiate.
7:30
If we hover over it,
you'll see it's expecting an object,
7:33
a position, and a rotation.
7:36
Let's quickly go figure out where
we want to spawn these pipes.
7:38
I'm going to comment this out
so that there's no compiler errors
7:43
to hold us back. In VS Code,
you can do this quickly
7:45
by holding control or command on Mac
and hitting the forward slash key.
7:49
Or you can just type two forward slashes
at the beginning of this line.
7:53
Okay let's save it.
7:57
I think positive
8:07
13 on the x-axis is a great spot,
so let's use that.
8:08
Again, you can create
a serialized variable for this
8:12
to adjust it in the editor
and to prevent hard coding values in this.
8:14
But the destroy method we did earlier,
I'm not too worried about it
8:18
in this scenario.
8:22
Okay,
so what object do we want to instantiate?
8:26
Our pipes prefab.
8:29
Where do we want to instantiate it?
8:31
At a new vector3 at 13f 0f 0f.
8:33
Lastly,
what about this quaternion rotation?
8:42
We want quaternion.identity.
8:45
Quaternion.identity in Unity represents
a rotation
8:47
that does not change an object's
orientation.
8:52
It's equivalent to no rotation or a
rotation of zero degrees around any axis.
8:55
I'm going to be honest with you.
9:01
Quaternions are very complex, confusing,
9:02
and something that I'll never understand,
nor need to understand.
9:06
You know what, go ahead and pause me and
do a Google image search of quaternion.
9:10
It's okay, I'll wait.
9:14
Did you see it?
9:17
Yikes, right?
9:19
That's some real brain-explody
stuff right there.
9:20
Now, don't let this insanity here
hit you the wrong way.
9:23
All I remember is dot identity
when instantiating objects,
9:27
and I leave it at that.
9:30
We could similarly just write transform
dot rotation here,
9:32
and it'll basically give it
whatever rotation it has by default.
9:36
But seeing this quaternion word scared me
when I first started,
9:39
and you're going to see it out there
in the wild, so I just wanted to bring it
9:42
up. Alright,
now we need to call this method
9:45
when our timer hits zero.
9:48
I'll remove this log here too.
9:54
Perfect, let's see if it's working.
9:57
Great!
10:09
They're spawning, moving,
and getting destroyed all on their own.
10:10
This is starting to show promise.
10:14
Now, we need to randomize their Y position
a bit to give the players
10:16
some challenge and, well, fun.
10:20
We'll tackle that in the next
video. I'll see you there.
10:23
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