- Home /
How to determine and delete the oldest instantiated object?
I am new to unity and programming.
I am creating a waterfall of letters that is destroyed upon typing the corresponding letter. But if there are multiple instances of a letter, every letter of that type is destroyed. How can i track and delete only the oldest one?
I am not looking for complete code, just a point in the right direction, I have looked into List and arrays but I can't wrap my head around how to.
Answer by Bunny83 · May 04, 2013 at 10:53 PM
Well, it's pretty easy. Basically there are two ways:
time-based (so each object lives for a certain amount of time eg. 5sec)
count-based (there are only a certain number of objects allowed.)
For a lifetime limitation all you need to do is call Destroy right after you Instantiated the object but make sure you provide a timeout value:
// C#
float timeToLive = 5.0f;
public Transform CreateObject()
{
Transform clone = (Transform)Instantiate(prefab);
Destroy(clone.gameObject, timeToLive);
return clone;
}
For a count limitation, just add your objects to a List and check if the list count is larger than your desired threshold and simply destroy the first object in the list (and remove it) until the count is within the desired limit:
//C#
int maxObjCount = 20;
List<Transform> objs = new List<Transform>();
public Transform CreateObject()
{
Transform clone = (Transform)Instantiate(prefab);
objs.Add(clone);
while(objs.Count > maxObjCount)
{
if(objs[0] != null)
Destroy(objs[0].gameObject);
objs.RemoveAt(0);
}
return clone;
}
edit
Ok, if you have a stream of different letters and want to destroy the oldest letter "X" there are also several possibilities. One way is to hold a List for each "letter type" in a dictionary for example. That way you can easily access the "correct list" for a certain letter. In this case you need to put new letters in the "correct" list.
Another way would be to have only one list which makes the bookkeeping of the objects simpler but the searching a bit more complicated. This is probbly the easiest way. Even with 1000 letters on screen it's no problem too search through 1000 objects since you only do this when the user presses a button.
To identify the letter-type of an object you could simply rename the cloned object so it's name reflects it's letter:
// To create an object
// C#
void CreateLetter(string aLetter)
{
// If you have seperate prefabs you have to select the right one for "aLetter" here
Transform clone = (Transform)Instantiate(prefab);
clone.name = aLetter;
objs.Add(clone);
}
// To remove the first letter
// C#
void RemoveLetter(string aLetter)
{
for(int i = 0; i < objs.Count; i++)
{
if (objs[i].name == aLetter)
{
Destroy(objs[i].gameObject);
objs.RemoveAt(i);
break; // This is important to stop the loop once the first is found
}
}
}
I have implemented a lifetime limit already. $$anonymous$$y issue is that when there are multiple objects of the letter B, a B keypress deletes all of them, i want them to be deleted in sequence oldest to youngest.
I have numbered the copies, but say I iterate through the numerical of "letterA01" and delete the first I find. Wouldnt this be terribly expensive when i hit 1000 spawned and have to search through all those no-existing ones?
How is the letter destroyed? Is there a script on the letter object that destroys itself, or do you have a dedicated script that handles that?
I'll edit my answer...
Answer by armoredpokey · May 05, 2013 at 12:04 PM
Well, if you're concerned about performance, you could create a hash map of letter names => ArrayLists of letters.
var letters : Hashtable = new Hashtable();
function Awake() {
alphabet = ["a", "b", "c", "d" ... etc ];
for (letter in alphabet) {
letters[letter] = new ArrayList();
}
}
Then, the approach is basically the same as the answer above; whenever you add a letter to the scene, make sure you update the arraylist corresponding to the letter, and whenever you want to remove one, just find that arraylist and delete its first element.
function AddLetter(l) {
// do something to create a game object
letters[l].Add(object);
}
function RemoveLetter(l) {
if (letters[l].Length == 0) return;
object = letters[l][0]; // you might need to do some typecasting for C#, like "object = (GameObject) letters[l][0]"
letters[l].RemoveAt(0);
Destroy(object);
}
Your answer
Follow this Question
Related Questions
Destorying prefab and instanstiating again? 0 Answers
instantiate object 2 Answers
Removing instantiated objects?? 1 Answer
Show/hide object in C# 2 Answers
How do I destroy a Instantiated UI image that is pushed on the Canvas? 2 Answers