Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Check If Instantiated Is Destroyed

Discussion in 'Scripting' started by mgrekt, Aug 25, 2020.

  1. mgrekt

    mgrekt

    Joined:
    Jun 22, 2019
    Posts:
    92
    How would you check if an instantiated object is destroyed? Say for example, you have a counter that it counts every prefab that is spawned. When the player destroys that prefab it would count one down, but here's the issue how would you check it?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Pretty sure there is no way to see if something has been destroyed. You're welcome to destroy it again if you like no harm no foul AFAIK. It will go away at end of scene. If you make a copy , you're also copying the already-destroyed thing so that too will go away at end of frame.
     
  3. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    What if you had the same code that destroys the prefab also decrements the counter?
     
  4. mgrekt

    mgrekt

    Joined:
    Jun 22, 2019
    Posts:
    92
    You suggesting this gave me an idea what if I make a script onto the zombie to check if it's still active in the hierarchy by making a statement if it equals to null (given that it will be null if it's destroyed). And when it equals to null I can subtract one from the script that counts prefabs instantiated.
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    Hmm... one problem with that though - if the zombie is destroyed how will that code run?
     
  6. mgrekt

    mgrekt

    Joined:
    Jun 22, 2019
    Posts:
    92
    True hmm I'll keep on thinking about it
     
  7. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    Instead of destroying use pools.

    Or maybe keep reference to the object created somehwere then you can check null?
    Code (CSharp):
    1. public class aclass:
    2. GameObject go;
    3. void Start()
    4. {
    5.     go = instantiate();
    6. }
    7. void Update()
    8. {
    9.     if(go) //or maybe if(go!=null)
    10.     {
    11.         //still exists
    12.     }
    13. }
     
  8. mgrekt

    mgrekt

    Joined:
    Jun 22, 2019
    Posts:
    92
    Here's the thing though I'm instantiating multiple objects over time this is doable if it was one, but it's not.

    Edit: I might attempt using a list, not sure how's its gonna turn out though since I barely touched them.
     
  9. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    It's certainly doable with multiple objects. That's what C#'s HashSets, Lists, and Dictionaries are for! Of course, checking for destroyed over and over in Update() is a waste when you can just register the object as having been destroyed when your code destroys it.
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Do you only care about a counter?! That's trivially easy... make a new script that implements
    OnEnable()/OnDisable()
    and put your count up count down code in there.
     
    mopthrow and PraetorBlue like this.
  11. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,697
    There's also the Awake() and OnDestroy() callbacks.
     
  12. DeeJayVee

    DeeJayVee

    Joined:
    Jan 2, 2015
    Posts:
    121

    You could instantiate them into a list.

    Its something like

    Code (CSharp):
    1. List<GameObject> enemies = new List<GameObject>();
    2.  
    3. enemies.add(Instantiate(prefab, transform, quaternion)
    I cant remember on a whim how to instantiate to a list, but thats basically itx a quick Google search will yield something.

    But anyway, if you instantiate your enemies into a list then you'll always have a count, just before you destroy them you remove them from the list

    Enemies.remove(thisenemy);
    Destroy(this);
     
  13. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    Just use an array then.
    Code (CSharp):
    1. public class aclass:
    2. GameObject[] go = new GameObject[99];
    3. void Start()
    4. {
    5.      for(int i = 0; i < 99; i++)
    6.     {
    7.        go[i] = instantiate();
    8.     }
    9. }
    10. void Update()
    11. {
    12.      for(int i = 0; i < 99; i++)
    13.     {
    14.         if(go[i])
    15.         {
    16.             //still exists
    17.         }
    18.     }
    19. }
     
  14. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I'd just add instantiated objects to a list. Whenever you want to know how many exist you call a method which iterates through the list removing all destroyed objects, then returns list.count.
     
  15. KeithBoshoff

    KeithBoshoff

    Joined:
    Nov 26, 2018
    Posts:
    1
    I have a component that manages Mesh Renderers and Mesh Filters (from creation to destruction, theoretically) on an object and actually hides them from the user (to prevent human error), so I like to do house cleaning when destroying the controlling component (ie. destroying the renderer and filter), which I do in OnDestroy. The problem is that there's no way of detecting the difference between the gameobject being destroyed (which destroys each component in turn) and only destroying the controlling component.

    So, when we destroy the game object it marks game object, mesh filter, mesh renderer, and controller for destruction, then OnDestroy is called on the controller, which destroys the mesh filter and mesh renderer again. This actually kicks up an error in the console which actually bypasses try() catch() statements.

    This is one of probably 20 situations where I've had to make a dumb workaround* to something that should be super simple because I can't check if an object is being destroyed.

    * Workaround in this case being unhiding the renderer and filter on destroy so the user can do manual housekeeping, which is really crappy.