In part 3 of this tutorial series we created the PlayerMovement script and made the Player move in the level.
In this part of the tutorial we are going to create the Knifes and make them fall from the sky so that the Player can start avoiding them.
Preparing The Knife Game Object
The Knife is falling down which is the expect behavior because we attached a Rigidbody 2D on him. But the Knife is too big, and it is not rotated correctly so it falls on the side. I am going to change the size of the Knife and rotate him so that the sharp edge of the Knife is facing down.
These are the settings for the Rotation and Scale property of the Knife game object:
You can ignore the Position property as that will change anyways when the Knife starts moving down.
I am also going to change the size of the Knife’s Box Collider 2D as the collider is covering too much of the Knife at the moment. I only want the collider to cover the sharp edge of the knife.
These are the values for the new size of the Box Collider 2D of the Knife:
So now when we run the game we have this:
The Knife Prefab
One of the most important concepts in Unity game development is something called a Prefab.
And a Prefab is a way for us to save game objects along with all the modifications we did to them.
If we delete the Knife game object from the Hierarchy tab, we will have to create a new one and go through all the set up we already did e.g. attach a collider, attach a rigid body, adjust their values and so on.
But if we create a Prefab out of the Knife then we can just drag that Prefab and we have the saved Knife game object with all of its components.
But how do we create a Prefab?
First inside the Project tab and Assets root folder, Right Click -> Create -> Folder. Give the new folder name Prefabs.
If this was a more complex game where we have Prefabs of all kinds such as different Players, Enemies, Obstacles, Pick Up Items and so on, we would create sub-folders to group all Prefabs that go together.
Now open the Prefabs folder and drag the Knife game object from the Hierarchy tab in the Prefabs folder:
This will create a Prefab out of the Knife game object and you will see the Knife Prefab inside the Prefab folder:
We can now delete the Knife game object from the Hierarchy tab and drag the Knife Prefab in the same tab and it will have all the components and properties that we already set up:
This is the power of Prefabs. And this is not the only purpose for what we can use them.
Prefabs are an essential part of our game logic, because in order to make the Knifes fall from the sky, we are going to use the Knife Prefab and create copies out of it.
Editing And Saving Changes To The Prefab
To apply the new change to the original Prefab, we had to select the Knife Prefab in the Hierarchy tab, and click on the Overrides button at the top right corner in the Inspector tab:
And then click on the Apply All from the new drop down list so that the new change will be applied to the original Knife Prefab stored in the Prefabs folder:
This what we need to every time we add a new change to a Prefab in the Hierarchy tab and you want that change to be saved on the original Prefab.
This also includes any changes you make to components such as resizing the collider that is already attached on the Prefab, that change will not be applied to the original Prefab until you override it by clicking on the buttons mentioned above.
I encourage you that you take 5 minutes now and experiment with this concept so that you will memorize it because it is really important as we will be using it a lot in our development.
Removing Components From Game Objects
And from there click on the Remove Component from the drop down list.
Of course, for this change to apply to the original Knife Prefab stored in the Prefabs folder, we need to override the changes by clicking on the Overrides -> Apply All.
The Knife Spawner Script
In order to make the Knifes fall from the sky we need to create a script that is going to do that for us.
Inside the Assets -> Scripts folder, Right Click -> Create -> Folder and give it a name Knife Scripts.
Inside Knife Scripts folder Right Click -> Create -> C# Script and give it a name KnifeSpawner.
Inside the Hierarchy tab, Right Click -> Create Empty and give it a name Knife Spawner, after that attach the KnifeSpawner script on the Knife Spawner game object in the Hierarchy.
Since the KnifeSpawner script is going to spawn the Knifes every X amount of seconds, the first we need is a reference to the Knife prefab, because we are going to create copies of that Prefab.
In the KnifeSpawner script above the Start function declare the following:
[SerializeField]
private GameObject knifePrefab;
If you select the KnifeSpawner in the Hierarchy tab and take a look in the Inspector tab you will see this:
You see that we have an empty field for the knifePrefab variable and inside that field we see None which denotes that we didn’t attach any game object.
Why is this important?
Now that we dragged the Knife Prefab in the knifePrefab empty field in the Inspector tab, we have a reference to the Knife Prefab and we can create as many copies of the knife prefab as we want.
To create a copy from a Prefab, we use the Instantiate function. In the KnifeSpawner script add the following line of code:
void Start()
{
Instantiate(knifePrefab);
}
Remove any copy of the Knife game object from the Hierarchy by selecting the Knife game object and pressing the Delete key on Windows, on Mac CMD + delete key. Or you can Right Click -> Delete on the Knife game object.
Now run the game:
As you can see from the video, as soon as we started the game a Knife was spawned in the scene and it fell down.
This is because of the Instantiate function we used in the KnifeSpawner.
Adding Icons To Empty Game Objects
This is not what we want for our game because if we use Instantiate like this, the Knife will always be spawned at the same place in our game.
Because of that we need a X and Y position where we are going to spawn the Knife game object.
For the Y position we can use the Knife Spawner Y position, we just need to move it above the view port of the Camera.
Because the Knife Spawner is an empty game object and thus it’s invisible in the Scene, I am going to show you a way how we can add an icon to an empty game object so that we can see where it is in the Scene.
Select the Knife Spawner in the Hierarchy and press the cube icon in the Inspector:
When you click on the cube, from the list select any icon which is either a label or a dot, and select any color of the label or the dot:
I am going to select the red label for the Knife Spawner and this is how it looks like in the Scene tab:
- X: 0
- Y: 6
- Z:0
[SerializeField]
private float min_X = -2.6f, max_X = 2.6f;
public class KnifeSpawner : MonoBehaviour
{
[SerializeField]
private GameObject knifePrefab;
[SerializeField]
private float min_X = -2.6f, max_X = 2.6f;
private Vector2 knifePos;
void Start()
{
SpawnKnife();
}
void SpawnKnife()
{
knifePos.y = transform.position.y;
knifePos.x = Random.Range(min_X, max_X);
Instantiate(knifePrefab, knifePos, Quaternion.Euler(0, 0, 90));
}
} // class
- X = 0;
- Y = 0;
- Z = 90;
Now we can test the game:
Spawning Infinite Knifes
[SerializeField]
private float minSpawnTime = 1f, maxSpawnTime = 3f;
void Start()
{
Invoke("SpawnKnife", Random.Range(minSpawnTime, maxSpawnTime));
}
The Invoke function spawned a new Knife after a random time interval, but it only spawned one Knife, what is the issue here?
Well the issue is that we are calling the Invoke function only once hence it has spawned only one Knife.
There are two solutions for this.
The first solution is to call the Invoke function again within the SpawnKnife function:
void SpawnKnife()
{
knifePos.y = transform.position.y;
knifePos.x = Random.Range(min_X, max_X);
Instantiate(knifePrefab, knifePos, Quaternion.Euler(0, 0, 90));
Invoke("SpawnKnife", Random.Range(minSpawnTime, maxSpawnTime));
}
As you can see, calling Invoke over and over again will create infinite number of Knifes that are being spawned.
The second solution is to use InvokeRepeating function which takes three parameters.
- The first parameter is the name of the function it will call
- The second parameter is a float which represents the time InvokeRepeating will be called for the first time
- And the third parameter is a float which represents the time InvokeRepeating will be called after that
InvokeRepeating("SpawnKnife", 1f, 2f);
InvokeRepeating("SpawnKnife", Random.Range(minSpawnTime, maxSpawnTime), Random.Range(minSpawnTime, maxSpawnTime));
void SpawnKnife()
{
knifePos.y = transform.position.y;
knifePos.x = Random.Range(min_X, max_X);
Instantiate(knifePrefab, knifePos, Quaternion.Euler(0, 0, 90));
}
And inside the start function call InvokeRepeating:
void Start()
{
InvokeRepeating("SpawnKnife", Random.Range(minSpawnTime, maxSpawnTime), Random.Range(minSpawnTime, maxSpawnTime));
}
Now we can test the game:
Where To Go From Here
In this lecture we learned about Prefabs, how we can create copies of Prefabs from our code and how we can repeatedly execute one function with the help of the Invoke function.
1 thought on “Creating Your First Unity Game – Rainy Knifes Part 4: Knifes, Prefabs And Spawning Obstacles In The Game”
I learn from this vlog a lot. saw many tutorials but this blog help me lot…thanks awesometuts..