- Home /
Networked position interpolation implementation (not Dead Reckoning)?
I spent most of today attempting to find a nice short description of how to implement interpolated positions for a networked object, without much success. It seems only mentioned here and there, but I couldn't find any descriptions which didn't make my head hurt. I finally managed to make an implementation which I believe could be cleaned up a lot, but here's the jist of it:
curAngle = Mathf.SmoothDampAngle(curAngle, newNetAngle, ref tempvelF, prevRotDiff);
myTransform.rotation = Quaternion.Euler(0, curAngle, 0);
if (newNetAngle != oldNetAngle)
{
prevRotDiff = Time.time - prevRotStamp;
prevRotStamp = Time.time;
oldNetAngle = newNetAngle;
}
myTransform.position = Vector3.SmoothDamp(myTransform.position, newNetPos, ref tempvelV, prevPosDiff);
if (newNetPos != oldNetPos)
{
prevPosDiff = Time.time - prevPosStamp;
prevPosStamp = Time.time;
oldNetPos = newNetPos;
}
It moves the object (in this case a player) just the right amount until it recieves a new update. What I'm wondering is what SmoothDamp and SmoothDampAngle actually does mathwise here? I tried doing the math myself but failed.
Answer by Owen-Reynolds · Feb 07, 2012 at 06:38 PM
MoveTo and SmoothDamp both do about the same thing, but the Smooths try to add an extra accelerate phase in front, and a decel in back. Sort of like how a spline turns a straight line into an S-curve.
MoveTo moves or spins at a constant speed. That can look robotic, as it snaps to full speed, then snaps to a stop. But, say you have an animation which already incorporates realistic movement. Then you want MoveTo, to run it evenly.
In your case, the original object is probably being moved "realistically" by physics, so you don't need to extra smoothing (it makes the copy object "heavier") and can use MoveTo.
Nice, I'll take a look at that tomorrow. What does the math behind $$anonymous$$oveTo look like though? I understand the concept, it seems like such a trivial thing but for some reason I couldn't figure it out.
I took a quick look at $$anonymous$$oveTowards (which I assume is what you meant), which seems to expect a speed value rather than time it takes to reach goal. Not really following how it's supposed to work, but in any case, this speed vs time is a pretty significant difference for me. If I would've been able to figure out the speed based on old & new positions and the timestamps I could probably have lived without SmoothDamp. What to do? :S
$$anonymous$$oveTowards is pretty much just val+=speed; if(val past target) val=target;
SmoothDamp (AFAI$$anonymous$$,) does the same, but also ramps up and down the speed. If you note, the time is only a guide. I guess you could set $$anonymous$$oveTowards speed = distance/wantedTime (speed is in $$anonymous$$/S.)
This is for dropped packets? The set-up confuses me. Unity will normally invisibly set transform.rotation
to the new angle. It looks like you're sending infrequent RPCs yourself, and making it smooth at the expense of a lag. But I haven't done enough Unity-Network stuff to say anything useful.
Yes Unity would automaticly set the angle and/or position if I let it, but the problem lies in the fact that packets are sent at a lower interval than the client's framerate (15 is the default sendrate, whereas I generally have like 90fps), so I need to smooth the positions inbetween the updates. At first I had it immediately update both position and angle, but it was choppy just as expected.
As for dropped packets, dead reckoning handles that a tad better since it keeps moving the object even if it didn't recieve any update, and corrects itself once it does. This interpolated solution rather just waits at the current position if it didn't recieve an update as expected, until it gets a new update, by which time it starts smoothing towards the new position. It works quite well as long as packets aren't frequently lost. A packet here and there won't be all that bad. This variant is somewhat more common than dead reckoning actually, since it's so much simpler to implement (which is why I felt so frustrated about not figuring it out at first).
distance/wantedTime was indeed the magic I was after. Thanks a lot!
Your answer
Follow this Question
Related Questions
Interpolating the motion of a camera moving from one node to another 1 Answer
Smoothing Network Movement with OnSerializeNetworkView 0 Answers
Network Trasnform Interpolation Factor 2 Answers
Lock player position 1 Answer
Why is Input.GetAxisRaw() not returning whole numbers when using a joystick? 1 Answer