HMD / controller replication with dedicated servers
Default server tick rate is 30tick, this may be a bit slow for VR games to really feel good so I would suggest upping it to 60tick if possible. For the HMD and Controller replication settings you need the UpdateRate to be AT or UNDER the server tick rate in order for smoothing to function properly (IE: for 60 tick, anything at or under 60 htz would work). Listen servers tick regardless and do not have this issue.
I will note though that the sweet spot for replication rate is 45htz, at 45htz if steamVR starts reprojecting then the updates will still be at full value, and when not reprojecting it will be about half refresh rate which is good.
Simulated objects and the character
By default I have gone in and disabled the player character from being blocked by simulating objects. This is because it is generally very disorienting and can cause movement hitching / stuttering when physx starts jittering.
You can turn it back on by setting
bool bAllowSimulatingCollision to true in the Root Component, this lets the capsule be blocked by physx simulating objects.
Also you may want to set bool bIgnoreSimulatingComponentsInFloorCheck in the movement component to false. This will let you stand on physx simulating objects.
Client Authoritative Rotation
As of mid 4.19 / early 4.19 I switched the default VRCharacter behavior (not simple vr character) to have client rotations be server authoritive with correction support. This means that if you want to test an FPS pawn, or want the legacy default engine behavior period, that you need to enable bUseClientControlRotation in the VRCharacterMovementComponent. This is false by default, when true it will use the original engine setup of just blindly setting rotation to match what the client sent in.
With the rotation authoritative you will want to perform actor rotations with one of the rotation MoveActions that have been added to the character. IE: Snap turn with a value or delta value, or SetActorRotation move action.
Smooth turning in multiplayer
Characters in engine default to using Bytes to replicate rotation axis’s, I have defaulted characters as of late 4.18.3 to use short components as the Pitch/Roll generally don’t replicate anyway. If you want to save the 1 byte cost and are not using smooth turning you can turn this back to byte components in your character BP or file. If you are on an older version you may want to set this to short components in order to get smoother rotation.
For many people acceleration is a potential cause of sickness in VR, to avoid acceleration when moving you can set the following variables in c++ or BP for the character movement component.
bRequestedMoveUseAcceleration = false; MaxAcceleration = 200048.0f; BrakingDecelerationWalking = 200048.0f;
Setting braking and max accel to high values effectively removes the ramp up accel time.
Client Authoritative Position
While generally undesirable in 2D games, client authed movement is actually better suited to VR, see as how the client already controls most aspects of their movements clients side. While not on by default with the plugin, it is still an option should you have issues with the character rollback.
Unknown to most this is already an available feature in engine (though it is defaulted to off).
/* If client update is within MAXPOSITIONERRORSQUARED then he is authorative on his final position /
To turn it on you can add the following lines to your DefaultGame.ini
Although this makes the client authoritative within the range, you can force it to always be authoritative with:
Set to true in the CharacterMovementComponent
IK Mesh ticking group
Skeletal meshes Animation Blueprint Graphs are ticked when the skeletal mesh itself is ticked. If your IK is lagging behind you should set the skeletal meshes tick group to something later in the stack (like post physics so physics grips are done by then).
As of 4.19 Epic added a scoped function to avoid updating the bones of a skeletal mesh until final movement when combining moves. I added a GetIKMesh() function that you can override in c++ or BP to pass in your IK mesh to avoid the bone movements. It may also be used in the future for further optimizations and features.