Search Unity

  1. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  6. Unity 2017.3 beta is now available for download.
    Dismiss Notice

Unity Multiplayer AddForce on rigidbodies not syncing across network.

Discussion in 'Multiplayer Networking' started by pmurph03, Aug 16, 2015.

  1. pmurph03

    pmurph03

    Joined:
    Mar 17, 2014
    Posts:
    44
    I have a network identity component along with a network transform component to sync rigidbody 3d attached to a gameobject (in this case a sphere). I have also added the object with the rigidbody to the list of spawnable prefabs on the networkmanager object/component. The rigidbody.AddForce is being called from a different gameobject networkbehaviour script this gameobject also has an attached network identity

    When AddForce is called by the host/server, the force is added and the rigidbody updates on both the client and sever as expected.

    When a client calls AddForce, it does not add any force on the server. On the client it appears to add the force for a short amount of time (on the client game only) before the object the force was added to reverts to its original position. However, running into the rigidbody with the client player does cause interactions between the colliders to reflect on both client and server, resulting in movement of the rigidbody on both. I have tried moving the AddForce calls to seperate [ClientRPC] and [Command] functions attached to a networkbehaviour inheriting script, which has no effect on the result of calling AddForce.

    I'm sure I'm probably missing something obvious, but I can't figure out how to get this part of networking to work. I appreciate any help that can be given.
     
  2. matis1989

    matis1989

    Joined:
    Mar 23, 2011
    Posts:
    160
    exact SAME problem here :(
     
  3. SuperNeon

    SuperNeon

    Joined:
    Mar 16, 2014
    Posts:
    83
    You have to add the force in the command function (server side).
    Can you provide some code ?
     
    pmurph03 likes this.
  4. pmurph03

    pmurph03

    Joined:
    Mar 17, 2014
    Posts:
    44
    (note this code is kind of weird due to trying to figure out what isn't working)
    In an OnTriggerEnter (attached to player object, inherits from network behaviour) I have:
    Code (csharp):
    1.  
    2.   if (m_ball_network != null)
    3.                 {
    4.                     if (m_networkIdentity.isServer)
    5.                     {
    6.                         Debug.Log("is server");
    7.                         m_ball_network.RpcAddClientForce(ForceMode.Impulse, forceDir, forceMult);
    8.                     }
    9.                     else if (m_networkIdentity.isClient)
    10.                     {
    11.                         Debug.Log("is client");
    12.                         m_ball_network.CmdAddForce(ForceMode.Impulse, forceDir, forceMult);
    13.                     }
    14.                     else
    15.                     {
    16.                         Debug.Log("not client nor server");
    17.                         m_ball_network.CmdAddForce(ForceMode.Impulse, forceDir, forceMult);
    18.                         //ball_RigidBody.AddForce(forceDir * forceMult, ForceMode.Impulse);
    19.                     }
    20.              
    21.                 }
    22.  
    These functions calls on m_ball_network (attached to the component with the rigidbody, inherits from networkbehaviour) are:
    Code (csharp):
    1.  
    2.  
    3. [Command]
    4.     public void CmdAddForce(ForceMode forcemode, Vector3 forcevector, float multiplier)
    5.     {
    6.         Debug.Log("command add force");
    7.         ball_rigidBody.AddForce(forcevector*multiplier, forcemode);
    8.     }
    9.  
    10.     [ClientRpc]
    11.     public void RpcAddClientForce(ForceMode forcemode, Vector3 forcevector, float multiplier)
    12.     {
    13.         Debug.Log("clientrpc add force");
    14.         ball_rigidBody.AddForce(forcevector*multiplier, forcemode);
    15.     }
    16.  
    Note that for both of the games that are running, upon hitting the ball they both log the "not client nor server" message (which is why that was changed to a command.) And I guess could be a part of the problem? I don't know. I feel like i've tried everything I can think of.

    Just tried moving the command to the same script that the OnTriggerEnter is in, and it has the same result as before.

    Got a workaround for detecting isServer and isClient while running both instances on the same computer by combining the isClient, isServer checks with a hasAuthority check as well, and that part seems to work. Except that using the Debug.Log shows that neither the ClientRPC or Command functions are actually being called (once they were moved to the same script that on trigger is in). Using both functions does call the command in the separate m_ball_network script component... Now its too late for me to continue to get it working, so maybe tomorrow.

    I do appreciate any help anyone can give me.
     
    Last edited: Aug 21, 2015
  5. SuperNeon

    SuperNeon

    Joined:
    Mar 16, 2014
    Posts:
    83
    Do you have a NetworkTransform to sync the position of the ball ?
    If yes: you don't have to apply the force on the client. It will be applied by the server and replicated by the NetworkTransform
    If no: the physics is not deterministic. you are not sure to have the same result.

    It seems your gameobject is not spawned by the server. Cmd or Rpc wont be called properly.
    How do you instantiate this object ?
     
    pmurph03 likes this.
  6. pmurph03

    pmurph03

    Joined:
    Mar 17, 2014
    Posts:
    44
    Yes there is a network transform component attached to the gameobject, as well as a network identity component. I have tried all the sync options including syncing rigidbody3d, and transform.

    The ball is a part of the multiplayer scene itself and as I understand it from the documentation NetworkServer.SpawnObjects is called to activate it on scene load. The prefab in the scene is also linked to the spawnable objects of the NetworkManager component in the network scene as well.



    I believe I just got it working.

    I believe the problem was that the script that does the Commands and Rpc to AddForce was not located directly on the base prefab of the player prefab that is identified as the player in the network manager.

    The OnTriggerEnter function was in a script that was attached to a gameobject that was a part of the player prefab, but down in its hierarchy. Although this gameobject also had a networkidentity component attached, and the script inherited from network behaviour, it appears to be what was causing the issue. Using the OnTriggerEnter function on that gameobject, and within that function, having it call a CmdAddForce function that I added to a player networking script that also controls animation syncing on the base player prefab seems to have solved the issue.

    Thank you for the help Neon. I appreciate it.

    Edit: I would also like to note that this was experienced in version 5.1.0f3, which I had mistakenly assumed was the latest version because inside the editor the check for updates reported that it was the latest version. Figured this out when I ran into other problems involving multiple network components on the same game object, and clientrpc calls being invoked out of order, which was fixed in 5.1.2.
     
    Last edited: Aug 27, 2015
    SuperNeon likes this.
  7. omerselman

    omerselman

    Joined:
    Mar 5, 2016
    Posts:
    11

    Hi mate;
    I just have the same problem. I have a networkbehaviour script attached to player prefabs checking the collisions and executing the addforce commands, also it edits the owner value of the ball script which is basicly i use for the positioning the ball and collided player. Player collides with ball and player scripts edits owner value of the ball and ball is positioning itself with that value. when player kicks the ball server player is doing all okay. client player has that odd behaviour which applies minimum force to ball.
    how did you solve this issue?