2
\$\begingroup\$

I know I've done this incorrectly, but I don't know what the right way is.

Right now I have two clients that connect to a server. Each tick the players send a packet of information containing their X,Y to the server. The server takes those packets and sends them to the other clients. So it's like this:

EXAMPLE:
Player1: 1:x,y or 1:100,125 Player2 receives that information, and then moves that instance of a NetPlayer based on the ID (1)

When the NetPlayer receives a new position packet from the server, it calls MovePlayerTo(Vector2 _newPosition);

public void MovePlayerTo(Vector2 _newPosition) {
            this.newPosition = _newPosition;
            //OldPacketPosition = newPosition;
            //newPosition = _newPosition
            //LerpFromOldToNew(OldPacketPosition, newPosition); 
}  

Then, in the NetPlayer.Draw method (called 60 times a second), the Position is set like so:

 Position.X = MathHelper.Lerp(newPosition.X, Position.X, lerpValue);
 Position.Y = MathHelper.Lerp(newPosition.Y, Position.Y, lerpValue);

This has smoothed the player out pretty well, but it still appears as if it's not being drawn as smooth as a local player, even with interpolation. It seems like it's being drawn at 45FPS. If I lower my client tick delay to 200ms, it lerps very quickly between those positions in short bursts. It doesn't actually make the entire movement smooth.

I've tried changing the MovePlayerTo() to set an OldPacketPosition, and NewPacketPosition, and then lerp between the last packet.position and the new one, and it becomes even choppier, no matter what I set my (float) lerpValue to.

Also I noticed if I jump up and down a bunch, it doesn't show the NetPlayer hitting the ground. He moves smoothly and kinda bounces before he even hits the ground and shoots back up in the jump animation.

I know I'm doing this improperly. I've seen other people set their tick rate to be really low, and the positions aren't super accurate but the movement is still smooth between packets.

EDIT: Changes:

public void SetPreviousPosition()
        {
            PreviousPos = LastNetPosition;
        }

        public void MovePlayer()
        {
            //Next = packetPosition
            //Previous = player's position when it received the packet
            //Lerp(previous, next);
            Position.X = MathHelper.Lerp(PreviousPos.X, NextPos.X, lerpValue);
            Position.Y = MathHelper.Lerp(PreviousPos.Y, NextPos.Y, lerpValue);

        }

So every packet received by the net player, the handler is calling the MovePlayer() with the new packet position, after setting it's last position to it's current position when the packet is received. It looks smooth, but not nearly smooth enough. The local player still is super smooth by comparison.

Do I need to lerp to the new position over a specific duration? Because right now it's just calling the method every time it receives a positional update from the server.

EDIT: 5/21/20

I just tried using my lerp function in a different program and it moves perfectly. I added a list of random X,Y packets and then had it lerp over it's update call so I'm assuming that's why it's smooth. In the multiplayer game, it can't have a list, because it needs to lerp between currentPos and packetPos. So I don't understand why it immediately stops working.

\$\endgroup\$
  • \$\begingroup\$ It looks like you're making the same mistake as in this previous question: you're using an exponential ease-out lerp which gives you fast & slow catch-up, looking like it's lurching and low framerate, instead of one consistent speed of travel. \$\endgroup\$ – DMGregory May 18 at 11:08
  • \$\begingroup\$ @DMGregory So I've changed it to Lerp from the last received position, to the goal position, with the lerpvalue based on the timestamp from the packet. but It's still not completely smooth so I think I have a fundemental misunderstanding of it. Do I call the lerp function once per packet received? Do I call it 60/times a second in the NetPlayer update()? Do I lerp for the duration of the packet delay? Say 50ms. Lerp from last position to goal for 50ms? I still can't get it to work as smooth as I've seen others do it. \$\endgroup\$ – user2578216 May 20 at 22:45
  • \$\begingroup\$ Show us your new code. \$\endgroup\$ – DMGregory May 20 at 22:56
  • \$\begingroup\$ @DMGregory Thanks Doug. See edits \$\endgroup\$ – user2578216 May 20 at 23:11
  • \$\begingroup\$ Looks like we're missing how you update LerpValue. \$\endgroup\$ – DMGregory May 20 at 23:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.