Search Unity

Re-assigning NetworkInstanceId of an object spawned on client after being spawned on server

Discussion in 'Multiplayer' started by solarisn, Aug 27, 2017.

  1. solarisn

    solarisn

    Joined:
    Apr 6, 2016
    Posts:
    13
    I'm currently building a cross-platform multiplayer VR/AR sandbox. In the experience, users can draw strokes in 3D space using the XRLineRenderer component. I want each of the independent strokes to have a NetworkIdentity because I'm using the underlying network management to control user interaction on those objects after creation (i.e. being able to move the stroke after it has been placed). My object manager and prefab classes are also abstracted so that any type of user-created object can be treated the same way for core functionalities such as moving, spawning, and deleting.

    My issue is that I want clients to be able to spawn a line immediately in their local scene so that there is no latency when they start drawing. Currently, the client has to send a command telling the sever to spawn a new line for them before being able to start adding line segments. This creates round-trip latency before the controlling client can affect the line.

    I want to know if there is a way that I can spawn the line in the client's local scene and THEN send a command telling the server to spawn a new line for him. The tricky part comes in trying to register the local client's version of the line as the one that the server spawned after it receives the network spawn back from the server. Is there a way to do this?

    Would appreciate any help in solving this problem. It seems like this would be a very valuable thing to know how to do because it would allow me to create more responsive interfaces.

    Thanks in advance!

    EDIT: So I think I'm on the right track but I'm still missing something.
    It looks like using Custom Spawn Functions is a good way to control object spawning on clients but I don't see any good way to specify the spawnable prefab that I want to be spawned on the client. I have an array of prefabs for each spawnable stroke type (because there are different brushes with their own materials) and the stroke that is currently selected is tracked using the array's index on a player's class. It would be awesome if the spawn function delegate included a parameter for a MessageBase so that I could send along additional information from the server (like the index of the right prefab to use). I already overrode the AddPlayer() function which allows for a custom MessageBase. This gave me the ability to tell the server whether to spawn an ARKit player prefab or a SteamVR player prefab for that client based on the requesting platform. That functionality was AWESOME and I would LOVE to see it added for custom spawn functions. As it stands now, I would have to write a set of custom spawn/unspawn functions for each spawnable prefab rather than writing a single abstracted set.

    The other alternative is that I can make the currently selected brush stroke index a SyncVar on the player object and use that to determine the right prefab to spawn but that means that my Custom Spawn Functions have to exist on the player object and those functions have to be registered every time a new player is added which is waaaay less elegant.

    EDIT/SOLUTION: I actually think I just misunderstood the way that spawn function registration works. I thought that the NetworkHash128 used to register the function was the assetId of the managing spawn class and was used to determine which class to route the spawn function call to but it's actually the NetworkHash128 of the prefab to take over spawning responsibility for. I believe this means that I can register the same delegate functions multiple times to take over spawning responsibility for all my spawnable prefabs. That means I can simply use the NetworkHash128 passed along in the custom spawn function to look up the prefab associated with that hash and spawn it.

    I'll post the code after I implement it so that others can learn from my mistakes! I'm also planning to write a detailed blog post down the road to help people learn a bunch of really helpful things I've discovered about architecting platform agnostic multiplayer applications using UNET.
     
    Last edited: Aug 27, 2017
  2. Saishy

    Saishy

    Joined:
    Jun 3, 2010
    Posts:
    79
    I've been wanting to do something similar, spawning a monster client-side and server-side at the same time and syncing them after.

    Tho I think I will have to redo a lot of parts from the hlapi since messages to disabled objects or non-existing ones are not supported.