Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Bug Joysticks isn't working for the client but for the host

Discussion in 'Multiplayer' started by nargis23, May 26, 2024.

  1. nargis23

    nargis23

    Joined:
    Jul 14, 2023
    Posts:
    8
    Hi,
    I'm developing a multiplayer Third person shooter game. The code was working from both host and client side while controlling from mouse/keyboard. Since, this will be a mobile multiplayer(android) game so I've added a "FixedJoysticks" to control game from mobile . But, the problem is that host can control his own player through the joysticks but client cannot, player is not moving for the client with the joysticks. On the other hand, client can move the player through joysticks when the host leaves. I don't know why this happened. I'm learning multiplayer but facing this problem. I have searched over the internet but still didn't get the solution. Hope you will help me in this case. Will be gladed.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using Unity.Netcode;
    4. using UnityEngine;
    5.  
    6. public class ThirdpersonMovementNet : NetworkBehaviour
    7. {
    8.     public CharacterController controller;
    9.     public Transform cam;
    10.     public float speed;
    11.     public float speed2 = 20f;
    12.     public float turnSmoothTime = 0.1f;
    13.     private float turnSmoothVelocity;
    14.  
    15.     [SerializeField] private float positionRange = 3f;
    16.     [SerializeField] private float positionRangeUpwards = 1082.0626f;
    17.     [SerializeField] private float positionRangeUpwards2 = 682.0626f;
    18.     [SerializeField] private float gravity = -9.81f;
    19.     [SerializeField] private float jumpHeight = 1.0f;
    20.  
    21.     [SerializeField] private Animator anim;
    22.     private Vector3 velocity;
    23.     private bool isGrounded;
    24.  
    25.  
    26.     public Transform groundCheck;
    27.     public float groundDistance = 0.4f;
    28.     public LayerMask groundMask;
    29.  
    30.     public FixedJoystick fixedJoystick;
    31.  
    32.     /* public override void OnNetworkSpawn()
    33.      {
    34.  
    35.     UpdatePosServerRpc();
    36.  
    37. }*/
    38.  
    39.     public override void OnNetworkSpawn()
    40.     {
    41.         if (IsServer)
    42.         {
    43.             Vector3 newPosition = new Vector3(Random.Range(-positionRange, positionRange), Random.Range(positionRangeUpwards, positionRangeUpwards2), Random.Range(-positionRange, positionRange));
    44.             transform.position = newPosition;
    45.             transform.rotation = Quaternion.Euler(0, 180, 0);
    46.             UpdatePosClientRpc(newPosition);
    47.          
    48.         }
    49.      
    50.     }
    51.  
    52.  
    53.     private void Start()
    54.     {
    55.  
    56.      /*   Cursor.lockState = CursorLockMode.Locked;*/
    57.  
    58.     }
    59.  
    60.     void Update()
    61.     {
    62.         if (!IsOwner && !MyGManager.Instance.IsGamePlaying()) return;
    63.  
    64.         isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    65.  
    66.         if (isGrounded && velocity.y < 0)
    67.         {
    68.             velocity.y = -2f;
    69.             anim.SetBool("ShouldFly", false);
    70.             anim.SetBool("Parachute", false);
    71.             if (anim.GetBool("ShouldJump"))
    72.             {
    73.                 anim.SetBool("ShouldJump", false);
    74.             }
    75.  
    76.             // Ensure the player goes back to idle when grounded
    77.             if (!anim.GetBool("IsRunning"))
    78.             {
    79.                 anim.SetBool("IsRunning", false);
    80.             }
    81.         }
    82.         /*
    83.                 float horizontal = Input.GetAxisRaw("Horizontal");
    84.                 float vertical = Input.GetAxisRaw("Vertical");*/
    85.  
    86.         float horizontal = fixedJoystick.Horizontal;
    87.         float vertical= fixedJoystick.Vertical;
    88.  
    89.  
    90.  
    91.         Vector3 dir = new Vector3(horizontal, 0f, vertical).normalized;
    92.  
    93.         if (dir.magnitude >= 0.1f)
    94.         {
    95.             float targetAngle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
    96.             float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
    97.             transform.rotation = Quaternion.Euler(0f, angle, 0f);
    98.             Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
    99.             controller.Move(moveDir.normalized * speed * Time.deltaTime);
    100.             anim.SetBool("IsRunning", true);
    101.         }
    102.         else
    103.         {
    104.             anim.SetBool("IsRunning", false);
    105.         }
    106.  
    107.         if (isGrounded && Input.GetButtonDown("Jump"))
    108.         {
    109.             velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    110.             anim.SetBool("ShouldJump", true);
    111.         }
    112.  
    113.         if (transform.position.y > 420 && velocity.y < 0)
    114.         {
    115.             anim.SetBool("ShouldFly", true);
    116.  
    117.             Vector3 moveDirection = cam.forward * vertical + cam.right * horizontal;
    118.             moveDirection.y = 0f; // Ensure no vertical movement
    119.             moveDirection.Normalize(); // Normalize to ensure consistent speed
    120.             controller.Move(moveDirection * speed2 * Time.deltaTime);
    121.         }
    122.         else if (transform.position.y <= 420)
    123.         {
    124.             anim.SetBool("ShouldFly", false);
    125.             anim.SetBool("Parachute", true);
    126.         }
    127.  
    128.         // Ensure parachute animation stops when grounded
    129.         if (isGrounded)
    130.         {
    131.             anim.SetBool("Parachute", false);
    132.         }
    133.  
    134.         velocity.y += gravity * Time.deltaTime;
    135.         controller.Move(velocity * Time.deltaTime);
    136.     }
    137.  
    138.  
    139.     [ServerRpc(RequireOwnership = false)]
    140.     private void UpdatePosServerRpc(Vector3 newPosition)
    141.     {
    142.         UpdatePosClientRpc(newPosition);
    143.     }
    144.  
    145.     [ClientRpc]
    146.     private void UpdatePosClientRpc(Vector3 newPosition)
    147.     {
    148.         transform.position = newPosition;
    149.         transform.rotation = Quaternion.Euler(0, 180, 0);
    150.     }
    151.  
    152. }
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,929
    Since this is Unity's Netcode there's a subforum specifically for NGO. ;)

    You can just use NetworkTransform to sync positions. You don't have to manually write RPCs to do this.
    Then you can make a subclass ClientAuthoritativeNetworkTransform which has the authority property overriden, so that the client can change the transform rather than the server.

    Since you check for IsOwner the most likely cause seems to be that the client isn't actually the owner of the object.

    When the host leaves the network session ends. Normally you'd reset the game at this point but I suppose here it just keeps on running offline and I can only assume that because of it the former client now has full authority over everything.