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 /
This question was closed Mar 24, 2013 at 11:50 PM by ExTheSea for the following reason:

I made a noobish mistake (explained in my last comment) which is now fixed.

avatar image
0
Question by ExTheSea · Mar 21, 2013 at 06:20 PM · multiplayernetworknetworkviewinterpolation

Unity Networking. Player flickers.

Hey. I'm currently trying to get rid of a little problem i have with my Multiplayer FPS. When i use only NetworkViews to synchronize the position of the Player between all connected players, the Player-Gameobjects of the other players kind of flicker when they move. That's why i added the NetworkInterpolatedTransfom Script from the Networking example to every Gameobject which has a NetworkView attached to it. When a game started i execute this code snippet in another script:

 function Start () {
         if(!networkView.isMine){
         var interpscript : NetworkInterpolatedTransform = GetComponent("NetworkInterpolatedTransform");
         interpscript.enabled = true;
         transform.networkView.observed = interpscript;
 }
 }

With this code i activate the NetworkInterpolatedTransform-Script and set the observed value of the networkview to this script on every gameobject i added this Script before.

The result of this can be seen in this Web Demo: http://dl.dropbox.com/u/83937500/WebPlayerBuild.html

(How to play:Open it in 2 BrowserWindows, type in a Name, click on advanced, click on start hosting a server, then test , then Start Server. In the other window just click on advanced and your server should show up in the Join a game via the list window)(Btw. Models/Animation/... are just for testing)

As you can hopefully see: There is a some type of flickering in the direction where the player moves. The Player himself is not flickering at all.

Now my question is: Where does this problem possible comes from and how can i solve it if someone knows how?

If you don't know the NetworkInterpolatedTransform-Script and need to see it to answer the question i can post it here.

Thanks in advance, ExTheSea.

PS: Here is the NetworkInterpolatedTransform.cs because i saw that the Networking example isn't available anymore for some reason:

 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;
         }
     }
 }
Comment
Add comment · Show 11
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 nastasache · Mar 21, 2013 at 09:05 PM 1
Share

Hi ExTheSea, I don't know if this will help you but I occurred this kind of flickering (I mean about flickering when move in your example - the jumping flickering when shoot it's a different thing related with sync of jump animation) exactly when I used interpolation and extrapolation scripts available on net in conjunction with sync via NetworkViews. Probably it's related with corrections which your NetworkInterpolatedTransfom script is trying to do. So that after a lot of headaches with sync the players movement, I decided to use not anymore the sync via NetworkView, switching to RPCs to send the positions&rotations to the server, and then, from the server to clients also via RPCs. $$anonymous$$eeping NetworkView sync only for animations and lag compensation.

avatar image ExTheSea · Mar 21, 2013 at 09:49 PM 0
Share

Thank you for your comment i will look into this and maybe use it for my project if it works out: I'm guessing you have a script that does something like this:

 @RPC
 function syncPosition(... syncPos : Vector3, syncRot : Vector3){
 ...
 player.transform.position = syncPos;
 player.transform.rotation = syncRot;
 ...
 }

...and you call the syncPosition-RPC in the Update function or is it something more complex? If so do you know any documentation which contains information about this technique?

Btw. if someone knows another solution maybe without going away from NetworkViews don't hesitate to post :)

avatar image nastasache · Mar 21, 2013 at 11:07 PM 1
Share

Yes, that's the point I think, as in your RPC prototype. Unfortunately the final scripts and inter-scripts communication finally working for me are pretty complex and difficult to show in few lines of code. As a very good point of start I suggest: http://www.playblack.net/zee-code/ This tutorial helped me a lot. $$anonymous$$eywords there: client movement, server movement (at first instance, ignore lag things)

Note I am not an expert. I was very frustrated to rewrite all movement scripts many-many times to keep all together (movement, animations) working acceptable in multiplayer mode and probably a better solution exist, even including NetworkViews for all the things, but I didn't found it. I think you must be prepared to rewrite all completely for few times, as I was prior to have a multiplayer sync on good enough way. Networking it's a hell place.

avatar image nastasache · Mar 21, 2013 at 11:15 PM 1
Share

Sorry, I didn't read last your three comments before to post, so that I answered to your @RPC example - more closed to my solution.

avatar image nastasache · Mar 24, 2013 at 11:22 PM 1
Share

I tested your Web Demo now and looks better. It's still flickering a bit (it's not about distance and position) but anyway it's better. But if you play with interpolationBackTime with arbitrary values I am not sure it's a good idea. Better to calculate the real delay (ping) and use the resulting value in calculate backtime. The reason you tested and implemented interpolation it's the lag?

Show more comments

0 Replies

  • Sort: 

Follow this Question

Answers Answers and Comments

11 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

Related Questions

Does the position change need state synchronization? 2 Answers

NetworkView Control 2 Answers

[uNet] Need help Converting From Unity Network to uNet 0 Answers

Sending info to/from different networkViews 1 Answer

Network View - Player is blinking, and visible only partially during movement. 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