Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Script only works on host

Discussion in 'Netcode for GameObjects' started by mcdoggus14, Jun 23, 2023.

  1. mcdoggus14

    mcdoggus14

    Joined:
    May 24, 2023
    Posts:
    5
    I have been trying to make a grabbing script for my stickman game, but this script that I'm using only works for the host. I'm not exactly sure what the problem is because I'm very new to this, roughly a month into Unity now. If someone could find the issue and maybe a solution that would be really great!

    Code (CSharp):
    1. using Unity.Netcode;
    2. using UnityEngine;
    3.  
    4. public class LeftHandGrab : NetworkBehaviour
    5. {
    6.     [SerializeField] private KeyCode mouseButton;
    7.     private PlayerController playerController;
    8.     public bool hold;
    9.     public bool holding;
    10.     public Rigidbody2D rb;
    11.     public FixedJoint2D fj;
    12.  
    13.     private void Awake()
    14.     {
    15.          playerController = GetComponentInParent<PlayerController>();
    16.     }
    17.     private void Update()
    18.     {
    19.         if (!IsLocalPlayer) return; // Check if is LocalPlayer
    20.         if (Input.GetKey(mouseButton) && !playerController.stopHoldingLeft) //Check if mouseButton is down and if another script allows me to start holding something
    21.         {
    22.             hold = true;
    23.         }
    24.         else
    25.         {
    26.             hold = false;
    27.             holding = false; //Player is not holding something
    28.             if (GetComponent<FixedJoint2D>() != null) //If there is a FixedJoint2D...
    29.             {
    30.                 Destroy(GetComponent<FixedJoint2D>()); //Remove FixedJoint2D
    31.             }
    32.             if (Input.GetKeyUp(mouseButton) && playerController.stopHoldingLeft) //Check if mouseButton is up and if another script doesn't allow me to start holding something
    33.             {
    34.                 playerController.stopHoldingLeft = false; //Allows player to be able to start holding something
    35.             }
    36.         }
    37.     }
    38.  
    39.     private void OnTriggerEnter2D(Collider2D collision)
    40.     {
    41.         if (!IsLocalPlayer || !hold || collision.isTrigger || holding) return; // Check if is LocalPlayer, player is able to hold, the Collision is not a trigger and the player is not already holding something.
    42.         rb = collision.GetComponent<Rigidbody2D>(); // rb = Rigidbody2D of collision
    43.         holding = true; //The player is holding something
    44.         if (rb != null) //If there is a Rigidbody2D in the collision
    45.         {
    46.             LinkFJServerRpc();
    47.         }
    48.         else
    49.         {
    50.             FJServerRpc();
    51.         }
    52.     }
    53.     [ServerRpc]
    54.     private void LinkFJServerRpc()
    55.     {
    56.         fj = transform.gameObject.AddComponent(typeof(FixedJoint2D)) as FixedJoint2D;
    57.         fj.connectedBody = rb; //FixedJoint2D connects to RigidBody2D
    58.     }
    59.     [ServerRpc]
    60.     private void FJServerRpc()
    61.     {
    62.         fj = transform.gameObject.AddComponent(typeof(FixedJoint2D)) as FixedJoint2D;
    63.     }
    64. }
     
  2. Mj-Kkaya

    Mj-Kkaya

    Joined:
    Oct 10, 2017
    Posts:
    153
    Hi @mcdoggus14 ,
    I cound't understand what part of script should be run ?
    But ,as I see to your script "LinkFJServerRpc()" and "FJServerRpc()" methods only run on Host/Server side and don't run client side.
    This structure can be a problem, because "ServerRPC" run just on Host side.
     
  3. mcdoggus14

    mcdoggus14

    Joined:
    May 24, 2023
    Posts:
    5
    I think I stuffed up this code as I was messing around with different ways to fix it before. I think the serverRpc attribute is supposed to have RequireOwnership = false or something, still doesn't work. Here is what it is supposed to do and what the host does:

    https://imgur.com/a/gNKWrFt

    And here is what the client does:

    https://imgur.com/a/oCE2YaL

    Hopefully that is what you needed to know?
     
  4. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,382
    [ServerRpc]
    will send a message to run that function on the server. Only the server runs that code.

    [ClientRpc]
    will send a message to run that function on client(s).

    You should get acquainted with the docs, as they do a pretty decent job of explaining these concepts you're struggling with.
     
  5. Mj-Kkaya

    Mj-Kkaya

    Joined:
    Oct 10, 2017
    Posts:
    153
    Do you use "Network Rigidbody2D" component?
    If you want to make networkObject you have to use network components.
     
  6. mcdoggus14

    mcdoggus14

    Joined:
    May 24, 2023
    Posts:
    5
    If I don't do a ServerRpc, the fixedJoint2D is only added on the client which doesn't do anything. I need a fixedJoint2D to be created and then set the connectedbody to the rigidbody it is colliding with. How would I go about doing that?
     
  7. mcdoggus14

    mcdoggus14

    Joined:
    May 24, 2023
    Posts:
    5
    Yes, I have set a NetworkRigidbody2D component.
     
  8. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,382
    In order to do this correctly in a networked architecture, you need to understand the workflow. The docs I linked explain the idea. Take the time to read them. When you understand what you need to do then you can apply it to everything, not just joints.
     
  9. mcdoggus14

    mcdoggus14

    Joined:
    May 24, 2023
    Posts:
    5
    I just spent a week away and when I got back I realised that I'm an idiot. I already knew everything I needed to get it working but I just couldn't figure it out. My solution was to use a separate script that only runs on the server and just send over the variable to tell the server my mouse button is down. I can't believe this took so much time.