Wha'ts a good Lerp technique?

To reduce the lag and the choppy movement of my players in my game I’ve created a strange prediction system (not sure if I can call it a prediction system). This system uses a local instance of the game object and another one, that is invisible and sends/receives data over the network. Both game objects respond identically to the keyboard input. The idea is that the local game object corrects it’s position and rotation smoothly according to the game object, that sends and receives data. Now, this is pretty smooth, but not as smooth as the movement in the professional multiplayer games we all play.

For that position correction I’m using Vector3.Lerp(transform.position, networkObject.transform.position, various methods);

various methods means that I have had a lot of atempts to get that value set. I’ve used fixed values like 0.5, tried to use Vector3.Distance to check the distance between the local and the network objects and many other things like those. Even tried rigidbody.velocity.magnitude (as my players are rigidbodies) not a good idea, DEFINITELY NOT A GOOD IDEA to use magnitude :smile: The problem is that the lag always finds a way to occur. I can’t allow the local object to get far from the network object either, because sometimes the local object can go behind another object before the network object has reached it and then the local object will desprately try to lerp to the network object’s position, but without succes, because the object between them will not let them.

If you are still following me, I just used a check:

if(Vector3.Distance(transform.position, networkObject.transform.position) > 0.7)  transform.position = networkObject.transform.position;

But that would teleport the local object instantly if it gets too far from the network object so I need to keep the objects as close as possible and still be able to maintain smoothness in the movement of the local object. Any suggestions what should I do?

Hello there!

This tutorial contains an excellent script for synchronizing objects smoothly over a network.
http://download.unity3d.com/support/resources/files/MultiplayerTutorial.pdf
Look for NetworkRigidbody.

Tsk tsk Metalhead, I already linked you the Unity interpolation scripts! :slight_smile:

Yes, I know and thanks for the links. However my idea is to have a local object and a network object, not only one object, that will do everything (I got my reasons). I couldn’t actually get the network rigidbody script to work anyway.

What are those reasons? That seems like a crazy amount of overhead/extra work with little benefit. And NetworkRigidbody/NetworkInterpolatedTransform are pretty simple, you just drop them on the object and make sure the object’s networkview is observing the script and voila.

Yes, I’m doing it exactly as you described and there’s just no difference. The movement is still choppy. The network view absorbs the rigidbody, not the transform. NetworkInterpolatedTransform is a whole new story, the objeects behave pretty strange, they instantly change their position for a second and then get back where they should be… I put those scripts in a folder called “Plugins” because they should be in that folder, right? I’m telling you, rigidbody makes no difference and interpolated transform is behaving pretty strange.

Now I want to have a local object, because that way there’s absolutely no delay in the movement of the characters (which are actually balls with rigidbodies that roll around). And also if the connection stops for a second, they will still be able to move. I read somewhere that Valve’s games use that exact technique.

Maybe I’m wrong about this and all this is not a good idea, but I can’t get the scripts to work and can’t see for myself which method will be better.

@Metal Head: It’s probably because you have both your script and the NetworkRigidybody activate at the same time.
Create a new scene with completly new objects and see if it works.

Well I think it’s working. But how does my ball’s script cause NetworkRigidbody not to work. In the client’s case it only sends input to the server.

EDIT
Oh, no… it’s the same with or without the script :frowning:

Nah, the NetworkRigidbody and NetworkInterpolatedTransform scripts are actually mostly inspired by Valve’s method of interpolation/movement prediction, from this article.

If you’re talking about the blue/red hitbox overlay image, they’re not actually both in the same instance of the game. They’re illustrating the difference in position of the same player in the local client’s instance of the game and the other client. There isn’t actually two player objects in any one instance of the game, invisible or not.

Oh, then maybe what I have read isn’t true. I didn’t even know about those hitboxes, I just read somewhere, that all of valvse’s games use a local instance of the player.

So what I did now is have only one object (there’s two prefabs - one spawns a local object and becomes invisible and the other one doesn’t spawn anything, I’m now using the other one) with that NetworkRigidbody script, which is located in “Plugins” folder in the root. This prefab has a rigidbody and a networkview, that is set to absorb the rigidbody and not the rotation. The player script only sends input data to the server, on the server this player script moves the ball and the data is absorbed by the networkview. I don’t have any lines in my code, that set the ball directly to a certain position so the position should be sent only through the network view. I have the NetworkRigidbody script attatched to that prefab.

I have this to check if I’m a client and if so, enable the NetworkRigidbody script.

When I build and connect, there’s no change, the ball’s movement is still choppy. Am I missing something?

Ah yeah, they do have local instances of the player, but so does Unity. All that means is when I instantiate my player across the network, I have the “real” copy in my local game, and it instantiates remote instances of my player in all other client’s local games.

Without seeing the rest of your code, I couldn’t really tell you whats wrong. I would play with the cars and 3rd person example in the Networking Example package, and see how they do it and use it as inspiration. Theres also an authoritative 3rd person example. From the looks of it you want it to be authoritative, so that last one would probably help you the most, specifically the “GraduallyUpdateState” script. This is from it’s comments:

Yes, I’m using an authoritative server. I looked at the example yesterday when I downloaded it (I knew about it long time ago, but had never downloaded it before)… I couldn’t really tell what’s different.

Here’s my player script: zing
It’s a pretty big mess right now, but I hope you’ll find your way through it.

Have you used this NetworkRigidbody script for a player, that uses a rigidbody or…what have you used it for?

I’m pretty sorry that the topic of this thread changed so much since the beginning :confused:

Naw, I use the CharacterController/CharacterMotor for my network players, not Rigidbody, so I use NetworkInterpolatedTransform. But movement is one of the few things I don’t handle authoritatively, each network player owns their own player prefab, controls input/movement locally on it, and broadcasts the results to all other players with NetworkInterpolatedTransform.

I want to calculate the movement on the server so I can prevent any possibilities of cheating. I searched for people, who have the same problem, but it seems no one has any problems with NetworkRigidbody…or no one is making multiplayer games. I looked at the tutorial’s assets again and I could see no difference. The car prefab was what I was looking at, because it uses rigidbodies and there’s the NetworkRigidbody script, but everything is pretty much the same as my prefab.

The car example is non-authoritative. I would take a look at the TPS-Auth example, even though it doesn’t use rigidbodies.