3
\$\begingroup\$

I am new to unity and the other day I was wondering that it would be useful if I could instantiate some objects in my game scene and, as they get instantiated, make it so that they get automatically deleted after a period of time.

I thought about automatically adding a Destroy script to them so that they could be deleted after a period of time using:

Destroy(Gameobject, time);

I'm not sure that's what I need, and if it is I don't know how I'd go about it.

How could I make it so that my objects get automatically deleted after some time, in the context that I'll have a lot of them?

\$\endgroup\$
  • 2
    \$\begingroup\$ Prefab, is the way to store sort of blue-print of your object. Then you can easily instantiate that prefab (your gameobject with attached script). Other way is to Instantiate an object then manually add the script through newObject.AddComponent<DestroyScript>();. For further details for prefabs, have a look at this link \$\endgroup\$ – Hamza Hasan Sep 7 '16 at 13:38
2
\$\begingroup\$

It is fairly easy to add any component to a game object on instantiation, including classes, using GameObject.AddComponent<T>(). If your script is good to go from the start, you can do this inline. If you need to do anything with your script after adding it, you can create references as you instantiate.

For further clarity, note that I say classes instead of scripts. When you create a script, a class is created inside that script with the same name. When you drag the script on to an object in the inspector, this is the class that is added. This is not a coincidence. While a compiler will not complain if you proceed to change the name of that class, Unity will complain that it can no longer find the original class, and start throwing errors. What you may not realise is that you are free to create additional classes after the first, within the same script file. While you can not simply "drag and drop" these additional classes on to an object via the Unity inspector, you can still add them to a game object using AddComponent<>.

Adding a class inline

Setting it up inline is quicker, but it leaves us with no reference to the game object nor the object destroyer we have created. If they are designed to run by themselves, without need of setup once they have been instantiated, we are fine. If you should need to reference either, later, read below for creating references.

using UnityEngine;

public Class ObjectCreator : MonoBehaviour
{
    public GameObject blueprint;

    public void CreateNewGameObject()
    {
        Instantiate<GameObject>(blueprint).AddComponent<ObjectDestroyer>();
    }

}

public Class ObjectDestroyer : MonoBehaviour
{
    public void Destroy(){...}
}

Adding and referencing the class

Sometimes just creating the class won't cut it. The same may go for your instantiated game object. If we create them inline, as the example above shows, we do not create any reference for further manipulation. We might want to create a reference to the game object we make for later use, or even add it to a list of all game objects we have created from the same class. Likewise, we may want to grab a local reference to the added ObjectDestroyer class, to perform additional setup.

You are free to only create a reference to the game object, or only create a reference to the class you are adding to the game object. With only referencing the game object, you can still create it inline, like the above example.

using System.Collections.Generic;
using UnityEngine;

public Class ObjectCreator : MonoBehaviour
{
    public GameObject blueprint;
    public GameObject lastCreatedObject;
    public List<GameObject> allCreatedObjects;

    public Start()
    {
        /* Lists are like arrays, but more complex. They allow    *
         * you to store a list of data like an array, but         *
         * provide additional features, such as the ability to    *
         * add more data on the fly without potential issues that *
         * arrays may cause. Just make sure that you have         *
         * using System.Collections.Generic; at the top, and      * 
         * initialise it in your Start() function.                */
        allCreatedObjects = new List<GameObject>();
    }

    public void CreateNewGameObject()
    {
        // Single reference
        lastCreatedObject = Instantiate<GameObject>(blueprint);
        // Adding to a list
        allCreatedObjects.Add(lastCreatedObject);
        // Adding the ObjectDestroyer class w/ reference
        ObjectDestroyer script = lastCreatedObject.AddComponent<ObjectDestroyer>();
        // Adjusting the ObjectDestroyer on our GameObject
        script.countdownTimer = 5f;
    }
}

public Class ObjectDestroyer : MonoBehaviour
{
    public float countdownTimer;
    public void Destroy(){...}
}

I referenced my GameObject, but not my class! Oh Noeeeeeee!

Of course, you may find that you need to access your ObjectDestroyer attached to the game object, but did not create (or otherwise lost) a reference to it. In similar fashion to the above examples, we can use GetComponent<>() to grab a reference after the initial creation.

using UnityEngine;

public Class ObjectCreator : MonoBehaviour
{
    public GameObject blueprint;
    public GameObject gameObject;
    public ObjectDestroyer myObjectDestroyer;

    public void CreateNewGameObject()
    {
        gameObject = Instantiate<GameObject>(blueprint).AddComponent<ObjectDestroyer>();
    }

    public void ReferenceDestroy()
    {
        // This works if we need to create a reference for later...
        myObjectDestroyer = gameObject.GetComponent<ObjectDestroyer>();
    }

    public void PostponeDestroy()
    {
        // But this works if we only need the reference for one call.
        gameObject.GetComponent<ObjectDestroyer>().Postpone();

        // Actually, you could use this for more than one call, but
        // anything more and it will be more efficient and easier 
        // to store an actual reference, locally, first.
    }
}

public Class ObjectDestroyer : MonoBehaviour
{
    public void Postpone(){...}
    public void Destroy(){...}
}

One last thing about Types, since you will run into it

Since you will run into the T type in using the above examples, I felt it would be wise to provide a quick explanation, to avoid potential confusion. When you see a T specified (for example, GetComponent<T>() or List<T>()), it simply means that that method or class is generic. That means that you can replace the T with a variety of other types, and it will work.

It is more complicated than that, but for a beginner, all you need to know is that GetComponent<T>() can be written as GetComponent<Collider>() if you want to retrieve an attached collider, or as GetComponent<Rigidbody>() if you want to retrieve an attached Rigidbody, or even as GetComponent<DooHickey>() if you want to retrieve an attached class called DooHickey.

There are limitations to how you can use generics, but in the general sense the above examples should not lead you astray. Just know that if you try GetComponent<T>() and the game object does not contain such a component, it will return null.

\$\endgroup\$
  • \$\begingroup\$ wow that was more than i needed to know. thanks for the extra info much appreciated ^_^ \$\endgroup\$ – Mohit Saxena Sep 7 '16 at 14:57
1
\$\begingroup\$

Simply attach this script to your gameObject / prefab, and set the lifeTime variable to how long you want this object to live:

using UnityEngine;

public class AutoDestruct : MonoBehaviour {

    // Lifetime of gameObject
    // Destroy this gameObject in this many seconds after being instantiated
    public float lifeTime = 10f;        

    void Start() {
        GameObject.Destroy(this.gameObject, lifeTime);
    }

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.