Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How to make Unity physics material work with netcode?

Discussion in 'Netcode for GameObjects' started by KristenBoyGames, Apr 27, 2022.

  1. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    I have to players, both have rigidbody, collider, network rigidbody, and the physics material. If i launch one player into the other the player that i launched bounces off of it like it should, but the other player stays still, If one player is just a prefab and isn't controlled by a client it works perfectly, but if both players are controlled by clients it doesn't. How do i fix this?
     
  2. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
  3. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    Ok so do i understand this correctly, to make it work the client has to write variables (like, direction, force) and send them to the server using NetworkVariables? and then the server reads them and uses them to move the clients player.

    My script takes the trajectory of the cursor and turns it into a direction and then puts it into a networkvariable, then the server reads it but moves the hosts player prefab instead.[/QUOTE]
     
  4. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    Yes exactly as long as all players are only moved on the host/server and have a NetworkRigidbody and NetworkTransform component on them you will get realistic collisions.
     
  5. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    ok, but how to call the function on a server to move the spesific client, as it is currently the host can move around, but the clients are frozen and when i check the rigidbody constraints are set to none
     
  6. Horst6667

    Horst6667

    Joined:
    Feb 5, 2018
    Posts:
    17
    On both clients and host (because the host is a client too) you could use a ServerRpc on the player's NetworkObject to communicate the player input to the host. Because a ServerRPC is executed only on the host's copy of the client's NetworkObject (not locally on the client), the movement and physics is done on the host and the result is synced back to all the clients.
    Rough example:
    Code (CSharp):
    1. [ServerRpc]
    2. public void MovePlayerServerRPC(Vector3 direction, Vector3 force)
    3. {
    4.   ApplyMovementToMyRigidBody(direction, force);
    5. }
    As long as the player's NetworkObject has a RigidBody, NetworkRigidBody and NetworkTransform attached, you should now see synchronized movement and physics on host and all clients.

    Have a look at the documentation on RPCs for more details and examples.
     
  7. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    here is the code
    Code (CSharp):
    1.  
    2. using System;
    3. using Unity.Collections;
    4. using Unity.Netcode;
    5. using UnityEngine;
    6.  
    7.  
    8.  
    9. public class NMOVE : NetworkBehaviour
    10. {
    11.     private void Update()
    12.     {
    13.         if (NetworkManager.Singleton.IsClient)
    14.         {
    15.             ClientUpdate();
    16.          
    17.         }
    18.         if (IsServer)
    19.         {
    20.            // MovePlayerServerRPC(force,power);
    21.         }
    22.    
    23.     }
    24.  
    25.  
    26.     private void Awake()
    27.     {
    28.         rb = GetComponent<Rigidbody>();
    29.         cam = Camera.main;
    30.         tl = GetComponent<linetrack>();
    31.      
    32.  
    33.     }
    34.  
    35.  
    36.    
    37.  
    38.     public int mousebutton;
    39.  
    40.     Vector3 startpoint;
    41.     Vector3 endpoint;
    42.     Vector3 startposition;
    43.  
    44.     Camera cam;
    45.     linetrack tl;
    46.     public float power;
    47.     Vector3 force;
    48.     public Vector3 minpower;
    49.     public Vector3 maxpower;
    50.     Rigidbody rb;
    51.     public static NetworkVariable<bool> firstpos = new NetworkVariable<bool>();
    52.  
    53.     void ClientUpdate()
    54.     {
    55.         if (Input.GetMouseButtonDown(mousebutton))
    56.         {
    57.             startpoint = cam.ScreenToWorldPoint(Input.mousePosition);
    58.             startpoint.y = 2;
    59.         }
    60.  
    61.         if (Input.GetMouseButton(mousebutton) && cooldown.cool)
    62.         {
    63.             Vector3 mousepoint = cam.ScreenToWorldPoint(Input.mousePosition);
    64.             Vector3 currentpoint = new Vector3(startpoint.x - mousepoint.x, 2, startpoint.z - mousepoint.z);
    65.             Vector3 hypotheticalpoint = new Vector3(gameObject.transform.position.x -
    66.                 currentpoint.x, gameObject.transform.position.y, gameObject.transform.position.z - currentpoint.z);
    67.             if (IsOwner)
    68.             {
    69.                 tl.RenderTheLine(gameObject.transform.position, hypotheticalpoint);
    70.             }
    71.          
    72.         }
    73.  
    74.         if (Input.GetMouseButtonUp(mousebutton) && cooldown.cool)
    75.         {
    76.             endpoint = cam.ScreenToWorldPoint(Input.mousePosition);
    77.             endpoint.y = 2;
    78.             startposition = gameObject.transform.GetChild(0).transform.position;
    79.             if (IsOwner)
    80.             {
    81.                 tl.EndLine();
    82.             }
    83.          
    84.             force = new Vector3(Mathf.Clamp(startpoint.x - endpoint.x, minpower.x, maxpower.x),
    85.             Mathf.Clamp(startpoint.y - endpoint.y, minpower.y, maxpower.y),
    86.             Mathf.Clamp(startpoint.z - endpoint.z, minpower.z, maxpower.z));
    87.          
    88.  
    89.             MovePlayerServerRPC(force,power);
    90.  
    91.  
    92.         }
    93.  
    94.     }
    95.  
    96.  
    97.  
    98.  
    99.     [ServerRpc(RequireOwnership = false)] // if i use "(RequireOwnership = false)" it moves the host and if i dont it gives an error saying that i cant write to it because im not an owner
    100.     public void MovePlayerServerRPC(Vector3 direction, float powerof)
    101.     {
    102.         rb.AddForce(direction*powerof,ForceMode.Impulse);
    103.     }
    the issue is that the client that isnt also a host cant move or will move the host, it depends on if i use (RequireOwnership = false) or not
     
  8. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    In Update, your check shouldn't be on
    NetworkManager.Singleton.IsClient
    , but instead
    IsLocalPlayer
    . As it is now, any client can provide input to any player.
     
  9. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    i changed it but it seems like the MovePlayerRPC never gets called on clients who arent hosts
     
  10. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    ok it turns out the the MovePlayerRpc does work but it doesnt add force to the player if the function is called by anyone other than the host
     
  11. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    Is
    power
    set on the player objects on all owners?
     
  12. KristenBoyGames

    KristenBoyGames

    Joined:
    May 23, 2021
    Posts:
    38
    yes, even if i change it to
    Code (CSharp):
    1. rb.AddForce(direction*10,ForceMode.Impulse);
    it still wont move.
    if i log the
    direction
    it doesnt log anything so i guess that the
    Code (CSharp):
    1. MovePlayerServerRPC(force,power);
    doesnt turn
    force
    into
    direction


    Edit: i dont know what i did but it suddenly it started working. i did not change the code.
     
    Last edited: May 10, 2022