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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Smooth networking movment?

Discussion in 'Multiplayer' started by Decoder46, Jun 13, 2015.

  1. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    Hello guys I am new to unity, hope I will manage to explain myself properly...

    So I have simple game with simple network system but the movement is laggy even in the same computer :/

    so this is what i got:

    movment:
    Code (CSharp):
    1. input = new Vector3 (Input.GetAxisRaw ("Horizontal"), 0, Input.GetAxisRaw ("Vertical"));
    2.             if (GetComponent<Rigidbody> ().velocity.magnitude < maxSpaad) {
    3.                 GetComponent<Rigidbody> ().AddRelativeForce (input * moveSpeed);
    4.             }
    Well yeah nothing more to show :D. Just want to make that players will see my cube more smoothly.

    If you need more information please tell me and i will add.
     
  2. 5vStudios

    5vStudios

    Joined:
    May 9, 2015
    Posts:
    106
    That piece of code is not enough for us to help you, you should have use of [Command], [ClientCallback] and [SyncVar]

    anyway, here is a simple script that syncs position

    Code (CSHARP):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using System.Collections;
    4. using UnityStandardAssets.Characters.FirstPerson;
    5.  
    6. public class PlayerNetwork : NetworkBehaviour
    7. {
    8.  [SyncVar] private Vector3 SyncedPosition;
    9.  
    10.  [SerializeField] Transform PlayerTransform;
    11.  [SerializeField] float PlayerSyncRate = 15f;
    12.  
    13.  void FixedUpdate()
    14.  {
    15.  SendPosition();
    16.  ReceivePosition();
    17.  }
    18.  
    19.  [Command]
    20.  void CmdSendPosition(Vector3 Position)
    21.  {
    22.  SyncedPosition = Position;
    23.  }
    24.  
    25.  [ClientCallback]
    26.  void SendPosition()
    27.  {
    28.  if (isLocalPlayer)
    29.  {
    30.  CmdSendPosition(transform.position);
    31.  }
    32.  }
    33.  
    34.  void ReceivePosition()
    35.  {
    36.  if (!isLocalPlayer)
    37.  {
    38.  transform.position = Vector3.Lerp(transform.position, SyncedPosition, Time.deltaTime * PlayerSyncRate);
    39.  }
    40.  }
    41. }
     
    Decoder46 likes this.
  3. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    Thanks for your help.

    where should I put it?
     
  4. Necromantic

    Necromantic

    Joined:
    Feb 11, 2013
    Posts:
    116
    You don't actually have to send the command to set the position if you have set the position as a SyncVar.

    I have a "Logic" script like this:
    Code (CSharp):
    1.  
    2.     [SyncVar]
    3.     private Vector2 movement;
    4.  
    5.     public void setMovement(Vector2 movement) {
    6.         this.movement = movement;
    7.     }
    8.  
    9.     void FixedUpdate() {
    10.         rigidbody.MovePosition(rigidbody.position + movement * Time.deltaTime);
    11.     }
    12.  
    And a Control script like this:
    Code (CSharp):
    1.  
    2.     void Update() {
    3.         if (!isLocalPlayer)
    4.             return;
    5.  
    6.         Vector2 movement = Vector2.zero;
    7.         if (Input.GetKey(KeyCode.W)
    8.             movement.y += 1;
    9.         if (Input.GetKey(KeyCode.S)
    10.             movement.y -= 1;
    11.  
    12.         paddleLogic.setMovement(movement * speed);
    13.     }
    14.  
    (A lot of stuff omitted)
    And that seems to work pretty well as a minimalistic movement synchronization example.
     
  5. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    Well I tryed it but it does not working well. iput it in the player object.

    I notice that he always return false in
    Code (CSharp):
    1. isLocalPlayer
    This is how I define a player:
    Code (CSharp):
    1. Network.Instantiate (playerPrefs[numbersOfPlayers],
    2.                              list[numbersOfPlayers].transform.position,
    3.                              Quaternion.Euler(new Vector3(0,270,0)),0);
     
  6. 5vStudios

    5vStudios

    Joined:
    May 9, 2015
    Posts:
    106
    does your player object have a 'NetworkIdentity' component attached ?
     
  7. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    Yes it is automatic attach to him when i added the script.

    Maybe I need to spawn the player differently?
     
  8. 5vStudios

    5vStudios

    Joined:
    May 9, 2015
    Posts:
    106
    Code (csharp):
    1. class MyManager : NetworkManager
    2. {
    3.    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    4.    {
    5.       GameObject player = (GameObject)Instantiate(playerPrefab, Vector3.Zero, Quaternion.Identity);
    6.       player.GetComponent<Player>().color = Color.Red;
    7.       NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
    8.    }
    9. }
     
    Last edited: Jun 15, 2015
  9. LovattoStudio

    LovattoStudio

    Joined:
    Feb 11, 2015
    Posts:
    15
    For instance Player you can use this:

    Firts you need regist the player connection in the host, you need call like this:
    Code (csharp):
    1. ClientScene.AddPlayer(0);
    then, this function will be called when player registration has been completed:
    Code (csharp):
    1. public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    When this function is called is the "green light" to instantiate the player, you can do it directly from the same function like this:
    Code (csharp):
    1.  
    2. /// <summary>
    3.     /// Call when add a player to the host
    4.     /// </summary>
    5.     /// <param name="conn"></param>
    6.     /// <param name="playerControllerId"></param>
    7.     public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    8.     {
    9.        
    10.         GameObject p;
    11.         Transform startPosition = GetStartPosition();
    12.         p = (GameObject)UnityEngine.Object.Instantiate(m_playerPrefab, startPosition.position, startPosition.rotation);
    13.         //Register the current player created
    14.         NetworkServer.AddPlayerForConnection(conn, p, playerControllerId);
    15.        // base.OnServerAddPlayer(conn, playerControllerId);
    16.  
    17.     }
    18.  
    Note: to prevent the player is instantiated twice, be sure to uncheck "Auto Create Player" in your NetworkManager.
     
  10. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    Ok so this is what i did:

    -I inherit NetworkManager.
    -Added the NetworkManager script to my player object.
    -Disable "Auto Create Player".
    -Did
    Code (CSharp):
    1. ClientScene.AddPlayer(0);
    When i wanted to spawn a new player.
    -Spawn the player:
    Code (CSharp):
    1. public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    2.     {
    3.         print("spawn");
    4.         int numbersOfPlayers=Network.connections.Length ;
    5.         GameObject p;
    6.  
    7.         p = (GameObject)UnityEngine.Object.Instantiate(playerPrefs[numbersOfPlayers],
    8.                                                        list[numbersOfPlayers].transform.position,
    9.                                                        Quaternion.Euler(new Vector3(0,270,0)));
    10.         NetworkServer.AddPlayerForConnection(conn, p, playerControllerId);
    11.  
    12.     }
    but the problem is that he doesn't print "spawn", this function doesnt even called.
     
  11. LovattoStudio

    LovattoStudio

    Joined:
    Feb 11, 2015
    Posts:
    15
    the script is a class inherited from NetworkBehaviour?
    I mean you use like this:
    Code (csharp):
    1. public class scriptName : NetworkBehaviour{
     
  12. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    no, I use it like this:
    Code (CSharp):
    1. public class NetworkManager : NetworkManager {
     
  13. Decoder46

    Decoder46

    Joined:
    Jun 12, 2015
    Posts:
    20
    Ok so i figure the problem, now he is throwing me an error:
    I initialize the server and then I call AddPlayer().

    This is what i am doing:
    Code (CSharp):
    1.  
    2. public  void StartServer(){
    3.         bool useNat = !Network.HavePublicAddress();
    4.         MasterServer.ClearHostList ();
    5.         Network.InitializeServer(10, port,useNat);
    6.         MasterServer.RegisterHost(GameName,lobbyName,"a game");
    7.         GetComponent<NetworkManeger>().SpawnPlayer();
    8.         ClientScene.AddPlayer(0);
    9.      
    10.     }
    11.  
     
    Last edited: Jun 16, 2015
  14. diego-vieira

    diego-vieira

    Joined:
    Mar 27, 2015
    Posts:
    31
    Have you found a solution for your last problem? I am having the same message.