Search Unity

Bug: Player OnDestroy is never called on Server

Discussion in 'Multiplayer' started by mischa2k, Jan 15, 2016.

  1. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    I attached a project with 10 lines of code, it's very simple:
    • start it in the Editor
    • select Start Host (spawns a Player)
    • stop the Editor with the Editor stop button (not the ingame NetworkManagerHud stop button)
      • usually this result in OnDestroy being called in GameObjects
    • see how OnDestroy is called in the Player Script, but:
      • it's never called with 'isServer == true', so it's only called for isClient and isLocalPlayer
    This is a problem because when quitting a game server, we usually want to save all player data. But if OnDestroy is never called with isServer==true (aka on the server), then it can't be saved, the only alternative is to save it every few minutes or so in an interval.

    Any insight on this would be greatly appreciated, perhaps I am missing something.

    [Tested on Unity 5.3.1f1]
     

    Attached Files:

    Last edited: Jan 15, 2016
  2. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    There is no guarantee that OnDestroy is called before the NetworkIdentity on the object is torn down, so isServer is not reliable in OnDestroy. The isServer variable should still be set in OnNetworkDestroy.
     
  3. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Thanks, works indeed!

    Greetings
     
    Last edited: Jan 15, 2016
  4. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Okay tested it some more. The documentation is correct, it is only called on clients (or host). So is there any function that we are supposed to use for something like "save all players before shutting down the server"? I can't seem to find any kind of OnDestroy/OnQuit/OnDisconnect function that is reliably called on the server when quitting it, while still being called early enough so that player data can still be accessed and saved. E.g. NetworkManager:OnDestroy is called reliably, but it's called too late because most of the time the Players were already destroyed. Also changing the Script Execution Order doesn't seem to have any influence on this.

    Obviously a manual GUI button with "Save stuff and quit" would work, but when running servers in Headless mode, no buttons can be clicked etc.

    Greetings
     
  5. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    NetworkManager::OnStopServer() ?
     
  6. Severos

    Severos

    Joined:
    Oct 2, 2015
    Posts:
    181
    If you want to save the data of player soon as they go offline I suggest using OnServerDisconnect, and personally I'd override the OnStopServer and disconnect all players along with saving any server states that are needed in next run.
     
  7. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    This function is only called when calling the StopServer() function explicitly, but not when just closing the game or stopping the Editor.

    I know that's probably the intended behavior and I won't complain if you don't intend to change it. I am just pointing out that there is no simple way to stop a headless mode server without losing player data. The only alternative that I see is to login as client and run some kind of admin command through the chat, but seeing how UNET is supposed to make Networking easier, having OnStopServer be called when one closes a (headless mode) server would make things much easier.

    Greetings