Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Question Simulate physics multiple times a frame

Discussion in 'Physics for ECS' started by Ftoveyan, Apr 25, 2024.

  1. Ftoveyan

    Ftoveyan

    Joined:
    Jan 16, 2024
    Posts:
    9
    I'm trying to create a client-side prediction and reconciliation system for networked physics (I don't want to use Netcode for Entities, for various reasons), this involves overriding the states of all my physics entities on the client to whatever I'm receiving from the server (which will be x cycles behind, where x is the latency), and then manually invoking the physics simulation x times on the client, to catch back up with the correct time. Client-side prediction and state overriding is all working fine, but I'm struggling with the reconciliation, purely because I can't figure out how to actually get physics to simulate multiple times in one frame.

    With regular Monobehaviour and PhysX, this is as simple as
    Code (CSharp):
    1. Physics.Simulate(deltaTime);
    , but I can't for the life of me figure this out with ECS and UnityPhysics.

    I understand that all the physics systems execute within FixedStepSimulationSystemGroup, so I've tried

    Code (CSharp):
    1.         var physicsSystem = Unity.Entities.World.DefaultGameObjectInjectionWorld.GetExistingSystem<FixedStepSimulationSystemGroup>();
    2.  
    3.         for (int i = 0; i < 2000; i++)
    4.         {
    5.             Debug.Log("Sim phys " + i);
    6.             physicsSystem.Update(Unity.Entities.World.DefaultGameObjectInjectionWorld.Unmanaged);
    7.         }
    This certainly hitches the framerate, but I would expect to see all my physics object "jump forward", and this doesn't happen, the game pauses for a fraction of a second, and then continues as if no additional physics simulations occurred.

    What's the correct way to do this? Manually invoking the physics simulation doesn't feel like that obscure a use case, and yet (as with much of ECS) I'm struggling to find docs on this)

    For context, I'm using ECS because I want the determinism offered by UnityPhysics, performance is nice, but that's less so why I'm here :)
     
  2. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    850
    FixedStepSimulationSystemGroup by default uses a rate manager that determines whether or not to actually run the systems it holds, based on the time known to the world. The rate manager in turn sets some state that is only visible to the systems that run in that group, such as updated double rewindable allocators (SystemState.WorldUpdateAllocator) and time that has been ticked from the previous execution of the group, so times inside the group for a time step of 0.05 would be 0, 0.05, 0.10, … The specific default rate manager used by FSSSG uses catch-up behaviour, so if you start from world time 0 and have a delta time of 0.13 for a final elapsed time of 0.13, your fixed step group would run 2 times: once from 0.0 to 0.05, and once more for 0.05 to 0.10. Next frame, if you have a delta time of 0.04 for a final elapsed time of 0.17, your fixed step group would run once for 0.10 to 0.15.

    Basically, running FSSSG in a loop would not do anything after the first call, since the world time outside it did not change.
    Physics should solely care about the delta time and not consider the actual time for anything, so you might be able to just run the PhysicsSystemGroup by itself instead. Be sure to push / pop the correct fixed delta time value so the simulation steps correctly, otherwise you would be using the actual game’s dynamic frame delta time.
     
  3. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    850
  4. Ftoveyan

    Ftoveyan

    Joined:
    Jan 16, 2024
    Posts:
    9
    This is a huge help, investigating this now and making progress! :)
     
  5. Ftoveyan

    Ftoveyan

    Joined:
    Jan 16, 2024
    Posts:
    9
    I find that surprising, when using UnityPhysics across different clients, the physics simulation isn't diverging across clients like it does with PhysX... perhaps it's just less non-determinstic than PhysX?

    E.G, let's say I have a pile of basketballs..
    PhysX
    The pile will be stable on the server, but collapse on the client
    UnityPhysics
    The pile will be stable on both, or collapse on both
     
  6. daniel-holz

    daniel-holz

    Unity Technologies

    Joined:
    Sep 17, 2021
    Posts:
    329
    For running Unity Physics multiple times per frame, have a look at the predictive physics simulation done in the Pool demo in the PhysicsSamples project.
     
    Spy-Master likes this.