Search Unity

Objects not syncing position properly between server and client

Discussion in 'Multiplayer' started by The-Game-Master, Apr 28, 2018.

  1. The-Game-Master

    The-Game-Master

    Joined:
    Aug 6, 2014
    Posts:
    54
    I have this code here, attached to my player:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5. using UnityEngine.UI;
    6.  
    7. public class gunControllerScript : NetworkBehaviour {
    8.  
    9.     [SyncVar]
    10.     public GameObject currentGun = null;
    11.  
    12.     public Transform gunHolder;
    13.     public RawImage gunImage; //UI Element for the gun's icon
    14.     public Text ammoText; //UI Element for the ammo text (Example: 12/30)
    15.     public Text weaponName; //The text box for the name of the weapon to appear in
    16.     private string[] ammos;
    17.  
    18.  
    19.  
    20.     // Use this for initialization
    21.     void Start () {
    22.         ammos = new string[2];
    23.         InvokeRepeating("updateAmmoCount", .5f, .5f);
    24.     }
    25.    
    26.     // Update is called once per frame
    27.     void Update () {
    28.         /*
    29.         if(currentGun != null)
    30.         {
    31.             currentGun.transform.position = gunHolder.transform.position;
    32.             currentGun.transform.rotation = gunHolder.transform.rotation;
    33.         }
    34.         */
    35.         if (isLocalPlayer)
    36.         {
    37.            
    38.             if (Input.GetButtonDown("Fire1"))
    39.             {
    40.                 if (currentGun != null)
    41.                 {
    42.                     currentGun.SendMessage("CmdFirePrimary");
    43.                     ammos = currentGun.GetComponent<GunScript>().GetAmmo();
    44.                     ammoText.text = ammos[0] + "/" + ammos[1];
    45.                 }
    46.             }
    47.             if (Input.GetButtonDown("Fire2"))
    48.             {
    49.                 if (currentGun != null)
    50.                 {
    51.                     currentGun.SendMessage("CmdFireSecondary");
    52.                     ammos = currentGun.GetComponent<GunScript>().GetAmmo();
    53.                     ammoText.text = ammos[0] + "/" + ammos[1];
    54.                 }
    55.             }
    56.             if (Input.GetButtonDown("Reload"))
    57.             {
    58.                 if (currentGun != null)
    59.                 {
    60.                     currentGun.SendMessage("Reload");
    61.                     ammos = currentGun.GetComponent<GunScript>().GetAmmo();
    62.                     ammoText.text = ammos[0] + "/" + ammos[1];
    63.                 }
    64.             }
    65.         }
    66.     }
    67.  
    68.     [Command]
    69.     public void CmdPickupWeapon(GameObject w)
    70.     {
    71.         if (currentGun != null)
    72.         {
    73.             currentGun.GetComponent<Rigidbody>().useGravity = true; //Make sure the currently-held weapon will drop to the ground
    74.             currentGun.GetComponent<Rigidbody>().isKinematic = false; //Make sure the currently-held weapon can move
    75.             currentGun.transform.SetParent(null); //Drop it from the hand (no longer relative to the hand, relative to the world instead)
    76.             currentGun.GetComponent<NetworkTransform>().enabled = true; //transformSyncMode = NetworkTransform.TransformSyncMode.SyncRigidbody3D;
    77.             foreach (BoxCollider bc in currentGun.GetComponents<BoxCollider>())
    78.             {
    79.                 bc.enabled = true; //Make sure it can be picked up and/or kicked around
    80.             }
    81.             foreach (BoxCollider b in currentGun.GetComponentsInChildren<BoxCollider>())
    82.             {
    83.                 b.enabled = true;
    84.             }
    85.             currentGun.GetComponent<NetworkIdentity>().RemoveClientAuthority(gameObject.GetComponent<NetworkIdentity>().connectionToClient);
    86.  
    87.         }
    88.         currentGun = w;
    89.         currentGun.transform.SetParent(gunHolder); //Attach the newly picked up weapon to the hand, and move it there
    90.         currentGun.transform.position = gunHolder.transform.position;
    91.         currentGun.transform.rotation = gunHolder.transform.rotation;
    92.         currentGun.GetComponent<Rigidbody>().useGravity = false;
    93.         currentGun.GetComponent<Rigidbody>().isKinematic = true;
    94.         currentGun.GetComponent<NetworkIdentity>().AssignClientAuthority(gameObject.GetComponent<NetworkIdentity>().connectionToClient);
    95.         //currentGun.GetComponent<NetworkTransform>().enabled = false; //transformSyncMode = NetworkTransform.TransformSyncMode.SyncTransform;
    96.         try
    97.         {
    98.             gunImage.texture = currentGun.GetComponent<GunScript>().GetGunIcon();
    99.             gunImage.material = null;
    100.         }
    101.         catch
    102.         {
    103.             Debug.Log("Failed image!");
    104.         }
    105.         try
    106.         {
    107.             weaponName.text = currentGun.GetComponent<GunScript>().GetName();
    108.         }
    109.         catch
    110.         {
    111.             Debug.Log("Failed text!");
    112.         }
    113.  
    114.         foreach (BoxCollider bc in currentGun.GetComponents<BoxCollider>())
    115.         {
    116.             bc.enabled = false; //Make sure it doesn't give us false weapon pickups, and doesn't continue to collide with the player
    117.         }
    118.  
    119.         foreach (BoxCollider b in currentGun.GetComponentsInChildren<BoxCollider>()){
    120.             b.enabled = false;
    121.         }
    122.     }
    123.  
    124.     public void updateAmmoCount()
    125.     {
    126.         if (currentGun != null)
    127.         {
    128.             ammos = currentGun.GetComponent<GunScript>().GetAmmo();
    129.             ammoText.text = ammos[0] + "/" + ammos[1];
    130.         }
    131.  
    132.     }
    133.  
    134.     public void OnTriggerStay(Collider col)
    135.     {
    136.         if (Input.GetButtonDown("Interact"))
    137.         {
    138.             if (isLocalPlayer)
    139.             {
    140.                 if (col.gameObject.CompareTag("Weapon"))
    141.                 {
    142.                     CmdPickupWeapon(col.gameObject);
    143.                     /*
    144.                     if (currentGun != null)
    145.                     {
    146.                         currentGun.GetComponent<Rigidbody>().useGravity = true; //Make sure the currently-held weapon will drop to the ground
    147.                         currentGun.GetComponent<Rigidbody>().isKinematic = false; //Make sure the currently-held weapon can move
    148.                         currentGun.transform.SetParent(null); //Drop it from the hand (no longer relative to the hand, relative to the world instead)
    149.                         currentGun.GetComponent<NetworkTransform>().transformSyncMode = NetworkTransform.TransformSyncMode.SyncRigidbody3D;
    150.                         foreach (BoxCollider bc in currentGun.GetComponents<BoxCollider>())
    151.                         {
    152.                             bc.enabled = true; //Make sure it can be picked up and/or kicked around
    153.                         }
    154.                     }
    155.                     currentGun = col.gameObject;
    156.                     currentGun.transform.SetParent(gunHolder); //Attach the newly picked up weapon to the hand, and move it there
    157.                     currentGun.transform.position = gunHolder.transform.position;
    158.                     currentGun.transform.rotation = gunHolder.transform.rotation;
    159.                     currentGun.GetComponent<Rigidbody>().useGravity = false;
    160.                     currentGun.GetComponent<Rigidbody>().isKinematic = true;
    161.                     currentGun.GetComponent<NetworkTransform>().transformSyncMode = NetworkTransform.TransformSyncMode.SyncTransform;
    162.                     foreach (BoxCollider bc in currentGun.GetComponents<BoxCollider>())
    163.                     {
    164.                         bc.enabled = false; //Make sure it doesn't give us false weapon pickups, and doesn't continue to collide with the player
    165.                     }
    166.                     */
    167.  
    168.                 }
    169.             }
    170.         }
    171.     }
    172. }
    173.  
    It works fine locally. It even works fine when the server player picks up a gun, as the client sees the gun being held and yada yada. When the client picks up a gun, however, the server sees the client holding the gun, but the client still sees the gun on the ground. After a little bit, the gun floats over and gitches out in the player's hand. When checking in the scene view, the gun actually doesn't become a child of gunHolder like it should. Again, this is only when clients attempt to pick up guns. They can still see the ammo count, and still fire the gun. Any idea why the position isn't showing up properly?
     
  2. Deleted User

    Deleted User

    Guest

    My Unet practice is a bit rusty, but I think you should get the desired results with this:

    Code (CSharp):
    1. [Command]
    2. public void CmdPickupWeapon(GameObject wep)
    3. {
    4.     RpcPickupWeapon(wep);
    5. }
    6.  
    7. [ClientRpc]
    8. public void RpcPickupWeapon(GameObject w)
    9. {
    10.     if (currentGun != null)
    11.         {
    12.             currentGun.GetComponent<Rigidbody>().useGravity = true; //Make sure the currently-held weapon will drop to the ground
    13.             currentGun.GetComponent<Rigidbody>().isKinematic = false; //Make sure the currently-held weapon can move
    14.             currentGun.transform.SetParent(null); //Drop it from the hand (no longer relative to the hand, relative to the world instead)
    15.             currentGun.GetComponent<NetworkTransform>().enabled = true; //transformSyncMode = NetworkTransform.TransformSyncMode.SyncRigidbody3D;
    16.             foreach (BoxCollider bc in currentGun.GetComponents<BoxCollider>())
    17.             {
    18.                 bc.enabled = true; //Make sure it can be picked up and/or kicked around
    19.             }
    20.             foreach (BoxCollider b in currentGun.GetComponentsInChildren<BoxCollider>())
    21.             {
    22.                 b.enabled = true;
    23.             }
    24.             currentGun.GetComponent<NetworkIdentity>().RemoveClientAuthority(gameObject.GetComponent<NetworkIdentity>().connectionToClient);
    25.         }
    26.         currentGun = w;
    27.         currentGun.transform.SetParent(gunHolder); //Attach the newly picked up weapon to the hand, and move it there
    28.         currentGun.transform.position = gunHolder.transform.position;
    29.         currentGun.transform.rotation = gunHolder.transform.rotation;
    30.         currentGun.GetComponent<Rigidbody>().useGravity = false;
    31.         currentGun.GetComponent<Rigidbody>().isKinematic = true;
    32.         currentGun.GetComponent<NetworkIdentity>().AssignClientAuthority(gameObject.GetComponent<NetworkIdentity>().connectionToClient);
    33.         //currentGun.GetComponent<NetworkTransform>().enabled = false; //transformSyncMode = NetworkTransform.TransformSyncMode.SyncTransform;
    34.         try
    35.         {
    36.             gunImage.texture = currentGun.GetComponent<GunScript>().GetGunIcon();
    37.             gunImage.material = null;
    38.         }
    39.         catch
    40.         {
    41.             Debug.Log("Failed image!");
    42.         }
    43.         try
    44.         {
    45.             weaponName.text = currentGun.GetComponent<GunScript>().GetName();
    46.         }
    47.         catch
    48.         {
    49.             Debug.Log("Failed text!");
    50.         }
    51.         foreach (BoxCollider bc in currentGun.GetComponents<BoxCollider>())
    52.         {
    53.             bc.enabled = false; //Make sure it doesn't give us false weapon pickups, and doesn't continue to collide with the player
    54.         }
    55.         foreach (BoxCollider b in currentGun.GetComponentsInChildren<BoxCollider>()){
    56.             b.enabled = false;
    57.         }
    58. }
    I hope this helps you out a bit!
    -PabloDiscobar
     
  3. The-Game-Master

    The-Game-Master

    Joined:
    Aug 6, 2014
    Posts:
    54
    Awesome, thank you! Does that mean I'd want to do the same for taking damage, call an RPC through a CmdFunction? I appreciate the help!
     
  4. Deleted User

    Deleted User

    Guest

    Yes you could do that. Then your code will look something like this:

    Code (CSharp):
    1. [Command]
    2. public void CmdTakeDamage(int dmg, healthscript target)
    3. {
    4.     RpcTakeDamage(dmg, target);
    5. }
    6.  
    7. [ClientRpc]
    8. public void RpcTakeDamage(int dmg, healthscript target)
    9. {
    10.     target.PlayerHealth -= dmg;
    11. }
     
  5. The-Game-Master

    The-Game-Master

    Joined:
    Aug 6, 2014
    Posts:
    54
    Cool, thanks. Now the object works fine on the client, but the client sees the host's gun flopping around (and sometimes the gun will freeze where the host was, and eventually come back to where the host moved after a few seconds). Any idea why that's happening? Thanks!