Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Braveheart · May 03, 2013 at 05:32 PM · movementnetworkingmultiplayervector3sync

How would I continue an object's movement in the same direction as per last user input?

If I have a Vector3 variable called movement and I feed this various pieces of user input (Vertical and Horizontal axis movement) how could I then have my code update this movement variable to continue moving in the same direction as per last input until new input is received?

What I'm trying to do is smooth multiplayer movement. So I have each player send their position once plus their movement vector (which is fed into Move()) and then lerp from the old position to the new one. But this is laggy from time to time so I'm trying to solve the lag. My idea was, continue moving the player using the last known movement vector and only lerp to the new position when a new position is received.

Is this a good solution to the problem of lag?

How do I continue the movement in the same direction as the Vector3 fed to Move()?

EDIT: I've tried numerous different things but there's still slightly choppy movement or slingshot type behaviour when lerping to the next position. I still need help with prediction/interpolation.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ExTheSea · May 05, 2013 at 01:16 PM 0
Share

If your problem is solved please accept an anwer. If not you should update us on what you've tried so far.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by ExTheSea · May 03, 2013 at 05:36 PM

If you're problem is laggy movements over the network you can use the NetworkInterpolatedTransform:

 using UnityEngine;
 using System.Collections;
 
 public class NetworkInterpolatedTransform : MonoBehaviour {
     
     public double interpolationBackTime = 0.1; 
     
     internal struct  State
     {
         internal double timestamp;
         internal Vector3 pos;
         internal Quaternion rot;
     }
 
     // We store twenty states with "playback" information
     State[] m_BufferedState = new State[20];
     // Keep track of what slots are used
     int m_TimestampCount;
     
     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
     {
         // Always send transform (depending on reliability of the network view)
         if (stream.isWriting)
         {
             Vector3 pos = transform.localPosition;
             Quaternion rot = transform.localRotation;
             stream.Serialize(ref pos);
             stream.Serialize(ref rot);
         }
         // When receiving, buffer the information
         else
         {
             // Receive latest state information
             Vector3 pos = Vector3.zero;
             Quaternion rot = Quaternion.identity;
             stream.Serialize(ref pos);
             stream.Serialize(ref rot);
             
             // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
             for (int i=m_BufferedState.Length-1;i>=1;i--)
             {
                 m_BufferedState[i] = m_BufferedState[i-1];
             }
             
             // Save currect received state as 0 in the buffer, safe to overwrite after shifting
             State state;
             state.timestamp = info.timestamp;
             state.pos = pos;
             state.rot = rot;
             m_BufferedState[0] = state;
             
             // Increment state count but never exceed buffer size
             m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);
 
             // Check integrity, lowest numbered state in the buffer is newest and so on
             for (int i=0;i<m_TimestampCount-1;i++)
             {
                 if (m_BufferedState[i].timestamp < m_BufferedState[i+1].timestamp)
                     Debug.Log("State inconsistent");
             }
             
             //Debug.Log("stamp: " + info.timestamp + "my time: " + Network.time + "delta: " + (Network.time - info.timestamp));
         }
     }
     
     // This only runs where the component is enabled, which is only on remote peers (server/clients)
     void Update () {
         double currentTime = Network.time;
         double interpolationTime = currentTime - interpolationBackTime;
         // We have a window of interpolationBackTime where we basically play 
         // By having interpolationBackTime the average ping, you will usually use interpolation.
         // And only if no more data arrives we will use extrapolation
         
         // Use interpolation
         // Check if latest state exceeds interpolation time, if this is the case then
         // it is too old and extrapolation should be used
         if (m_BufferedState[0].timestamp > interpolationTime)
         {
             for (int i=0;i<m_TimestampCount;i++)
             {
                 // Find the state which matches the interpolation time (time+0.1) or use last state
                 if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount-1)
                 {
                     // The state one slot newer (<100ms) than the best playback state
                     State rhs = m_BufferedState[Mathf.Max(i-1, 0)];
                     // The best playback state (closest to 100 ms old (default time))
                     State lhs = m_BufferedState[i];
                     
                     // Use the time between the two slots to determine if interpolation is necessary
                     double length = rhs.timestamp - lhs.timestamp;
                     float t = 0.0F;
                     // As the time difference gets closer to 100 ms t gets closer to 1 in 
                     // which case rhs is only used
                     if (length > 0.0001)
                         t = (float)((interpolationTime - lhs.timestamp) / length);
                     
                     // if t=0 => lhs is used directly
                     transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
                     transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
                     return;
                 }
             }
         }
         // Use extrapolation. Here we do something really simple and just repeat the last
         // received state. You can do clever stuff with predicting what should happen.
         else
         {
             State latest = m_BufferedState[0];
             
             transform.localPosition = latest.pos;
             transform.localRotation = latest.rot;
         }
     }
 }


Sry for the long code but i couldn't find it uploaded somewhere anymore and was to lazy to upload it myself :). What you can do then is to add the script to the gameobject you have a networkView on and set the networkView's observed to the script.

Worked for me. Hope it does for you too. If you can't use that script because you have another method for syncing movement (for example RPC's) or you can't use it for another reason let me know.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Braveheart · May 03, 2013 at 06:31 PM 0
Share

Thanks for responding! The problem is indeed laggy movement over the network.

I'm using TNet for networking, not Unity. So syncing is done using RFC's (TNet's version of the RPC, used in the very same way). Would this still work?

If not, how would I go about smoothing out the movement over the network?

avatar image ExTheSea · May 03, 2013 at 08:37 PM 0
Share

Well basicaly what you're trying to achieve is called interpolation.You propably should be able to use this script after doing some conversion to tcp. I personaly never used rfc but here are some links that use mainly rpc calls to do interpolation: http://answers.unity3d.com/questions/138334/iterpolatin-positions-networking.html

http://forum.unity3d.com/threads/79310-Extrapolation-amp-Interpolation

and here is another interpolation script from the wiki: http://wiki.unity3d.com/index.php?title=NetworkView_Position_Sync

and finally here is one of my questions about this topic where a User called nastasache explained me a bit about interpolation and rpcs maybe it helps you: http://answers.unity3d.com/questions/421877/unity-networking-player-flickers.html

The basics that you propably have to do is synching the position/rotation in Update and then do some lerping to match them to the current ones but like i said i never did anything in depth. I just found that script put it on my gameobject and it worked.

The thing is that i can't really help you by trying things out myself as i would think that strapping tcp on to a networkView-Project would be a quite difficult task but still if you have questions i will still try to help you as much as i can :) ...and maybe someone will come who actually knows about rfc's

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

13 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity networking tutorial? 6 Answers

bouncing a puck of a vertical wall through code 0 Answers

How to Sync List 1 Answer

Sending Animation Over Network 0 Answers

Help| Sync' boolean variable (Friendly Fire) 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges