- Home /
How stream unreliable data to only one server/client?
Background: I'm trying to add voice chat to the game so that only those who are close to the person speaking will hear it.
From my understanding OnSerializeNetworkView is the only way to stream unreliable data, but can I make it so it doesn't send the data to other clients and only the server? I want the server to chose who gets to see the data and who doesn't, and all ways I know how to do this is to just ignore the data in the clients who shouldn't get it. This is of course not a viable solution as it would take extra bandwidth for no purpose.
Answer by ScroodgeM · Aug 20, 2012 at 10:26 PM
when you use a client-server-client model and send data from one client to another, this data is received by server and sends again to client, so you could make a custom OnSerializeNetworkView for server, that will change received data before send it to others.
so just check if you are on server and after receiving data work with it before sending.
That would not work because the automatic syncing is send to all by default. When the server is not the owner he just acts like a client plus an additional relay station. You can't manipulate the data and send them further. OnSerializeNetworkView will always be isReading for any peer that is not the owner. The owner will always be isWriting.
The best bet is to use SetScope and / or Network.SetReceivingEnabled / Network.SetSendingEnabled
server that is not owner of network object is not just a relay. i remember an issue when i'd remove some objects with colliders from server (this caused holes in walk surface) to make it lighter, and when one of clients (owner) walk near this place, it was not able to fall through hole cause there's no hole in client, but on the server player's character falls down and other clients got this player fallen down, but owner still thinks it is before hole (looking at collider).
i can try to reproduce this issue. but this let me think that server is not simple relay....
Sure it is. What you describe is actually the prove ;) Every peer (no matter if it's a client or the server) runs it's own game. Physics are calculated on each peer seperately. each peer has it's own objects. The owner of the object is the only one who can send updates through the network. If the owner can stand at the point where he is in "his world", he will not fall. If there's a hole on other peers, the server or other clients the object will fall, but it will be "teleported" back up each time it receives an update from the owner. In this case you have an inconsistent state of the scenes on different PCs.
The network system (NetworkViews) are just build on top of the normal game scene / logic. They just sync the position in intervals. If you use reliable delta compression, the owner will only send updates when something has changed on his side. That means in our case above, when the owner doesn't move, the object can fall on other peers until a new update is sent.
Even if, in the case of an observed Transform and / or rigidbody, the server is simulating on it's own machine one frame and then send it's current state to the others, it wouldn't apply to OnSerializeNetworkView because you can send any data via this function, so the server can't do any logical changes to the data. Again the server can't change the data that got serialized by the owner in OnSerializeNetworkView. It just pass it through. Same for RPCs that are send to All or Others. But with RPCs you always can send an RPC to the server only and it can distribute it manually to the others. In this case you can of course change whatever you want ;)
server is not just a relay. it can correct data that receives before sending to others. in this example i use OnSerializeNetworkView method to sync data (transform position) with offset to one of it's axis (slider) that applies before sending data on owner and server. Value on this screen is transform's axis value.
so, owner (bottom left screen) has transform in position 0 (ball in center), but sends it's position with offset 2.23. server (top screen) receives it (ball is moved right a little). but before sending to others it adds offset 3.94. others (client at bottom right) receives a little offsetted position. so both owner and server offsets applied.
all this lets us to correct data on server even if server is not owner of objects.
both these slider at owner's screen and server's screen are moves ball at bottom right client
i can share sources for testing it.
http://zammyart.com/nettest.unitypackage
10 $$anonymous$$B
just compile it, run some instances, start server on one of it, clients on others, instantiate one ball and move.
Your answer
Follow this Question
Related Questions
Network syncing between Clients 0 Answers
OnSerializeNetworkView problems with clients 1 Answer
OnSerializeNetworkView to only one recipient 2 Answers
Total Message Bytes Queued? 3 Answers