Search Unity

Question Is there a way to get the velocity of a rigidbody on the client side?

Discussion in 'Netcode for GameObjects' started by Kolichikov, Aug 18, 2022.

  1. Kolichikov

    Kolichikov

    Joined:
    Jul 21, 2014
    Posts:
    16
    My characters are controlled with a basic pid control that relies on the current rigidbody velocity to decide if it needs to apply force. On the host side, this works as expected, but on the client side, all calls to rigidbody properties return 0. Even trying to manually calculate the velocity using transform.position doesn't work, because the transform diff is always 0.

    Code (CSharp):
    1. var newPos = transform.position;
    2. var diff = newPos - lastPos; //this is almost always zero, except for some weird places I can't figure out why.
    3. lastPos = transform.position;
    The question:
    Is there any way to get the velocity of a rigidbody on the client side when networking with an authoritative server (without using a network variable, see below)?

    Other stuff
    I've tried to introduce a network variable for the velocity, but the whole point was to have an input before the round trip (I'm trying to let the client pretend it's doing things before the authoritative server returns the actual position).

    Stepping back, maybe I'm just approaching this incorrectly. What I want to do is have the client use the same movement code to calculate the force/torque applied to the rigid body, then make a ServerRpc to have that force actually applied. Because the force applied depends on the current velocity, the client also needs this information, it's not enough to simply pass the inputs to the server and wait for a response. That's why I want the velocity information on the client.
     
  2. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    This is a problem I've also ran into before. You may want to consider making the movement client-authoritative, but if you want to keep it server-authoritative, then you are going to need to either estimate the velocity or extrapolate from the last velocity update that you received from a network variable or Rpc.

    The reason your estimate of the velocity from the position likely failed is because the transform is only updated on a network tick (as set by the tick rate in the network manager), which is likely (and should be) much less frequent than frame updates. You can fix this by only updating the difference in position on a tick, but if you're relying on the transform then you are already waiting on server updates, so you might as well just use the latest velocity update from the server, which also arrives every tick.

    I'd advise having the server send velocity updates through a network variable or Rpc, and keeping the last N velocity updates on the client (with timestamps). Then when you need the current velocity, do an order N-1 extrapolation for it based on the past updates. Note that a higher N is not always better, N=2 or N=3 is fine. Though depending on your tick rate and accelerations it might be that the last velocity update is close enough to whatever the current one would be – you can always correct the force/torques on the next network update.
     
    Last edited: Aug 20, 2022
  3. Kolichikov

    Kolichikov

    Joined:
    Jul 21, 2014
    Posts:
    16
    Thank you for the confirmation on the network tick, this was my eventual guess as to why they're almost always the same.

    I will just avoid client reconciliation for now, and focus on setting up all the other networking bits, but your suggestions give me good starting points for when I work on it, thank you.