Search Unity

Unity Multiplayer AddForce on rigidbodies not syncing across network.

Discussion in 'Connected Games' started by pmurph03, Aug 16, 2015.

  1. pmurph03


    Mar 17, 2014
    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


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


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


    Mar 17, 2014
    (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):
    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.                     }
    21.                 }
    These functions calls on m_ball_network (attached to the component with the rigidbody, inherits from networkbehaviour) are:
    Code (csharp):
    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.     }
    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.     }
    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


    Mar 16, 2014
    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 ?
    megabrobro and pmurph03 like this.
  6. pmurph03


    Mar 17, 2014
    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


    Mar 5, 2016

    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?