Unreal CharacterMovementComponent is awesome for replicating character movements.
I want to know whats the best way to replicate movement for non-characters. E.g. I am using a pawn class as an aeroplane.
So should I just use a charactermovementcomponent and make its MovementMode as flying(in case it affects replication) and replicate it?
Or
Create something of my own for replication.
Or
Just switch on the replicate movement and pass movement position to the server.(I don’t think it will work well though)
The simplest step is to simply check the ‘Replicate Movement’ box in the Blueprint (under the Replication tab in Defaults view). This will give you the most basic form of replicated movement, and it’ll even do Physics Objects too. One thing it doesn’t replicate is physics forces imparted onto objects, so if you’re physics-driven you might experience some odd behaviour and a lot of rubber-banding/snapping on clients.
‘Replicates Movement’ will only attempt to sync movement on the clients from the server. You’ll have to setup your movement so that it’s performed on the server, and then rely on the Replication to pass that new information to the clients. This is all Latency and connection dependent, so the clients will never get completely seamless control of their object and control might seem a bit unresponsive.
The best way is to simulate the movement on the client AND the server, but when the client receives a position/rotation update, just interpolate to it smoothly to prevent rubber banding, which is exactly what CharacterMovementComponent does. A lot of FPS games do this to keep the movement fluid for the clients, and more often than not the predicted movement is correct, so the rubber banding is practically invisible.
EDIT: It’s also worth adding that CMC’s are very strictly tied to Character classes, which have a capsule collision, skeletal mesh etc. Creating your own component is probably much easier.
Hmm I guess then there is easy way to do it then. Then another thing I have to check is if the server can move to the replicated movement location which the client is moving to.
Should I send the movement Location from the client each tick? And should I optimize the location. Like send the location has an FIntVector instead of FVector? I don’t think I will require that much accuracy.
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.
I didn’t know that… I recently wrote my own network-enabled MovementComponent and was sending user input to the server at approx. 30x/second manually (unreliable but ordered via timestamp). I’ll have to look into that, it sure would be nice if UE4 did that part for me.
Do you know of a handy reference to look that up? I can’t see one, and won’t be able to check it myself until morning.
The input is not automatically sent from client to server I checked now. So I need to use efficient server calls to sent the current state of the client to the server.
Also another question. FVector_NetQuantize100 2 decimal point precision?
And FVector_NetQuantizeNormal = just from +1 to -1?
Physics-based movement is pretty common these days. How can we get objects that move via AddImpulse to move smoothly? I mean, I assume this is why I’m seeing my actors blinking from one location to the other without any client-side prediction. Or is my assumption incorrect and it’s something else I’m doing wrong? It seems like estimating the position between updates (via velocity) is a no-brainer but I’m not seeing it happen.
Appreciate any assistance.
EDIT: I just read elsewhere that you have to do client-side prediction yourself, so what I’m seeing isn’t directly related to the physics. I really think this should be built-in but oh well, now I know.
Bit of a bump that one, but I can add some information now that I’ve actually gone through and done this.
So essentially, the problem with using PhysX for networked physics is that replaying old moves is pretty much impossible unless you want to save the entire physics scene state every time your movement code ‘ticks’. I gave up on doing my movement with PhysX a while ago now. For replay / reconciliation to work, you have to update and replay the entire scene to have it working properly, which is costly.
There isn’t any one-size-fits-all prediction system, and frankly the engines Character Movement class is unbelievably messy. A lot of the code in CMC can be separated out into different classes or static managers (especially the timestamp code which is a minefield in itself) - and a lot of the functions could easily be templated to send different input to the server. It’s a relic from the UT / Gears days I expect, and while it’s had some improvements since the engine has released it’s very one-dimensional. For my hovertank game (which needs predictive physics-like movement), I had to essentially create my own version of the CMC, but along the way I tried to separate common code into different core classes so that the movement components themselves stay quite small. This took about 3 months (on and off) all said and done, but now works for both my hover vehicles and will work for turreted tracked vehicles etc as well.
There are some caveats to my current solution:
At the moment, there’s no ‘smoothing’. For smoothing, you need to have a separated collision primitive and a visual mesh. My vehicles are skeletal meshes using Physics Assets for collision (because the shape and size varies so widely, so no default primitive will fit). Currently I don’t have a way of separating the visual mesh from the collision in the skeletal mesh itself, so until I do that’s a problem. The code for smoothing is done, but until I can move the collision and visual mesh separately it won’t do anything.
Input values have to be clamped between -1.f and 1.f. This is because the input is quantized when sent over the network, and for that to work, you need to know the range. This is perfect for me, because mouse delta doesn’t change how fast my vehicles can move or rotate.
This is the major one (and is also a factor for character movement) - because you’re not using PhysX for movement, you have to write your own collision rejection. This is bloody easy for a Character with a capsule collision, but a minefield for me with floaty vehicles. This would be the major advantage of using PhysX, since it’s collision code is probably also faster than anything I could write. My collision code is also pretty sh*t at the moment.
Replicating PhysX objects with prediction is difficult, basically. I sank about 4/5 months of time into trying to do it, and never got anywhere. The combination of having to replay an entire scene, trying to sync timestamps from different players with variable frame times and connections speeds and everything else was just too much work for one person. Some people have had luck doing this, but have so far kept their code to themselves (perfectly reasonable of course, but unfortunate all the same).
Remote clients (non-local clients) just rely on replicated movement. You can’t do prediction for every client on every other client, because the bandwidth consumption becomes insane.
Unreal Tournament has always used client-authoritative physics and brute-force server corrections. Who knows, maybe UT4 will be different and we’ll finally see a more templated network model!