Skip to content

Latest commit

 

History

History
17 lines (14 loc) · 4.87 KB

tutorial-netcodecharacters-optimization.md

File metadata and controls

17 lines (14 loc) · 4.87 KB

Netcode character optimization ideas

General

  • If you don't need the convenience of being able to easily switch a player's controlled character or have the character entity be destroyed without destroying player data, you could choose to make the Player and the Character be the same entity. This would remove the need to have one ghost for each. If you do this, you may also want to tweak the Player systems to use components on the same entity rather than getting those components via lookups.
  • If the character will only ever rotate around the world up axis, you can synchronize only the Y euler angle of the character rotation instead of the full quaternion. For this to work, you'll have to add a prediction system that updates in the PredictedSimulationSystemGroup before PredictedFixedStepSimulationSystemGroup, and reconstructs the character's LocalTransform.Rotation from that Y euler angle before any other system tries to use the rotation (you might have to make sure this updates before the OrbitCameraPrePhysicsSystem as well if using the third-person character).
  • Depending on whether or not you will need access to some of the synchronized character/player/camera data on interpolated clients, you could select the Only send when "Known Predicted" as the Send Optimization for the various synchronized components in the Ghost Authoring Inspection Component of character/player/camera prefabs.
  • If your character does not need the concept of a "Parent Entity" (does not need to stand on moving platforms, etc...), you can remove ghost fields for the ParentEntity, ParentLocalAnchorPoint, and ParentVelocity fields of the KinematicCharacterBody component.
    • Even if you do still need to support character parent entities, additional optimizations are possible:
      • KinematicCharacterBody.ParentVelocity synchronization can be omitted if you make sure you only ever de-ground the character from its parent entity (or destroy the parent entity while the character is parented to it) between the Update_ParentMovement and Update_MovingPlatformDetection steps of the character update.
      • KinematicCharacterBody.ParentLocalAnchorPoint synchronization can be omitted if you take care of setting it manually & deterministically after the Update_Initialize and before the Update_ParentMovement steps of the character update. For full precision, you would have to find the point of contact between the character collider and the parent entity using a physics query, and calculate the contact point's local position compared to the parent entity. Remember that you cannot use the character's ground hit for this, because this would be happening before the character has detected grounding. Otherwise, if you don't mind a precision/quality loss for the logic that makes the character follow a rotating moving platform, you can also set it to the local position of the bottom of the character compared to the parent entity. Since we must choose between a performance penalty (find contact point with a physics query), a quality penalty (using character capsule bottom instead of true contact point), or a bandwidth penalty (synchronizing KinematicCharacterBody.ParentLocalAnchorPoint) in a netcode context, this isn't done by default.
      • You can limit what is synchronized on moving patform ghosts based on what you can assume in terms of how moving platforms move in your game. For example, if you know that your moving platforms will only ever move their position but not their rotation, you can only synchronize positions rather that full transforms.

Third person character (orbit camera)

  • If nothing in your game's simulation will need to rely on your character camera's position or distance, you may remove the ghost field attribute from OrbitCamera.TargetDistance, and move all of the camera distance/position handling code to the (non-predicted) OrbitCameraLateUpdateSystem, before orbitCamera.SmoothedTargetDistance is calculated.
  • You could avoid making the orbit camera prefab a ghost completely, if you make your character components and systems responsible for calculating and storing a "camera rotation". Then, owning clients would simply spawn a local prefab for the camera whenever their character is spawned by the server, and that prefab would always be setting its rotation to that calculated "camera rotation" stored in the character components. Instead of using the rotation of the camera entity in order to determine where the character should move or rotate to, you would be using this stored "camera rotation" on the character.
  • If the character will only ever rotate around the world up axis, and the camera doesn't have to follow the change in the character's up direction, you could replace the camera's float3 PlanarForward ghost field with a simple float YawAngle, and make camera yaw calculations based on this. This would require less bandwidth to synchronize.