• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by dananddna · Aug 20, 2012 at 11:48 PM · destroy-clones

How to delete oldest of a series of instantiated objects

Hello, I have a script that instantiates a new object every time Fire1 is hit. I only want three of these clones present in the scene at a given time, so I set up a limit.

I was wondering how one would script it so that if you were to continue to create new objects after hitting that limit, the oldest/first clone would automatically be destroyed, so you would still only have only three objects present in the scene. How would you achieve this sort of continuous turnover?

Thank you!

 //Object to be instantiated
 var prefabToSpawn: Transform;
 
 //Current number of waypoints present
 var totalWayPoints: int;
 //One can only create 3 waypoints at a time
 var wayPointLimit: int = 3;
 
 function Update () {
 
     //if you press Fire
     if (Input.GetButtonDown("Fire1")){
         
         //if you haven't reached the waypoint limit yet
         if(wayPointLimit > totalWayPoints){
         
             //create a new waypoint
             Instantiate(prefabToSpawn, transform.position, Quaternion.identity);
     
             //add another waypoint to the total
             totalWayPoints++;
             }
     
 
     
     }
 
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by aldonaletto · Aug 21, 2012 at 12:18 AM

You could store each instantiated object in a circular list. When you're going to store a new object and the current position already has an object, delete it:

//Object to be instantiated var prefabToSpawn: Transform; //One can only create 3 waypoints at a time var wayPointLimit: int = 3;

// circular list: private var wayPointList: Transform[]; private var curPos: int = 0;

function Start(){ wayPointList = new Transform[wayPointLimit]; }

function Update () { //if you press Fire if (Input.GetButtonDown("Fire1")){ if (wayPointList[curPos]){ // if some object already in curPos... Destroy(wayPointList[curPos].gameObject); // delete it } //create a new waypoint and store it in curPos: wayPointList[curPos] = Instantiate(prefabToSpawn, transform.position, Quaternion.identity); //increment curPos in a circular fashion: curPos = (curPos + 1) % wayPointLimit; } } A better alternative would be to simply move the oldest object to the new position, instead of deleting it and creating a new one:

...
function Update () {
    //if you press Fire
    if (Input.GetButtonDown("Fire1")){
        if (wayPointList[curPos]){ // if some object already in curPos...
            wayPointList[curPos].position = transform.position; // just move it
        } else {
            // otherwise create a new waypoint:
            wayPointList[curPos] = Instantiate(prefabToSpawn, transform.position, Quaternion.identity);
        }
        //increment curPos in a circular fashion:
        curPos = (curPos + 1) % wayPointLimit;
    }
}
Instantiate and Destroy are heavy operations, thus this alternative is more efficient - but not always possible: you can only use it when the new object is exactly equal to the older one!
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Paulo-Henrique025 · Aug 21, 2012 at 12:19 AM

You can use a Queue to do that. If you have more than the max allowed objects you must Dequeue the first one and them Enqueue your new object.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class QueueSample : MonoBehaviour {
 
     public Queue<GameObject> queue = new Queue<GameObject>();
     
     // Update is called once per frame
     void Update () 
     {
         if(Input.GetKeyUp(KeyCode.A))
         {
             if(queue.Count < 3)
             {
                 queue.Enqueue(new GameObject("Created in: " + Time.timeSinceLevelLoad.ToString()));
             }
             else
             {
                 Destroy(queue.Dequeue());
                 queue.Enqueue(new GameObject("Created in: " + Time.timeSinceLevelLoad.ToString()));
             }
         }
     }
 }
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Kryptos · Aug 21, 2012 at 08:39 AM 1
Share

This looks pretty fancy. But unfortunately this is bad for memory: Queue is not very efficient and creating/destroying will lead to memory leak or expensive GC computation.

I would recommend using the solution given by Aldo or Dave.

avatar image Paulo-Henrique025 · Aug 21, 2012 at 12:31 PM 0
Share

They are re-implementing a Queue, and how does creating and destroying objects will leads to a memory leak?

avatar image Kryptos · Aug 21, 2012 at 12:46 PM 0
Share

Calling GameObject.Destroy removes the object from UnityEngine management but there might be some references elsewhere that are not set to null. Then GC cannot completely release the memory.

Plus creating/destroying at medium or high rate is bad because of memory fragmentation. Or you will have to call GC explicitly and frequently. But that way all objects will move in 3rd generation and stay longer in memory.

Conclusion: it is better/safer to use some pool mechanism and reuse as much as possible the same set of objects.

avatar image Paulo-Henrique025 · Aug 21, 2012 at 02:59 PM 0
Share

None of the others implementations mentioned pooling, which is the correct way to go for almost everything, enemies, bullets and spell effects. They both used Instantiate() and Destroy(), so all our responses are fated to memory leak/GC spikes.

avatar image aldonaletto · Aug 21, 2012 at 11:35 PM 1
Share

Actually, the second alternative in my answer is pool based: the objects are instantiated only while the circular list isn't full, then they start to be reused (moved to the new position ins$$anonymous$$d of deleted and recreated). I offered both alternatives because the pool only works when the objects are identical - if an object is modified during its life, using it as a brand new one may become too complicated (it must be restored to the initial settings).
The fixed size circular list is a simple and fast way to handle this case, but it's interesting to know the Queue alternative - it's a FIFO (first in, first out) structure like the circular list, but can have variable size.

avatar image
0

Answer by DaveA · Aug 21, 2012 at 12:19 AM

  1. You could pre-instantiate 3 things, then just use them. Put them into an array and cycle the index of that array. With so few you could even assign them manually in the Inspector

  2. When you instantiate, have a global counter that adds one. In the OnDestroy function on a script attached to each spawnee, decrement that count. Don't spawn if count is three.

  3. There's more but this should get you started

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by dananddna · Aug 23, 2012 at 08:08 PM

Thank you all for your input!

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Paulo-Henrique025 · Aug 23, 2012 at 08:11 PM 0
Share

We are here to help but please don't comment creating a new answer.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to Destroy Individual Instance of an Object 3 Answers

Missile GameObject being destroyed automatically! 1 Answer

Difference between Destroy and Destroy immediate (In this case). 2 Answers

Trouble Destroying Instantiated Prefab in Array 2 Answers

touch and destroy clone object with specific color 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges