Instantiating and Casting
Using C# through Unity, you will at some point, need to create (or instantiate) new GameObjects; this can be done in several ways; the first way could be to call the constructor of the class GameObject as in the next code.
GameObject g = new GameObject ();
Another way, is to use the built-in function called Instantiate. So, for example, let’s say that we want to instantiate bullets, that we have created as prefabs; we could use the following code:
public GameObject bullet; void Start () { GameObject g3 = (GameObject)(Instantiate (bullet, transform.position, Quaternion.identity));
In the previous code:
- We instantiate a new object and save it in the variable g3.
- We use the method called Instantiate to create a new Object; this method takes three parameters: an object, a position and a rotation.
Now, the important thing to notice here is that the method Instantiate returns a variable of type Object and NOT GameObject; however, when we create the variable g3, we need to make sure that, because the type of g3 is GameObject, that what is returned by the method Instantiate is also of type GameObject; this is the reason why we use the code (GameOBject) just before the keyword Instantiate: this is called Casting; by casting, we have converted the type returned by the method Instantiate from Object to GameObject.
You will obviously use Csting in other occasions; however, when using the Instantiate method, we will need to use casting.
Note that casting can be done using the keyword as, as described in the following code:
GameObject g3 = Instantiate (bullet, transform.position, Quaternion.identity) as GameObject;
In the previous code we use the key words as GameObject to specify that the Object returned by the method Instantiate will be casted as a gameObject.
Destroying
As we have seen previously, it is possible to instantiate objects using the Instantiate function; and it is also possible to destroy or to deactivate an object accordingly.
To destroy a specific object, you can use the Destroy function and destroy an object either instantaneously or after a specified delay, as illustrated in the next code snippet.
void Start () { Destroy (gameObject, 5); Destroy (GameObject.Find ("Cube"); }
In the previous code:
- We use the function Start.
- We destroy the object linked to this script with a delay of 5 seconds; this could be used for example, for bullets or any objects that would typically disappear a few seconds after its creation. Note that we use gameObject with a lowercase g as we refer to the object linked to this particular script.
- In the second line, we look for an object called Cube and we destroy it instantaneously.
There are also times where it is good not to destroy an object, but instead, to deactivate it; for example, you may want an object to appear in the scene only after the player has collected some items; this can be useful for treasure hunts, or adventure games based on exploration; in this case you would typically do the following:
- Add the object to the scene manually (possibly). While you could do this through code, doing this manually has the advantage, especially for bulky object, to know exactly where and how they will fit in the scene. Of course, if you had to do this for several objects, a script-based Instantiation may be more efficient.
- Make sure the object is activated in the Scene view (by checking the Inspector)
- Create a reference to the object in your script before it is deactivated.
- Deactivate the object from your script at the start of the scene.
- Reactivate the object from your script when an event has occurred (e.g., player collected all relevant items).
public class DestroyAndDeactivate : MonoBehaviour { GameObject g; bool collectedItems; void Start () { g = GameObject.Find ("Cube2"); g.SetActive (false); } void Update () { if (collectedItems && ! g.activeInHierarchy) g.SetActive (true); }
In the previous code:
- We declare the variable g that will be used as a reference to the object we need to hide/deactivate.
- We also declare a Boolean variable that will be used to know whether the necessary items to activate the object have been collected.
- Then, in the function Start, we find the object called Cube2 and link it to the variable g.
- Through the variable g, we deactivate the object Cube2.
- In the Update function, we then check that the object Cube2 is not active; we also check that the items have been collected; if this is the case, then we activate the object Cube2.
So this approach is very useful when you want to reveal or unveil some items; and you can also, as we have seen earlier, destroy objects either instantaneously or after a delay.
Deactivating
This being said, there are cases when you may want to make sure objects (and any related component or children) are not destroyed when transitioning between scenes. You see, when you load a new scene, by default all the objects in the previous scene are destroyed before the objects from the new scene are instantiated. So, there are cases
In this case, you could use the following snippet and attach the corresponding script to the object that you’d like to keep between scenes.
void Awake() { DontDestroyOnLoad(transform.gameObject); }
In the previous code:
- We implement the method called Awake that is usually called when the script is loaded; this method is called only once in the lifetime of the game.
- We then use the method DontDestroyOnLoad to ask Unity to keep this particular object and its children.
- The method Start in not used in this case, as it is often called every time a scene is starting; however, in our case, we just want to call it once in the game, and Awake is therefore more appropriate.
You could this method when you want to create a game manager that should be present in (accessible from) any scene, for example.