Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Unity Multiplayer UNET ids failing to match on network session

Discussion in 'Connected Games' started by lucasmontec, Mar 3, 2017.

  1. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    For come reason scene object spawning works perfectly in the editor, in build <-(lo)-> editor, build <-(lo)-> build connections but not across the web (editor<->editor always seems to fail).

    I'm getting the following errors:
    Found no behaviour for incoming [ClientRpc:InvokeRpcRpcAddFeedEvent] on Spawner (1) (UnityEngine.GameObject), the server and client should have the same NetworkBehaviour instances [netId=6]. UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()
    Found no behaviour for incoming [ClientRpc:InvokeRpcRpcTransmitStateOnConnect] on Spawner (UnityEngine.GameObject), the server and client should have the same NetworkBehaviour instances [netId=5]. UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()



    This occurs when my friend connects his build to my editor or build across the web. This is random, occurs almost 99% of the time (but sometimes doesn't). This also only occurs across the web.

    Scene are IDENTICAL. 100% Sure.
    The scene is pretty simple:
    It is just a setup prefab with all UI and controllers. The DEBUG inside it is the NWManager with the HUD component.


    The NW manager is the same I use across the project. Same settings but without online/offline scenes:



    Its code just adds events to relevant things. Doesn't change normal behaviour.

    The gamemode code spawns prefrabs periodically. They are spawned on the server and they have SyncTransform.

    The only possible problem I noticed is that when this error occurs it points to netId=x. When setting the inspector to debug and inspecting NetworkIdentity components across the scene, in some of them the object scene ID differs from the same object on my friends PC.
     
  2. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    The same game setup works on all other scenes.
     
  3. Driiades

    Driiades

    Joined:
    Oct 27, 2015
    Posts:
    151
    It's like you destroyed/removed a NetworkBehavior script.
     
  4. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    I'll check that but I find it unlikely. No scripts that I have remove any components. All instantiations are made through the nw manager. All removals also.
     
  5. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    With a script I have managed to get this:
    [CLIENT]
    Code (CSharp):
    1.  
    2. * [GAMEOBJECT, NETID] Player_10, active: True, netId: 12
    3. * [GAMEOBJECT, NETID] Player_9, active: True, netId: 11
    4. * [GAMEOBJECT, NETID] Spawner, active: True, netId: 1
    5. * [GAMEOBJECT, NETID] Spawner (1), active: True, netId: 2
    6. * [GAMEOBJECT, NETID] DM Gamemode, active: True, netId: 4
    7. * [GAMEOBJECT, NETID] UIController, active: True, netId: 5
    8. * [GAMEOBJECT, NETID] Chat, active: True, netId: 6
    9. * [GAMEOBJECT, NETID] NetworkRouter, active: True, netId: 7
    10. * [GAMEOBJECT, NETID] ConsoleNW, active: True, netId: 8
    [SERVER]
    Code (CSharp):
    1.  
    2. * [GAMEOBJECT, NETID] Player_10, active: True, netId: 12
    3. * [GAMEOBJECT, NETID] Player_9, active: True, netId: 11
    4. * [GAMEOBJECT, NETID] Chat, active: True, netId: 1
    5. * [GAMEOBJECT, NETID] ConsoleNW, active: True, netId: 2
    6. * [GAMEOBJECT, NETID] NetworkRouter, active: True, netId: 3
    7. * [GAMEOBJECT, NETID] UIController, active: True, netId: 4
    8. * [GAMEOBJECT, NETID] Spawner, active: True, netId: 5
    9. * [GAMEOBJECT, NETID] Spawner (1), active: True, netId: 6
    10. * [GAMEOBJECT, NETID] Spawner (2), active: True, netId: 7
    11. * [GAMEOBJECT, NETID] DM Gamemode, active: True, netId: 8
    Seems like all netids are wrong. The scenes are the same. This happens just after a build on my friends computer.

    [edit] Also for those with sharp eyes that noticed Spawner (2) only shows serverside... for some reason it was getting deativated in the client. About this: No code explicitly deativates it. It is not marked as server only. It should be disabled on start but on join it should get enabled again (UNET documentation).
     
    Last edited: Mar 6, 2017
  6. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    With a fresh pull from the server (GIT), everything 'works' but the script reveals an issue:


    Seems like netIds are not beeing synchronized correctly.
    When my friend creates a build, more errors appear and more ids turn wrong.
     
  7. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
  8. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    I can't develop until this is solved. Forum can consider this a post bump. If this is not allowed.. um sorry. This seems to be something critical and weird about Unet Behaviour. The documentation says net ids are tied to a network session and yet they are differing across client and server using the same scene.

    In a 'working' scene this is also happening:
    Client
    Code (CSharp):
    1. * [GAMEOBJECT, NETID] Player_9, active: True, netId: 11
    2. * [GAMEOBJECT, NETID] Player_8, active: True, netId: 10
    3. * [GAMEOBJECT, NETID] Chat, active: True, netId: 1
    4. * [GAMEOBJECT, NETID] ConsoleNW, active: True, netId: 3
    5. * [GAMEOBJECT, NETID] UIController, active: True, netId: 2
    6. * [GAMEOBJECT, NETID] Spawner, active: True, netId: 5
    7. * [GAMEOBJECT, NETID] Spawner (1), active: True, netId: 6
    8. * [GAMEOBJECT, NETID] DM Gamemode, active: True, netId: 7
    Server
    Code (CSharp):
    1. * [GAMEOBJECT, NETID] Player_9, active: True, netId: 11
    2. * [GAMEOBJECT, NETID] Player_8, active: True, netId: 10
    3. * [GAMEOBJECT, NETID] Chat, active: True, netId: 1
    4. * [GAMEOBJECT, NETID] ConsoleNW, active: True, netId: 2
    5. * [GAMEOBJECT, NETID] NetworkRouter, active: True, netId: 4
    6. * [GAMEOBJECT, NETID] UIController, active: True, netId: 3
    7. * [GAMEOBJECT, NETID] Spawner, active: True, netId: 5
    8. * [GAMEOBJECT, NETID] Spawner (1), active: True, netId: 6
    9. * [GAMEOBJECT, NETID] DM Gamemode, active: True, netId: 7
    After a build in my friend's machine, this also happened:

    Coudn't repeat the process to cause this.

    What we have tried:

    https://issuetracker.unity3d.com/is...ethod-breaks-networkmanager-if-loading-scenes
    We have removed awake override and also tested calling base awake with reflection.

    https://forum.unity3d.com/threads/f...-client-player-prefabs-not-showing-up.363606/
    We tried to locate possible unregistered objects getting spawned without success. Failing objects were always scene objects.

    https://forum.unity3d.com/threads/spawn-scene-object-not-found-for-1.333122/
    This seemed quite similar to our problem but most of the rpc fails aren't our code. The main rpc to fail is the transmit state on connect. This seems to be because the netids are wrong and the call cannot find the behavior in the wrong game object. The right game object is either disabled (randomly) or is enabled but with the wrong id.

    We thought it could be a memory problem but..


    https://forum.unity3d.com/threads/unet-clientrpc-not-executing-on-host.320288/
    We also checked this and read all our code to delay possible rpcs on start. Nothing was there. Still the failing RPC is transmit state on connect (from UNET).

    http://www.bellingo.de/blog/no-behaviour-for-incoming-rpc-unet-pitfalls-2/
    This also gave us tips but without sucess. We are not using class with same names (not even similar).
     
    Last edited: Mar 7, 2017
  9. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    We just tested this:
    "The NetworkBehaviour component requires a NetworkIdentity on the game object. There can be multiple NetworkBehaviours on a single game object. For an object with sub-components in a heirarchy, the NetworkIdentity must be on the root object, and NetworkBehaviour scripts must also be on the root object."
    from:
    https://docs.unity3d.com/ScriptReference/Networking.NetworkBehaviour.html

    And it is still not working. Actually removing every NetworkBehaviour component from a hierarchy made our NWRouter (marked as server-only) spawn on the client. Also made our gamemode object disabled on the client.

    [edit]
    Scene ids on NW Identities were non 0 with the play mode turned off.
    Zeroing manually didn't do anything.
     
    Last edited: Mar 7, 2017
  10. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    We have inspected almost the entire code on Scene Objects spawn.
    https://docs.google.com/spreadsheets/d/1HREQE8WVDAMDiEwMWJGQu_QtkobmgTwgHLnwcXvSlrI/edit?usp=sharing

    This spreadsheet has comments on what we got out of it and possible problems that we think may result in what we are experiencing. We find it reasonable to think the method OnPostProcessScene is the most probable cause since it is just after the first build (player build and not entering playmode), since a pull from git, that the errors start.
     
  11. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    289
    You might also look into this thread. It deals with an UNET issue that causes script execution orders to be different between editor and build. I don't know, maybe your problem is somehow related to this. Moreover, you could try to directly contact one of the people of the UNET staff about your issue.
     
  12. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    Thankis @moco2k I'm really not sure what I'm experiencing. NetIds should work. It is actually a weird design the way they assign them... Actually many things in the UNET HLAPI code are really weird. I'm in contact with a Unity guy that helped me before, he is going to bring UNET staff to check this problem. Until then, I'll keep testing stuff.
     
  13. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    My suspicions were correct.
    I have made the following script:
    Code (CSharp):
    1. public class UnitySceneIdDebug : MonoBehaviour {
    2.     [PostProcessScene]
    3.     public static void OnPostProcessScene() {
    4.         int nextSceneId = 1;
    5.         string debug = "";
    6.  
    7.         //Is the list ordered the same way always or am I insane?
    8.         string list = FindObjectsOfType<NetworkIdentity>().Select(uv => uv.name).Aggregate((current, next) => current + ", " + next);
    9.         Debug.Log("The list returned by FindObjectsOfType<NetworkIdentity>() is:\n" + list);
    10.  
    11.         foreach (NetworkIdentity uv in FindObjectsOfType<NetworkIdentity>()) {
    12.             // if we had a [ConflictComponent] attribute that would be better than this check.
    13.             // also there is no context about which scene this is in.
    14.             if (uv.GetComponent<NetworkManager>() != null) {
    15.                 Debug.LogError("NetworkManager has a NetworkIdentity component. This will cause the NetworkManager object to be disabled, so it is not recommended.");
    16.             }
    17.             if (uv.isClient || uv.isServer)
    18.                 continue;
    19.  
    20.             //Original UNET code
    21.             /*uv.gameObject.SetActive(false);
    22.             uv.ForceSceneId(nextSceneId++);*/
    23.  
    24.             debug += "Generated scene id(" + (nextSceneId++) + ") for GameObject: " + uv.gameObject.name + "\n";
    25.         }
    26.  
    27.         Debug.Log(debug);
    28.     }
    29. }
    And runned on my machine:
    Code (CSharp):
    1. The list returned by FindObjectsOfType<NetworkIdentity>() is:
    2. ConsoleNW, UIController, NetworkRouter, Spawner, Spawner (1), DM Gamemode
    3.  
    4. UnityEngine.Debug:Log(Object)
    5. UnitySceneIdDebug:OnPostProcessScene() (at Assets/Editor/UnitySceneIdDebug.cs:16)
    Code (CSharp):
    1. Generated scene id(1) for GameObject: ConsoleNW
    2. Generated scene id(2) for GameObject: UIController
    3. Generated scene id(3) for GameObject: NetworkRouter
    4. Generated scene id(4) for GameObject: Spawner
    5. Generated scene id(5) for GameObject: Spawner (1)
    6. Generated scene id(6) for GameObject: DM Gamemode
    7.  
    8. UnityEngine.Debug:Log(Object)
    9. UnitySceneIdDebug:OnPostProcessScene() (at Assets/Editor/UnitySceneIdDebug.cs:34)
    And then my friend runned on his machine:
    Code (CSharp):
    1. The list returned by FindObjectsOfType<NetworkIdentity>() is:
    2. UIController, ConsoleNW, NetworkRouter, Spawner, Spawner (1), DM Gamemode
    3. UnityEngine.Debug:Log(Object)
    4. UnitySceneIdDebug:OnPostProcessScene() (at Assets/Editor/UnitySceneIdDebug.cs:16)
    5.  
    6. Generated scene id(1) for GameObject: UIController
    7. Generated scene id(2) for GameObject: ConsoleNW
    8. Generated scene id(3) for GameObject: NetworkRouter
    9. Generated scene id(4) for GameObject: Spawner
    10. Generated scene id(5) for GameObject: Spawner (1)
    11. Generated scene id(6) for GameObject: DM Gamemode
    Same scene. Same Unity version. Same workplace setup.
     
  14. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    Couldn't wait.
    Did a workaround that fixes the order based on GO name. Just can't repeat GO names for objects that have NWIdentities. Maybe doing this sort with instanceIds can be something too.

    Workaround code:
    Code (CSharp):
    1. public class FixUNETSceneIds : MonoBehaviour {
    2.     [PostProcessScene(10)]
    3.     public static void OnPostProcessScene() {
    4.         int nextSceneId = 1;
    5.  
    6.         //Is the list ordered the same way always or am I insane?
    7.         List<NetworkIdentity> list = Resources.FindObjectsOfTypeAll<NetworkIdentity>().ToList<NetworkIdentity>();
    8.         list.RemoveAll(go => PrefabUtility.GetPrefabParent(go) == null && PrefabUtility.GetPrefabObject(go) != null);
    9.         list = list.OrderBy(x => x.gameObject.name).ToList<NetworkIdentity>();
    10.  
    11.         foreach (NetworkIdentity uv in list) {
    12.             if (uv.isClient || uv.isServer)
    13.                 continue;
    14.  
    15.             //Override original UNET code
    16.             //uv.gameObject.SetActive(false); -- no need, already disabled
    17.             uv.ForceSceneId(nextSceneId++);
    18.         }
    19.  
    20.     }
    21. }
     
    jethrogillgren, ACHIEVR and VildNinja like this.
  15. AshkoreDracson

    AshkoreDracson

    Joined:
    Jul 6, 2014
    Posts:
    24
    I just found this thread by experiencing the same bug, it's really not consistent but occasionally in my cinema game, when a client connects to the server, it is somehow assigned the same ID as one of the seats, causing a lot of synchronization problems, especially with Commands and ClientRpc's, NetworkTransform and the like still seem to work fine.
    This bug is still not fixed in Unity 5.6.0f3
     
    lucasmontec likes this.
  16. r_del71

    r_del71

    Joined:
    Jul 22, 2015
    Posts:
    3
    I have a similar situation happening, but mine seems to be limited to when a different device is set as the host. When I run the Unity editor as the host, everything seems to function exactly as it should.

    I'm only referencing players in the game though, so not exactly what you are doing, but the end result is the same (some id's referencing the same object are different.)

    I am going to try your code above to see if I can get a better understanding of what is going on, thanks for posting!
     
    lucasmontec likes this.
  17. Emiles

    Emiles

    Joined:
    Jan 22, 2014
    Posts:
    32
    I don't know if this will help but i got the same error and managed to work out what was causing it for my specific scenario.
    I want to be able to dynamically apply a Networkbehaviour script to my player Prefab. Such that a user would connect. On connection i had another script attach a behaviour to the Player Instance. The script i'm adding calls a server method to instantiate a non-player object.

    As soon as i attached the Network behaviour script to the player prefab, rather than dynamically adding it after the server had created it, the issue went away.

    You may not be doing the same thing, but my suggest is to look for anything that changes the player instance in anyway what so ever. For example, in my main project, i have two separate Unity projects trying to connect to the same multiplayer server. To get this to work requires the meta files to be exactly the same in both projects. Any deviation and the networking code fails. So it clearly likes things to be EXACTLY the same.
     
  18. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    No, I wasn't adding any behaviours dynamically. I was using UNET exactly according to spec. But since my workaround, I'm not having the issue. Btw, as I described, the issue was happening to static netids.
     
  19. lchproducciones

    lchproducciones

    Joined:
    Jun 5, 2014
    Posts:
    2
    Uhm.. this seems to be still happening. The workaround still works btw.
     
    lucasmontec likes this.
  20. Dreamer

    Dreamer

    Joined:
    Mar 8, 2011
    Posts:
    64
    Can't believe this bug still happens at new version. It's been years. What is Unity doing??????????????????????????????????????????????????????????
     
  21. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    1,411
    Try using HLAPI Pro (free, search on a forum). It's fixed there.
     
  22. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,043
    lucasmontec likes this.
  23. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    You used my fix? Because I order the list by object name (which isn't reliable).

    just saw your fix and it is based on sibling index. Woundn't that change uppon adding and removing things dynamically?

    Also, awesome work on the HLAPI fix. I have a TON of documentation and assets developed to cope with all the bugs, if you need help, count me in!
     
    Last edited: Oct 21, 2017
    lchproducciones likes this.
  24. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,043
    Yes, I tried about 10 different ways and came to the conclusion that sibling index is the best for now, since scene objects have no unique id in Unity. This works reliably now and doesn't randomly change after restarts.

    Any scene change still requires a rebuild yes. Ideally UNET would compare some kind of 'lastProjectChange' timestamp in the login handshake - because if you changed something in the client and not in the server then things usually go wrong.
     
    lucasmontec likes this.
  25. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    I thought about hashing each object. It would make the build a bit slower but it would guarantee, almost always, the same order.
     
  26. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,043
    Won't work. If you have two monsters (same type) that spawn on the spot, they will have the same hash
     
  27. ACHIEVR

    ACHIEVR

    Joined:
    Aug 24, 2017
    Posts:
    3
    Wow, this is such critical information about UNet Scene Objects hidden away here in this thread.
    It's unbelievable that games work as well as they do without developers being aware of the magic (or lack of) how UNet is wiring up client and server scene objects.

    Thank you @lucasmontec so much for your brilliant investigation and work-around.

    I've created an additional variation of it, that I attach this script to each of my scene objects:

    Code (CSharp):
    1. public class NetworkIdentitySceneId : MonoBehaviour {
    2.     public int SceneId = 0;
    3. }
    4.  
    Then I use your script, but check if it has this ID manually set and I use that instead.

    Thank you so much!
     
    lucasmontec likes this.
  28. Driiades

    Driiades

    Joined:
    Oct 27, 2015
    Posts:
    151
    Or you just rework the HLAPI and let developpers specify the scene id of their objects in the scene.
    That what I will do.

    Same for assetID, so we can communicate between different project.

    There is more configuration from developpers but also more freedom.
     
    lucasmontec likes this.
  29. stevesan

    stevesan

    Joined:
    Aug 14, 2011
    Posts:
    63
    My client build can connect to a host if the host is an Editor...but not if the host is a build. I see the "Spawn scene object not found for 1" and 2, 3, 4. What's going on here..
     
  30. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    For 50 USD I'll debug for you. Otherwise, I'll wish you good luck.
     
    xVergilx likes this.
  31. stevesan

    stevesan

    Joined:
    Aug 14, 2011
    Posts:
    63
    Will keep that in mind...might take you up on it later. I'm dropping this for now.

    But is this bug still not fixed, as of 2018.1?
     
  32. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    1,411
    Nothing has changed, as far as I know
     
  33. patrick_scheper

    patrick_scheper

    Joined:
    Mar 18, 2015
    Posts:
    16
    This same problem occured to me when I assigned a value to the NetworkBehaviour without it being initialized by the server/client. Maybe that helps someone.

    Unity 2018.1.0f2
     
  34. MichiealO

    MichiealO

    Joined:
    Jul 7, 2013
    Posts:
    59
    And yeah, no -- this bug is still not fixed as of 2018.1.... As, I found this thread looking up what the heck the new set of errors that I am getting mean. >.<
    I just love this... I spend 99% of my day debugging UNITY... Not, my game in unity, but Unity itself. It used to be, I'd sit down, crack open Unity and build a game... now, it's I crack open unity and see what the latest idiotic bullshit I will have to deal with, in a sad attempt at doing what I love. Oh well, maybe if I say it enough, I will be able to stomach using Unreal.
     
  35. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    135
    I can confirm this bug is around in Unity 2018.2 still.
    And since UNET will be deprecated, the bug is known for what... two years now..., even though they promise support until 2022, considering I have issued a fair amount of bugs, I don't think they will fix any of this at all.
     
  36. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    1,411
    Use Mirror (previously HLAPI Pro). It has this bug fixed in there.
     
    vis2k likes this.
  37. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,043
    This happens because UNET's NetworkScenePostProcess assumes that FindObjectsOfType always returns the same order - but the documentation says that it doesn't. For this to work, we need to sort the FindObjectsOfType result in a deterministic way. We did that in Mirror and the UNET team copied our fix to UNET, but they did it wrong so the bug is still in there.
     
    Alexees and xVergilx like this.
  38. dmitryon

    dmitryon

    Joined:
    Jan 6, 2018
    Posts:
    8
    The fix is: have the same exact build as the server. Then the IDs match.
     
  39. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    Since unet has been deprecated, reviving this thread is useless. Still, I wanted to respond since having the exact same build is the premise of this entire discussion. The builds where always the exactly identical. The issue has nothing to do with code or setup, but it is caused by the differences in processing internal functions on different processors.
     
  40. lucasmontec

    lucasmontec

    Joined:
    Apr 7, 2015
    Posts:
    78
    For the people asking if the bug was fixed, use mirror. Mirror contains an implementation of the fix very similar to mine (suggested here).
     
    vis2k likes this.
  41. dmitryon

    dmitryon

    Joined:
    Jan 6, 2018
    Posts:
    8
    I'm using the unet right now, deprecated as it is, cross platform (Mac/PCx64/PCx32) and as different as the processes are, when builds were not identical I had this exact issue of mismatching IDs, but once the builds were built from the same source code version - the issue was fixed. Unity version 2018.3.7f1