Search Unity

Network.Instantiate & Destroy buffered RPC problem

Discussion in 'Multiplayer' started by hugettini, May 17, 2015.

  1. hugettini

    hugettini

    Joined:
    Apr 1, 2013
    Posts:
    19
    This is an old problem discussed in many places, but none of the solutions fixes it in my case.

    **Problem:**

    I have a game which creates some temporary objects (lasers). When the objects expire they should be gone for good, however any client which joins after they expire, but before the player which created them leaves, gets the (already destroyed) objects sent to them by the server. I've already been down a couple of trails in trying to fix this (it's well documented & discussed), currently I use the solution referenced at (http://answers.unity3d.com/questions/628787/properbest-way-to-instantiate-and-destroy-with-uni.html) to remove the buffered RPC instantiate events from the server using

    if (Network.isServer) { Network.RemoveRPCs (viewID); }

    But still when a new client joins the destroyed objects are sent to it.
    I've built a little sandbox to demonstrate the problem;

    - Start the server
    - Start the client (Client 1)
    - Start a second instance of the client (Client 2)
    - In Client 1 press the fire button 3 times at 1 second intervals
    - Wait 5 seconds for the spheres to expire
    - Keep the Server and Client 1 running, but close down Client 2
    - Start up Client 2 again, when it re-joins it receives the 3 spheres

    Fairly obviously the 3 spheres are removed by the server when I call Network.RemoveRPCs(Player) Network.DestroyPlayerObjects(Player)
    But not when the server executes Network.RemoveRPCs(viewId) which is what I need.
    The behavior I see is almost as if the Network.RemoveRPCs(viewId); call is broken (which it is documented as having been for some time, but reportedly fixed from Unity 4.3-ish).

    I am using Unity 5.0.1.

    Any help would be greatly appreciated.
     

    Attached Files:

  2. hugettini

    hugettini

    Joined:
    Apr 1, 2013
    Posts:
    19
    I've investigated a little bit more.

    And I've realized if the Network.Instantiate function is called on the server, instead on any client, the app works great. (Then you've to remove the rpcs as usual)

    The question would be, is it possible to instantiate it from any client, and make the removeRPCs work?

    Thank you!
     

    Attached Files:

  3. hugettini

    hugettini

    Joined:
    Apr 1, 2013
    Posts:
    19
    Ok, finally I found a partial solution.

    The best way to do it is:

    1. Allocate a new ViewID
    NetworkViewID viewID = Network.AllocateViewID();

    2. Instantiate every projectile on each player using a RPC (not using Network.Instantiate) and set the allocated networkviewID
    GetComponent<NetworkView>().RPC("InstantiateProjectile", RPCMode.AllBuffered, viewID);

    [RPC]
    public void InstantiateProjectile(NetworkViewID viewID){
    GameObject Sphere = Instantiate(PrefabToFire, new Vector3(0, 0, 2), Quaternion.identity) as GameObject;
    Sphere.GetComponent<NetworkView> ().viewID = viewID;
    }

    3. Destroying the object will also have to destroy the buffered rpcs on the create
    Network.RemoveRPCs(GameObject.Find("/Client").GetComponent<NetworkView> ().viewID);

    This only servers as long you only instantiate 1 object at a time (wich is my case)
     

    Attached Files: