• 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 oliver-jones · Dec 05, 2013 at 09:47 PM · iosnetworkrpcsync

Networking - Best way to Sync Rigidbodies?

Hello,

I'm working on a type of pool/billiard game over a local network using Unity's builtin networking for iOS. I'm trying to figure out the best way to sync position of the balls.

Basically, I want it so when it's Player One's turn, that device only applies the actual velocity to the balls when hit, and then syncs the outcome of the position to the client / Player Two. And the same for when its Player Two's turn. So who's ever turn it is, will essentially control the balls physics, and sync it to the client.

What I've done so far is this, which is attached to all the balls (FYI, the initial force applied to the balls are also called locally, and synced in the same manor):

 function Update(){
 
     if(GC.NETWORK.myTurn){
 
         networkView.RPC("SyncVelocity", RPCMode.Others,     rigidbody.velocity.x,
                                                             rigidbody.velocity.y,
                                                             rigidbody.velocity.z);
     }
 }
 
 
 @RPC
 function SyncVelocity(x : float, y : float, z : float){
 
     rigidbody.velocity.x = x;
     rigidbody.velocity.y = y;
     rigidbody.velocity.z = z;
 }

Note how I'm only sending that RPC to 'others' .... so the player that ISNT playing. Is this the correct way to do it? I'm worried that because I'm sending this every frame it might 'overload' the clients network listener ... if thats even a thing?

I had also synced the local position and rigidbody velocity before, but when testing on my iPad2, and being the player who ISNT playing, everything went laggy, suggesting that there was too much data being sent from the current players RPC? (Although I didnt get lag when on my iPhone5 as being the 'none player'. Maybe because its just generally better at processing it all).

I don't know, just need a point in the right direction really?!

Thanks.

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 Kiloblargh · Dec 05, 2013 at 10:36 PM 0
Share

You don't need to do it every frame, you should use an InvokeRepeating. Also, it looks like every ball is sending an RPC every frame? You can store moving balls in a list and do them all at once. Also, you can send a Vector3 in an RPC.

If one player is controlling the physics, though, why not just disable the rigidbodies during the other player's turn and send xy position-at-time updates?

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Pangamini · Dec 09, 2013 at 12:48 PM

You are making a turn-based game, which makes things a lot easier for you. Floating point operations may give different results on different platforms, so expecting that same setup will have same results is ingenuous. And proper realtime networking of physics is a very complex problem, usually combining prediction (what you do, local physics calculation) and corrections based on data from server.

But as i said, you don't need to deal with this since your game is turn based. So why not just record the ball movement in frames (on the server), send it (and wait for the client to receive the whole "movie")) and then, after all data is transmitted, simply replay the motion? No need for real-time simultaneous ball motion on all PCs, unless you want to be able to shoot them.

Having all physics being calculated on server will simplify the coding and prevent cheating.

Comment
Add comment · Show 6 · 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 oliver-jones · Dec 09, 2013 at 05:34 PM 0
Share

Okay, so with this 'movie record' system, will I be expecting lag? Because I preferably want it to be almost instant sync, as its a local game - players will be sitting/standing next to one another, so lag will not work in this particular project.

Also, player one is always the server. Its not one of those games where there is a server that is a NPC, and players connect as clients (excuse my lack of terminology).

So, if your 'movie clip' system doesn't have lag, how would I go about doing it? Thanks

avatar image Kiloblargh · Dec 09, 2013 at 06:19 PM 0
Share

You could run the physics at 10x speed or faster, tracking only the time and place of each collision for each ball, then both players would effectively be watching a replay and the clients' replay would only be delayed by a second or so. I think most existing pool sims already do something like that- if you made one with 2-way real-time physics sync, yours would be the first. And it wouldn't be a good thing in this case.

avatar image Pangamini · Dec 09, 2013 at 09:20 PM 0
Share

That's exactly what i would do, but not just 10x faster, but simply - as fast as possible (in single frame or separate thread) but in unity that might mean you'd need to implement some other physics engine? I don't think you can unhook the current one from the realtime simulation.

avatar image Pangamini · Dec 09, 2013 at 09:27 PM 0
Share

Or, an acceptable solution would be to stream this "movie" while it's still being generated on the server. With some little latency. And if they sit on a LAN, you don't need to worry about amount of data (much). Then add some simple interpolation between those keyframes too, possibly creating non-regular additional keyframes on ball collision (so the interpolation reaches the exact point)

avatar image oliver-jones · Dec 10, 2013 at 12:48 PM 0
Share

Okay, so in terms of actual coding, how would I build the recording? So - every 20 frames, send the record over and essentially 'play' it with a lerp? Also - will I need to turn off the rigidbody/collisions on the player thats viewing the recording?

Show more comments
avatar image
0

Answer by Jamora · Dec 10, 2013 at 02:40 PM

I would have the server NetworkInstantiate all the balls, so that it is the owner. Have the NetworkView of each ball observe its Transform (it is by default) and set the transfer mode to unreliable.

Now, playing as the server is simple, as all computation is done locally and merely transmitted to the other players. But, how to allow the remote player to actually play? Easy enough: have each remote player send the parameters of each original strike to the cueball to the server. Then the server performs this strike and transfers all positions over the network.

This method will need to be improved if you have a fancy 3D pool-game where you actually hit balls with sticks and allow the physics to handle the rest (mainly because of the lag between hitting the ball and it actually starting to move can be discernable). But for a 2D, top-down view the only things you need to transfer over the network from clients to the server are

  • the angle at which the cueball was hit (direction)

  • the power of the hit (speed)

  • possibly which part of the ball was hit (for curve-balls)

In one sentence: Only send the parameters of the strike to the cueball to the server, and forget about controlling balls remotely.

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 Pangamini · Dec 10, 2013 at 04:15 PM 0
Share

The main problem here is that floats can have different results on different CPUs. Even if those are tiny differences, in physics simulation they will accumulate.

avatar image Jamora · Dec 10, 2013 at 05:03 PM 0
Share

Because only the parameters of the strike (not the actual hit) are sent to the server, only one computer is doing the physics simulation; the server. The server constantly syncs the positions of the clients balls to its own to achieve the illusion of the remote player actually playing.

The remote client is doing three things:

  • displaying the table

  • receiving position information from the server for each ball

  • occasionally sending out data on how the cue ball should be hit (but doesn't actually hit it)

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

18 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 avatar image avatar image avatar image avatar image avatar image

Related Questions

why my cmd function not work? 1 Answer

Joining a Running Server (Game) and Waiting for Game State Data. How? 1 Answer

IL2CPP - RPC doesn't work 1 Answer

How to change GameObject Material over Network! 0 Answers

Transfering vars to RPCs? 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges