Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Destroy(gameobject) vs Despawn()

Discussion in 'Netcode for GameObjects' started by Max_power1965, Sep 19, 2022.

  1. Max_power1965

    Max_power1965

    Joined:
    Oct 31, 2013
    Posts:
    127
    I have the following code the destroy an object which only happens on the Host side.

    Code (CSharp):
    1.  public void OnTapReceived()
    2.     {
    3.  
    4.         if (_allowTap)
    5.         {
    6.             if (NumberOfTapBeforeDestroy.Value > 1)
    7.             {
    8.                 GetComponent<CloneBubbleManager>().CloneBubble();
    9.             }
    10.             if (IsHost == false)
    11.             {
    12.                 TransmitBubbleDestroyStateToServerRpc();
    13.             }
    14.             else
    15.             {
    16.                 Destroy(gameObject);
    17.             }
    18.         }
    19.     }
    20.  
    21.     [ServerRpc(RequireOwnership = false)]
    22.     public void TransmitBubbleDestroyStateToServerRpc()
    23.     {
    24.         Destroy(gameObject);
    25.     }
    The code works fine but I'm confused about the Despawn() method. When and why should I use Despawn() instead of Destroy?
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    656
    I'd imagine if you Spawn a network object you'll want a corresponding Despawn call before destroying it, otherwise the object won't be de-registered from the NetworkManager.

    You can combine despawning and destroying the object with Despawn(true).
     
    codeBatt likes this.
  3. Max_power1965

    Max_power1965

    Joined:
    Oct 31, 2013
    Posts:
    127
    How do you know that the object won't be de-registered? I haven't found anything in the documentation. I'm personal code Destroy seams also to "de-registered" the object from the Manager
     
  4. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    229
    If you want to despawn a networkObject but not destroy it on all the clients, you should use the despawn method with DontDestroyWithOwner property set to true
     
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    656
    You're right, I guess the NetworkManager handles it via OnDestroy. The reason I thought it didn't pick it up was I tried it with a network object containing a NetworkList and calling Destroy on that spammed a load of errors, whereas calling Despawn(true) was fine.
     
  6. itisMarcii_

    itisMarcii_

    Joined:
    Apr 5, 2022
    Posts:
    111
    Overall its just so the Netcode System can destroy the object correctly.

    If you gonna Despawn a NetworkObject, the Server will firstly check if there are children on the Object that dont have the OnDestroyWithParent flag. They will be rerooted and remain in the Scene.
    Afterwards the NetworkObject will be Enqued into the ReleasedNetworkObjectIds to recycle the NetworkObjectId.
    Afterwards all other Clients will be messaged that this NetworObject is gonna despawn.
    Also the Object will be removed correctly from all the Arrays, for example the SpawnedObjectList.
    After everything is in order, the NetworkObject is gonna be destroyed.

    So to summarize, the Despawn unsubscribse the NetworkObject from everything and sends a message towards all Clients in that process. And afterwards its gonna be Destroyed.

    If you wanna have a closer look into the process, just open the NetworkObject code and follow all methods resulting from the Despawn method.
     
    pdeschain-unity likes this.
  7. Max_power1965

    Max_power1965

    Joined:
    Oct 31, 2013
    Posts:
    127
    Ok, so you are saying that by calling destroy directly all of the above won't happen? To be honest, I thought the same, but my code is working fine, so I thought that behind the scene when Destroy is called the network component will automatically do his stuff.
    I really whish for more detailed documentation.
     
  8. itisMarcii_

    itisMarcii_

    Joined:
    Apr 5, 2022
    Posts:
    111
    I agree with the documentation statement. They improved it A LOT over the last months, but there is still so much information missing.

    I expect (I havent looked into the code right now) that Netcode detects if an object in the scene is missing. But most likely that will occure somwhere in the middle of the process, which can cause issues ... maybe.
    The Despawn method is the safe way and I would recommend to use it.

    if you gonna take a look into the code base pls share the insight with us :)
     
  9. SamuelBellomoUnity

    SamuelBellomoUnity

    Unity Technologies

    Joined:
    Sep 24, 2020
    Posts:
    14
    @Max_power1965 Is your object dynamically spawned or statically placed in scene?
    The behaviour you describe above seems to fit with dynamically spawned, where both a despawn and destroy will be synced automatically to clients when OnDestroy is called server side.
    However, if static, did you test with a client connected? Client side you should only see a despawn, no destroy. A manual destroy server side will trigger a despawn server and client side, but no destroy client side (which will need to be called manually).
    You should use Despawn(destroy: true) to destroy both client and server side to get the same behaviour with dynamic vs static NetworkObjects.
     
    CreativeChris likes this.
  10. Max_power1965

    Max_power1965

    Joined:
    Oct 31, 2013
    Posts:
    127
    Hello my objects are dynamically spawned, that it's why the simple Destroy was working. And when I use the Despawn() method, isn't that automatically isn't the default parameter set to true, in other words, calling Despawn() is the same as calling Despawn(destroy: true) right?
     
    firebird721 likes this.