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

Question Unable to update the Rigidbody position from a UDP call

Discussion in 'Multiplayer' started by Duburs, Apr 27, 2024.

  1. Duburs

    Duburs

    Joined:
    May 17, 2017
    Posts:
    2
    Hey, I am attempting to implement a UDP client / server which simply updates the rigidbody position whenever it recieves a package.

    Below is my current implementation that attempts to do it asynchronously but for some reason the Playermovement class fails silently on the rb.position call below, it just does nothing (no errors either but the client.BeginRecieve does not reexecute which means that it's stuck somehow). It seems to fail using anything from Monobehaviour and I am wondering why this happens and if there is something I can do to get this to work?

    If I remove the rb.position and update it in the fixedUpdate instead everything works as intended but I would rather update it on a UDP package rather than every frame hence my question.

    Code (CSharp):
    1.    
    2. public abstract class NetworkMonoBehaviour<T> : MonoBehaviour {
    3.  
    4.   private void ReceiveCallback(IAsyncResult result)
    5.       {
    6.           byte[] receivedBytes = client.EndReceive(result, ref remoteEndPoint);
    7.           string receivedString = Encoding.ASCII.GetString(receivedBytes);
    8.           NetworkPackage<T> receivedPackage = JsonUtility.FromJson<NetworkPackage<T>>(receivedString);
    9.  
    10.           if (receivedPackage.uuid == uuid)
    11.           {
    12.               DataReceived(receivedPackage.data);
    13.           }
    14.           client.BeginReceive(AC, client);
    15.       }
    16.  
    17.       protected abstract void DataReceived(T data);
    18.   }
    19.  
    Code (CSharp):
    1.  
    2.  
    3. PlayerMovement : NetworkMonoBehaviour<networkpackagetype>
    4. {
    5.  
    6.     // rb = gameObject.GetComponent<Rigidbody2D>();
    7.  
    8.     protected override void DataReceived(MovementNetworkPackage data)
    9.     {
    10.         Debug.Log("Rigid body");
    11.  
    12.         Vector2 _dir = new Vector2(data.direction_x, data.direction_y);
    13.         Vector2 _pos = new Vector2(data.position_x, data.position_y);
    14.  
    15.         /* This code fails silently with nothing happening, if I update the dir and position in fixed update it works */
    16.         rb.position = _pos + _dir;
    17.     }
    18. }
    19.  
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,505
    My hunch is that you are receiving UDP packets on a background thread, as is best practice (if not required). You need to make sure that you call the methods that make changes to components on the main thread.

    One way to do so is with UnityMainThreadDispatcher.

    Btw, what's your goal here?
    Are you aware that there are free networking solutions? (NGO, Fishnet, ...)
    Are you aware of the numerous pitfalls of synchronizing dynamic rigidbodies over the network?

    Particularly nasty when that rigidbody is the player object because it will never feel right getting pushed around by and fighting for authority with other players. Consider Rocket League but with heavy lag - that'll be your initial behaviour. They managed to run their (self-made!) deterministic physics simulation at 120 Hz on the server with rollback and reconciliation and generally put in a lot of effort to make it feel alright.
     
    Duburs likes this.
  3. Duburs

    Duburs

    Joined:
    May 17, 2017
    Posts:
    2
    Ah thank you. The main thread explanation makes a lot of sense.

    There is no specific goal tbh, I do realise that it'd be faster and more optimal to use already made libraries but I generally find it more fun to implement my own thing :). I am looking to do more of an event driven type of networking solution that only runs when needed, again I am sure that already exists but I have an idea and want to see if I can do it.
     
    CodeSmile likes this.