Learning Unity — Instantiating And Destroying GameObjects Dynamically
Imagine you were developing a video game of your own. Chances are you would want your game to periodically generate in-game objects, such as enemies, player pick-ups, obstacles, etc. In Unity scripting, this is known as instantiation.
Conversely, you would also want these in-game objects to go away at some point. For example, when an enemy has been defeated by the player. This is known as destruction.
In this article, I am going to demonstrate a very simple example of instantiating and destroying an object using Unity scripting.
To begin, we need to create two GameObjects. The first will be a simple 3D object of some kind — a sphere or cube is fine. Anything that will be clearly visible. Feel free to add a Material to the object if you want.
The other GameObject we need is just an empty object. I recommend renaming this object to something that makes sense to you. The purpose of this object is to house all of the script logic for this example, so I named it “Controller”.
The next thing to do is to make our 3D object into a prefab. This can be done by simply dragging the object to the Project window. Having a folder specifically for your prefabs is a good practice (you can see I have already done that in the above picture). Once the prefab is created, go ahead and delete the original object.
After the prefab has been created, we next need to create a script for our empty object (the “Controller”). Right click in the Project window and find the command to create a C# script. Give the script an appropriate name (ideally the same as your empty object). Similar to with the prefabs, having a folder dedicated to your scripts is a good practice (note the picture above).
Once your script has been created, within the Unity editor drag it to the empty object. This will attach the new script to this object. Once that is done, open the script in the editor of your choice. First thing we will need in the script is two class level variables. One will refer to the prefab we have already created and the other will refer to the object we are going to instantiate and destroy. Both are of type GameObject.
Notice that the prefab object has the “SerializeField” attribute attached to it. Though there are other ways to have the prefab object variable find the correct object to reference, SerializeField allows us to do it very easily from within the Unity editor.
To do this, click on the empty object in the Unity editor. You should now see in the script component a field with a name taken from the variable name in the script. In my case, that new field’s name is “Object Prefab”.
Note how the field tells you it expects a Game Object. With this window open, drag the prefab object into this field and then the variable in the script will refer to the prefab object.
With that done, now we want to make this script able to actually generate the prefab object into the game. To make sure we only create new objects when we want to, here is a small snippet of code to provide for user control. When put into the Update method of our script, any code put into this if statement will only run when the space key is pressed.
Within this code block we now will enter the code for instantiating game objects. That code is just one line: Instantiate(_objectPrefab);.
If you now return to the Unity editor, allow the script to compile, and then start the game, you will find that a 3D object matching your prefab will be created every time you press the space key. It may appear that only one is being created, but in actuality they are all being generated in the same position so it only appears that there is one.
In the picture above, notice that there are five Sphere objects in the Hierarchy window. They were all created using our script.
Now we want to destroy our generated objects, and this is where our other class level variable (_object) comes into play. When you use the instantiate method, it returns a GameObject. As we’ve already demonstrated, you don’t need to keep track of this GameObject, but if you want to destroy you will need to. So now we are using our other GameObject variable, _object, to store a reference to the instantiated GameObject. With that reference, you can then destroy the object with the following line of code: Destroy(_object);.
Now if you run this code, it might appear to be doing nothing at all, but the truth is that it has created and destroyed an instance of our 3D object. It has just done both virtually instantaneously. So now let me just adjust this code slightly with an if/else statement so that our work can be noticed.
So with this final version of the script, we are still waiting for the user to press the space key, but once it has been pressed we do a check. If the GameObject variable _object is null, then we will instantiate a copy of our prefab and assign the reference to _object. Otherwise, we will destroy _object.
The variable _object is null by default, so the first press of our space key will create our prefab object in the game and _object will be a reference to that object. When space is pressed again, _object refers to our recently created object so it will be destroyed. When the object is destroyed, the reference becomes null again so we are back to where we started.
In the next article, we will see how we can make use of time in Unity. Until then, good luck and happy coding!