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

OnStartClient called before scene is fully loaded?

Discussion in 'Multiplayer' started by MythicalCity, Aug 26, 2016.

  1. MythicalCity

    MythicalCity

    Joined:
    Feb 10, 2011
    Posts:
    420
    I'm using OnStartClient to initialize my player inside the gameplay scene, but it seems that OnStartClient is called on the player's script before the scene is fully loaded, so some objects that I am trying to reference inside OnStartClient do not yet exist in the scene (even though they are gameobjects permanently inside the scene, not instantiated by my code at runtime). Is this the correct functionality? if so, is there another function I can use that will be called once the player object has been added to the scene and also after the scene is loaded (like Start or Awake normally work)?
     
  2. MythicalCity

    MythicalCity

    Joined:
    Feb 10, 2011
    Posts:
    420
    I forgot to mention that this only happens on a build, in the editor things seem to load in the scene before network objects have their OnStartClient or Start functions called.
     
  3. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    I think I face the same issue in my project.
    Indeed, the issue only appears in the game build, not in the editor.

    While in the editor, for example, the Awake function of preplaced network objects is called before OnStartServer or OnStartClient of my player object. However, for some reason, the order of these calls is different in the build. Here, I encounter the issue that the Awake function of a preplaced networked object is called AFTER the player object OnStartServer function hook.

    I do not understand this behavior and I believe it might be a bug.
    Even if it is not, I would have expected that Awake is always called first. However, if this is not the case in particular circumstances for whatever reasons, there should be information in the docs on such cases.

    I have already submitted a case for this but maybe you should do so as well. I guess the more information are available, the more easy it is for the UNET QA staff to identify the root cause.
     
    Last edited: Aug 28, 2016
    isidro02139 likes this.
  4. MythicalCity

    MythicalCity

    Joined:
    Feb 10, 2011
    Posts:
    420
    Thanks for letting me know! I'll report it too. Can you post a link to your bug report?
     
    isidro02139 likes this.
  5. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    I don't think it is already registered as a bug. Currently, I think it's a QA case only.
     
  6. emotitron

    emotitron

    Joined:
    Oct 9, 2016
    Posts:
    41
    This is still an issue. If there is a NetworkBehaviour alternative to Awake, would be nice if it was clearly documented. For network object pooling, OnStartClient replaces OnEnable... but there is nothing obvious to replace Awake.
     
  7. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Does anybody know what the intent of all the different initialize methods are?
    -Awake
    -Start
    -OnStartClient
    -OnStartServer
    -OnStartLocalPlayer
    -OnStartAuthority
    -OnRebuildObservers
     
  8. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    292
    I think the order is...
    • Awake
    • OnStartServer
    • OnStartClient
    • OnStartLocalPlayer
    • OnStartAuthority (not sure if this is before or after local player actually, need to read the source)
    • OnEnable (this might come right after Awake, before all the OnStartXXX calls, not sure)
    • Start
    • Update
    • OnDisable
    • OnNetworkDestroy (this might actually come before OnDisable, not 100% sure)
    • OnDestroy
    I've never even seen OnRebuildObservers so i have no idea where in the timeline that one comes. I'd have to really re-read the UNET source to figure out the different OnStartXXX ordering, but Awake _should always_ be called before _any other_ call - if it is not, that is kind of a huge bug - i'd trace out the ID of the asset and ensure that that is what is really happening.
     
  9. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    292
    Note also that by the time OnDestroy() is called, isServer, isClient and all the isXXX are set to false - if you need to use those values, you need to do your clean up in OnNetworkDestroy()
     
  10. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    292
    Also, OnStart (and Stop) Authority can be called multiple times, if you are setting and removing authority on GameObjects dynamically, rather then just once at SpawnWithAuthority() time.
     
  11. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    In fact, that's exactly the bug we have here - Awake is not guaranteed to be called before everything else for some networked objects. For me, for example, it happens with networked objects which are pre-placed in the scene. It appears in build only, not in editor though, which makes it even more tricky to deal with. I also had a short chat with Alexey from the UNET staff about it. It seems that this already has been registered and understood as a bug. However, Alex said that it is not trivial to fix and will require some bigger UNET design changes.
     
    Last edited: Jan 13, 2017
    Zullar likes this.
  12. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    292
    Wow, that's pretty brutal. I wonder if we have been bit by that bug - it might explain some intermittent bugs we have in builds which I can't recreate in-editor...
     
  13. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I have also seen that the order can sometimes be:
    -OnDisable
    -OnNetworkDestroy
    -OnDestroy

    or other times it can be
    -OnNetworkDestroy
    -OnDisable
    -OnDestroy

    If you Destroy() on client then you only get
    -OnDisable
    -OnDestroy

    other times it can fail to be destroyed as Jos-Yule pointed out and you only get. I bug reported this recently case 867411
    -OnDisable


    ***My workaround***
    What I've done (incase this helps you guys). I ONLY use
    -Awake
    -Start
    -OnDestroy

    I do not use anything else that the order is sometimes swapped or sometimes isn't called. During these methods I check to see if I'm a client/host/etc. and then do things accordingly. You could check things like authority? So for example instead of
    -Start
    -OnStartClient
    -OnStartServer

    ...I just use Start() and nothing else
    Code (csharp):
    1.  
    2. Start()
    3. //do something that both server & clients need
    4. if(iAmServer) //is the host
    5. {
    6.   //do something server related
    7. }
    8. else //is client
    9. {
    10.  // do something client related
    11. }
    12.  
    How to determine if you are iAmServer... not straightforward. I have static bool that is set when host/client is started. The reason I do this is when the server shuts down and everything gets destroyed I can still access that bool and disconnect/null out/destroy things accordingly (whereas NetworkServer.active wouldn't work).

    The problem I have with OnDestroy() and OnNetworkDestroy() is they are ambiguous. They are called
    -On application exit
    -When Destroy() is called
    -When NetworkServer.Destroy() is called
    -On scene close/change

    So if you want to do things like play an audio sound or generate shrapnel when an object is destroyed... well you don't want to do this during application exit or scene exit. But with Unity's OnDestroy and OnNetworkDestroy there is no way to tell what is causing the destroy. So I use a UNET message (reliable sequenced) for CustomDestroy that I call first. This lets me know if I am manually destroying an object, or if it's being destroyed automatically by application exit, scene exit, etc.

    It seems like a lot of bandaids for an incomplete UNET system (and don't even get me started on the scene change UNET bugs where SyncVars/SyncLists desync and hooks fail, or where RPC's fail. This is the biggest bug for me.). I hope they restructure and fix all these bugs soon. I haven't seen any UNET dev's post anything in months. Is there a different forum you are talking to them on? I've been bug reporting like crazy and QA has been really good at replicating all bugs, but none have been fixed since SeanR left like 1 year ago. UNET is terrifying me.
     
    jethrogillgren likes this.
  14. Deleted User

    Deleted User

    Guest

    Since UNET is deprecated and a lot of people might move to MIRROR, this is what MRGadget, administrator and moderator on Discord says about this:
    It's true that Awake, Start, OnStartClient and OnStartLocalPlayer can have some deviation in timing because the first two are driven by Unity and the latter two are invoked by messages. There's no way to make Unity wait before firing Start until the network messages have arrived and been processed, so if those messages are the least bit delayed after the SpawnMessage, either due to internet lag, or server processing time, or the weather, Awake and Start may have already run
     
    Charzard4261 and Joe-Censored like this.