0

I have an object that creates another object. I pass the created object to some other object then destroy the original. Assuming the object I passed it to keeps its own reference, does destroying the creator also destroy the created object? I think the answer is no, but perhaps there are some caveats?

class MyObject : MonoBehaviour
{
    MyObject myObj = new MyObject();

    void someFunc()
    {
        GlobalObj.GiveObject(myObj)
        Destroy(gameObject)
    }
}

class GlobalObj
{
    MyObject obj;

    GiveObject(MyObject o)
    {
        obj = o;
    }
}
CodeMonkey
  • 1,795
  • 3
  • 16
  • 46
  • The object exists as long as there is a reference to it and afaik Destroy has nothing to do with it. – Fabjan Sep 30 '17 at 16:47
  • @CodeMonkey I also do believe you should add a compileable code with and mention which script is the creator in this case. I feel like `MyObject` is the creator here but I am a bit confused. Also note that you [**cannot**](https://stackoverflow.com/questions/37398538/unity-null-while-making-new-class-instance) create new instance of an Object that inherits from `MonoBehaviour` with the `new` keyword. – Programmer Sep 30 '17 at 17:04

2 Answers2

0

MyObject is a reference type so whatever Unity does when Destroy is called, it does not remove the object from memory; the reference is still valid.

The Destroy method seems to be just about removing the object from the game. There may be no Dispose involved which means the instance can be used without any issue.

Kzryzstof
  • 7,688
  • 10
  • 61
  • 108
  • Destroy doesn't remove the object from memory?? Or does it just wait for a garbage collection which checks for any references? Will the entirety of the MyObject never be collected because myObj has others referencing it? – CodeMonkey Sep 30 '17 at 15:59
  • 1
    The Garbage Collector will remove an object from memory only if it is not referenced anymore. If another object (still in use) keeps a reference on your destroyed object, your destroyed object will not be collected by the GC. – Kzryzstof Sep 30 '17 at 17:14
  • All of *that said* if you try to do anything with the reference after `Destroy()` has been called on a GameObject or Component, Unity will throw a runtime exception saying, "[Object] has been destroyed, yet a script is still trying to access it." – Draco18s no longer trusts SE Sep 30 '17 at 18:28
  • It makes sense if the method you are trying to access is related to the Unity framework. But that was not the question. The object is not removed from memory. – Kzryzstof Sep 30 '17 at 18:54
  • The question is not about the object being explicitly destroyed. It's about the object that the destroyed object created and passed somewhere else before being destroyed. – CodeMonkey Sep 30 '17 at 19:03
  • @CodeMonkey The reference that you have passed before the call to Destroy will still be there after Destroy is called. However as highlighted in the answer below, certain methods based on the Unity framework may raise exceptions if you try calling them after the destroy. But the reference to that object is still there :) – Kzryzstof Sep 30 '17 at 19:08
  • Again, I'm not trying to reference the one that was destroyed. I'm trying to reference the object that the destroyed object created and passed somewhere else before it was destroyed. – CodeMonkey Sep 30 '17 at 19:09
  • @CodeMonkey Sorry for the confusion. It does stay for either case. Object A creates Object B. Object B is passed to Object C. Object A is Destroy'd. As long as Object C keeps the reference to Object B, Object B will stay in memory. – Kzryzstof Sep 30 '17 at 19:13
0

No, this is bad

When you call Destroy() in Unity, that object is gone. You can pass around a reference to that object all you want, but that reference points to a null object (sort of).

For the same frame during which the object is destroyed, the reference will continue to function normally (see test code examples), however, on the next update cycle those references will point to null as Unity has deconstructed the object and it no longer exists. Attempting to reference it will throw the runtime exception:

MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.

Your script should either check if it is null or you should not destroy the object.

The following examples were what I tested:

public class TestDestroy_NonCrashing : MonoBehaviour {
    public GameObject someObj; //assigned in the inspector
    
    void Start () {
        Destroy(someObj);
        Debug.Log(someObj); //prints "Cube (UnityEngine.GameObject)"
        MeshRenderer someComponent = someObj.GetComponent<MeshRenderer>();
        someComponent.material.SetColor("_Color", new Color(1, 0, 0));
    }
}

public class TestDestroy_Crashing : MonoBehaviour {
    public GameObject someObj; //assigned in the inspector
    
    void Start () {
        Destroy(someObj);
    }

    void Update() {
        Debug.Log(someObj);  //prints "null"
        MeshRenderer someComponent = someObj.GetComponent<MeshRenderer>();
        someComponent.material.SetColor("_Color", new Color(1, 0, 0));
    }
}
Community
  • 1
  • 1
  • 1
    The question was whether the reference was lost or not after calling Destroy, which is not the case: the reference is still available otherwise a NullReferenceException would have been thrown. If you add another method or property to that object that is not linked to the Unity Framework, the method or property will still be available to be called. – Kzryzstof Sep 30 '17 at 18:52
  • @Kzrystof This is why I included the example code and talked about how the Unity object is still around during that frame. If we're talking a non-Unity object (the question is unclear, as the object being passed around and destroyed is a MonoBehaviour), then things might be different. – Draco18s no longer trusts SE Sep 30 '17 at 18:57
  • The question is about destroying the creator, not the created. You are destroying the created. – CodeMonkey Sep 30 '17 at 19:09
  • @CodeMonkey I took a look at the question again and you're right. – Draco18s no longer trusts SE Sep 30 '17 at 19:43
  • @Kzrystof For the sake of clarity, Unity doesn't guarantee exactly *when* an object will be destroyed during the frame which `Destroy(obj)` was called, it only guarantees that it will be destroyed before the render pass on the following frame. – arkon Oct 03 '19 at 13:36