Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Can't figure out ClientRpcParams

Discussion in 'Netcode for GameObjects' started by chegodaevandrey, Dec 2, 2023.

  1. chegodaevandrey

    chegodaevandrey

    Joined:
    Oct 17, 2022
    Posts:
    4
    Hi there! I'm trying to make players stop aiming once they collide with a trigger. To make sure that the right players stop aiming, I use ClientRpcParams. It works to some extend but apparently I'm doing something wrong.

    Here's the code:

    Code (CSharp):
    1. public class SuppressorRect : NetworkBehaviour
    2. {
    3.  
    4.     // UI that gives the suppressed player an indication that they can't aim
    5.     [SerializeField] Transform suppressionUI;
    6.     // standard Starter Assets Inputs, just with NetworkBehaviour
    7.     [SerializeField] StarterAssetsInputs starterAssetsInputs;
    8.  
    9.  
    10.     // when a player shoots in the direction of other players, they get hit by a trigger collider
    11.     private void OnTriggerStay(Collider otherPlayersCollider)
    12.     {
    13.         NetworkObject otherPlayer = otherPlayersCollider.gameObject.GetComponentInParent<NetworkObject>();
    14.  
    15.         if (otherPlayer != null)
    16.         {
    17.             SuppressOtherPlayerServerRpc(otherPlayer.OwnerClientId);
    18.         }
    19.  
    20.     }
    21.  
    22.     [ServerRpc(RequireOwnership = false)]
    23.     public void SuppressOtherPlayerServerRpc(ulong otherPlayersClientId)
    24.     {
    25.         // getting the intput assets...
    26.         StarterAssetsInputs suppressedPlayerInputs = NetworkManager.Singleton.ConnectedClients[otherPlayersClientId]
    27.             .PlayerObject.GetComponent<StarterAssetsInputs>();
    28.  
    29.         // ...and disabling the ability to aim
    30.         if (suppressedPlayerInputs != null)
    31.         {
    32.             suppressedPlayerInputs.aim = false;
    33.         }
    34.  
    35.         // Executing the suppression on the Client
    36.         SuppressOtherPlayerClientRpc(new ClientRpcParams
    37.         {
    38.             Send = new ClientRpcSendParams
    39.             {
    40.                 TargetClientIds = new[] { otherPlayersClientId }
    41.             }
    42.         });
    43.     }
    44.  
    45.  
    46.  
    47.     [ClientRpc]
    48.     public void SuppressOtherPlayerClientRpc(ClientRpcParams clientRpcParams = default)
    49.     {
    50.         if (IsOwner) return; // just in case
    51.         Debug.Log("I am suppressed");  // this works
    52.         suppressionUI.gameObject.SetActive(true);  // this works
    53.        starterAssetsInputs.aim = false;  //this doesn't work
    54.  
    55.     }
    56.  
    57.  
    58. }
    I'm quite curious what I'm doing wrong, because the aim doesn't get interrupted on Client in the runtime (Host's aim gets interrupted just fine).

    If the case is not clear enough I'm happy to provide you with more information. Thank you!
     
  2. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    244
    Here is what I would do to handle this type of scenario.
    Not sure if you wanted other players to key off of this or not, but the below adjusted and new component scripts are taking into consideration that the server dictates the trigger and notifies the other player via the PlayerSuppressionHandler.SuppressAim method that sets a NetworkVariable.
    Each player registers to listen to changes in NetworkVariable relative to their own local player instance.
    The StarterAssetsInputs.aim is set based on the inverse of the m_IsAimSuppressed.Value.
    You might need to make it such that it only sets StarterAssetsInputs.aim to false if m_IsAimSuppressed.Value is true, otherwise it allows the normal player input flow to occur.

    I sort of gutted your SuppressorRect and migrated most of the suppression logic into the PlayerSuppressionHandler component.

    Take a look and see if this makes sense, if so create the PlayerSuppressionHandler, adjust your SuppressorRect, and see if that gets you closer to your goals? (This is all pseudo code so you might need to make some adjustments)

    Code (CSharp):
    1.  
    2. /// <summary>
    3. /// Create a component from this and add to the player prefab
    4. /// </summary>
    5. public class PlayerSuppressionHandler : NetworkBehaviour
    6. {
    7.     [SerializeField] Transform suppressionUI;
    8.     // standard Starter Assets Inputs, just with NetworkBehaviour
    9.     [SerializeField]
    10.     private StarterAssetsInputs m_starterAssetsInputs;
    11.     public float MaxSupressionTime = 3.0f;
    12.     private float m_SupressionTime;
    13.     private NetworkVariable<bool> m_IsAimSuppressed = new NetworkVariable<bool>();
    14.     public void SuppressAim(bool suppressed)
    15.     {
    16.         if (!IsSpawned || !IsServer)
    17.         {
    18.             return;
    19.         }
    20.         m_IsAimSuppressed.Value = suppressed;
    21.         // Continue to extend the suppression time until this method is no longer invoked or
    22.         // the m_SupressionTime has passed
    23.         m_SupressionTime = suppressed ? Time.realtimeSinceStartup + m_SupressionTime : 0.0f;
    24.     }
    25.     public override void OnNetworkSpawn()
    26.     {
    27.         if (IsOwner)
    28.         {
    29.             m_IsAimSuppressed.OnValueChanged += OnIsAimSuppressed;
    30.         }
    31.         base.OnNetworkSpawn();
    32.     }
    33.     private void OnIsAimSuppressed(bool previous, bool current)
    34.     {
    35.         if (IsOwner)
    36.         {
    37.             var message = current ? "I am suppressed!" : "I am no longer suppressed.";
    38.             Debug.Log(message);
    39.             suppressionUI.gameObject.SetActive(current);
    40.         }
    41.     }
    42.     private void Update()
    43.     {
    44.         if (!IsSpawned || (!IsServer && !IsOwner))
    45.         {
    46.             return;
    47.         }
    48.         if (IsServer)
    49.         {
    50.             // Reset the suppressed flag for the player if they are no longer suppressed
    51.             if (m_IsAimSuppressed.Value && m_SupressionTime < Time.realtimeSinceStartup)
    52.             {
    53.                 SuppressAim(false);
    54.             }
    55.         }
    56.         if (IsOwner)
    57.         {
    58.             // Supress the player input aim if not already being suppressed
    59.             // Not sure what the m_starterAssetsInputs.aim is and if that is a key input or not.
    60.             // You could do something like:
    61.             m_starterAssetsInputs.aim = !m_IsAimSuppressed.Value;
    62.             // If not, then you can add additional logic for this based on the m_IsAimSuppressed.Value.
    63.         }
    64.     }
    65. }
    66. public class SuppressorRect : NetworkBehaviour
    67. {
    68.     // when a player shoots in the direction of other players, they get hit by a trigger collider
    69.     private void OnTriggerStay(Collider otherPlayersCollider)
    70.     {
    71.         // My assumption is the server will be the authority on this?
    72.         if (!IsServer)
    73.         {
    74.             return;
    75.         }
    76.         var otherPlayer = otherPlayersCollider.gameObject.GetComponentInParent<PlayerSuppressionHandler>();
    77.         if (otherPlayer)
    78.         {
    79.             otherPlayer.SuppressAim(true);
    80.         }
    81.     }
    82. }
    83.  
     
    Last edited: Dec 2, 2023
  3. chegodaevandrey

    chegodaevandrey

    Joined:
    Oct 17, 2022
    Posts:
    4
    Thank you, I'll give it a try and let you know about the results!