docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Physics

    The Netcode package has some integration with Unity Physics which makes it easier to use physics in a networked game. The integration handles interpolated ghosts with physics, and support for predicted ghosts with physics.

    This works without any configuration but will assume all dynamic physics objects are ghosts, so either fully simulated by the server (interpolated ghosts), or by both with the client also simulating forward (at predicted/server tick) and server correcting prediction errors (predicted ghosts), the two types can be mixed together. To run the physics simulation only locally for certain objects some setup is required.

    Interpolated ghosts

    For interpolated ghosts it is important that the physics simulation only runs on the server. On the client the ghosts position and rotation are controlled by the snapshots from the server and the client should not run the physics simulation for interpolated ghosts.

    In order to make sure this is true Netcode will disable the Simulate component data tag on clients on appropriate ghost entities at the beginning on each frame. That make the physics object kinematic and they will not be moved by the physics simulation.

    In particular:

    • The PhysicsVelocity will be ignored (set to zero).
    • Yhe Translation and Rotation are preserved.

    Predicted ghosts and physics simulation

    By the term Predicted Physics we mean that the physics simulation runs in the prediction loop (possibly multiple times per update from the tick of the last received snapshot update) on the client, as well as running normally on the server.

    During initialization Netcode will move the PhysicsSystemGroup and all FixedStepSimulationSystemGroup systems into the PredictedFixedStepSimulationSystemGroup. This group is the predicted version of FixedStepSimulationSystemGroup, so everything here will be called multiple times up to the required number of predicted ticks. These groups are then only updated when there is actually a dynamic predicted physics ghost present in the world.

    All predicted ghosts with physics components will run this kind of simulation when they are dynamic. Like with interpolated ghosts the Simulate tag will be enabled/disabled as appropriate at the beginning of each predicted frame, but this time multiple simulation steps might be needed.

    Since the physics simulation can be quite CPU intensive it can spiral out of control when it needs to run multiple times. Needing to predict multiple simulation frames could then result in needing to run multiple ticks in one frame as the fixed timesteps falls behind the simulation tick rate, making the situation worse. On server it may be beneficial to enable simulation batching in the ClientServerTickRate component, see the MaxSimulationStepBatchSize and MaxSimulationStepsPerFrame options. On clients there are options for prediction batching exposed in the ClientTickRate, see MaxPredictionStepBatchSizeFirstTimeTick and MaxPredictionStepBatchSizeRepeatedTick.

    Using lag compensation predicted collision worlds

    When using predicted physics the client will see his predicted physics objects at a slightly different view as the correct authoritative view seen by the server, since it is forward predicting where objects will be at the current server tick. When interacting with such physics objects there is a lag compensation system available so the server can look up what collision world the client saw at a particular tick (to for example better account for if he hit a particular collider). This is enabled via the EnableLagCompensation tick in the NetCodePhysicsConfig component. Then you can use the PhysicsWorldHistorySingleton to query for the collision world at a particular tick.

    Multiple physics worlds

    Predicted simulation will work by default and all physics objects in the world should be ghosts. To enable client-only physics simulation (for example to use it run VFX, particles and any other sort of physics interaction that does not need to be replicated) another physics world needs to be created for it.

    By default, the main physics world at index 0 will be the predicted physics world, but a separate client-only physics world can also be created, running it's own distinct simulation. This can be done by implementing a custom physics system group and providing it with a new physics world index. Creating a client only physics world at index 1 can be done most simply like this:

    [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)]
    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public partial class VisualizationPhysicsSystemGroup : CustomPhysicsSystemGroup
    {
        public VisualizationPhysicsSystemGroup() : base(1, true)
        {}
    }
    

    Where the arguments to the custom class constructor are the world index and boolean indicating if it should share static colliders with the main physics world. Physics simulation will here run in the usual FixedUpdateSimulationGroup as usual. See more about the CustomPhysicsSystemGroup in the Unity Physics documentation.

    The two simulations can use different fixed-time steps and are not required to be in sync, meaning that in the same frame it is possible to have both, or only one of them to be executed independently. However, as mentioned in the previous section, for the predicted simulation when a rollback occurs the simulation may runs multiple times in the same frame, one the for each rollback tick. The client only simulation of course just runs once as normally.

    When a client only physics world exists, all non-ghost dynamic physics objects can be moved to that. This can be configured in the NetCodePhysicsConfig component which can be added to a subscene. By setting the ClientNonGhostWorldIndex there to the client only physics world index all dynamic non-ghosts will be moved there.

    As part of the entity baking process, a PhysicsWorldIndex shared component is added to all the physics entities, indicating in which world the entity should be part of.

    Note

    It is the responsibility of the user to setup their prefab properly to make them run in the correct physics world. This can be achieved with the PhysicsWorldIndexAuthoring component, provided with the Unity Physics package, which allows setting the physics world index for rigid bodies. For more information, please refer to the Unity Physics documentation.

    Interaction in between predicted and client-only physics entities

    There are situation when you would like to make the ghosts interact with physics object that are present only on the client (ex: debris). However, them being a part of a different simulation islands they can't interact with each-other. The Physics package provides for that use-case a specific workflow using Custom Physics Proxy entities.

    For each physics entity present in the predicted world where you would like to interact with the client-only world, you need to add the CustomPhysicsProxyAuthoring component. The baking process will then automatically create a proxy entity with the necessary physics components (PhysicsBody, PhysicsMass, PhysicsVelocity) along with a CustomPhysicsProxyDriver which is the link to the root ghost entity. It will make a copy of the ghosts collider as well and configure the proxy physics body as kinematic. The simulated ghost entity in the predicted world will then be used to drive the proxy by copying the necessary component data and setup the physics velocity to let the proxy move and interact with the other physics entities in the client-only world.

    The ghost proxy position and rotation and are automatically handled by SyncCustomPhysicsProxySystem system. By default the kinematic physics entity is moved using kinematic velocity, by altering the PhysicsVelocity component. It is possible to change the default behavior for the prefab by setting the GenerateGhostPhysicsProxy.DriveMode component property. Furthermore, it is possible to change that beahviour dynamically at runtime by setting the PhysicsProxyGhostDriver.driveMode property to the desired mode.

    Limitations

    As mentioned on this page there are some limitations you must be aware of to use physics and netcode together.

    • Physics simulation will not use partial ticks on the client, you must use physics interpolation if you want physics to update more frequently than it is simulating.
    • The Unity.Physics debug systems does not work correctly in presence of multiple world (only the default physics world is displayed).
    In This Article
    Back to top
    Copyright © 2024 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)