Well if you didn’t send movement data from the Client to the Server, it wouldn’t move (at least not very far), since the server would be forcibly settings it’s position back to whatever it thinks it should be every time you get an update. That would be exactly where the object first spawned in the world if you don’t do the movement on the server. The only way to get movement is to do the movement on the server, NOT the client. This is just the way it’s generally handled in Unreal since we use a Authoritative Server / Dumb Client model.
CMC does exactly this, it does the actual movement on both client and server, but in the end, the server has control over where the final position should be. It means that they’re always a tiny bit out of sync, but it’s not detrimental in anyway to game-play and the client gets a more responsive fluid experience.
Definitely don’t send the movement location each tick, that’ll throttle the connection and you’ll have to use RPC’s to do so, which is expensive. Don’t send RPC’s to clients each tick from the server either, as that will also throttle you. The best approach is to do the movement on the server, then rely on the replication system to figure out how often it should send movement updates out to clients. If you throttle your connection with RPC’s, replicated variables will stop coming across reliably, as I recently discovered thanks to the NetProfiler tool.
As for optimization, using Int’s would give you horrible jitter, but UE already has optimized FVectors with use the _NetQuantize suffix like the following. They sacrifice a tiny (and virtually unnoticeable) amount of precision in favour of lower data transmission between players.
- FVector_NetQuantize1000
- FVector_NetQuantize100
- FVector_NetQuantize10
- FVector_NetQuantize
NetQuantize100 seems to be the most common one in use as far as I’ve seen in Epics samples, such as ShooterGame and it’s uses in source code.
So with all this in mind, the best approach would be:
-
Do the movement operation on both Server & Client. This will likely happen auto-magically without you having to go out of your way and write any additional code, as I’m fairly sure player input is automatically sent across the network. Don’t take that one to the bank though, I could be wrong there.
-
On the client, blend from current position to the received position from the server. You can use PostNetRecieveLocationAndRotation() (I believe it’s called that, do a search for it :)) to do the logic in there.