Search Unity

How to sync projectile spawning (and events in general)?

Discussion in 'Multiplayer' started by noise256, Sep 1, 2015.

  1. noise256

    noise256

    Joined:
    Apr 7, 2013
    Posts:
    22
    Hi everybody,

    I'm a bit stuck on how to handle this. Working on a top down space game. I have client side prediction working for the local player and that's fine. However, I'm not sure how to handle firing weapons (and syncing events in general).

    The way it works currently, is that when the player fires their weapons, it sends a [Command] to the server instance of the player object and the server then begins to network spawn projectiles. The problem with this is that since the player is operating in the future (client side prediction) and because of the latency of projectiles being spawned on the client, there is a significant delay. Enough of a delay that projectiles appear in the players previous position and are destroyed mid-flight on the local client when NetworkServer.Destroy() is called on the server.


    Solution 1: Server spawns projectile, projectile is then fast-forwarded on the local client, e.g.

    Code (CSharp):
    1. transform.position += transform.up * initialVelocity * (Network.time - commandTime)
    The problem here is that this is proving quite hard to implement. I can't currently spawn the projectiles with client authority (I don't have Unity Pro for 5.2) so the best way I could find of determining that the current instance of the projectile was on the local client is to do:

    Code (CSharp):
    1.         NetworkInstanceId projNetId = GetComponent<Ownable>().getOwner().GetComponent<NetworkBehaviour>().netId;
    2.         NetworkInstanceId connectionNetId = NetworkClient.allClients[0].connection.playerControllers[0].unetView.netId;
    3.  
    4.         if (projNetId == connectionNetId) {
    5.             //... fast forward
    6.         }
    Where owner is a variable storing a reference to the GameObject that created the projectile, i.e. the 'owner'. Even for me, this seems super hacky. Having the fast forward code in both Awake() and Start() seems to be problematic as transform.rotation still seems to be set to Quaternion.identity there and isn't set correctly yet (although might be doing something wrong here).

    Second of all, I'm not sending individual commands for every time the player fires, rather the player sends a single message to turn on their weapon and another to turn them off. Therefore I'm not quite sure how to determine commandTime and the best I can think to do is to just use the RTT but that seems fairly inaccurate.


    Solution 2: Network spawn the projectile on server but delay activation/movement there until some network time T when all clients have received and executed the spawn message.

    Again, I need to determine the correct time to wait for, should I just use the RTT or double the time it takes for the spawn message to be received? I'm not quite sure what the best way to delay activation of an object is either although I should be able to work this one out.


    This seems like it should be quite a common problem so I'm wondering how its usually solved. Is there a more common solution that the ones I've considered? I'm quite new to networking so I'd greatly appreciate help from anyone experienced with this kind of problem.

    Thank you.
     
    Last edited: Sep 1, 2015
  2. noise256

    noise256

    Joined:
    Apr 7, 2013
    Posts:
    22
    I removed the post to check out a bug but I've put it back again.