Search Unity

Resolved (Case 1315688) multi worlds UpdateInGroup(typeof(FixedStepSimulationSystemGroup) update behavior

Discussion in 'Physics for ECS' started by TheOtherMonarch, Feb 18, 2021.

  1. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    867
    I have been playing around with mult-worlds see code below. if you comment out [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] then OnUpdate will be called 10 times as expected. However, if you do not then OnUpdate will be called 11 times. Being called Twice on update #7.

    Code (CSharp):
    1. [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    2. public class ProjectSystem : SystemBase
    3. {
    4.     private int count = 0;
    5.  
    6.     protected override void OnCreate()
    7.     {
    8.  
    9.     }
    10.  
    11.     protected override void OnDestroy()
    12.     {
    13.  
    14.     }
    15.  
    16.     protected override void OnUpdate()
    17.     {
    18.         count++;
    19.         Debug.LogError("OnUpdate:  " + count);
    20.     }
    21. }
    22.  
    Code (CSharp):
    1. public class ProjectAuthoring : MonoBehaviour
    2. {
    3.     //private ProjectSystem mySystem;
    4.     private World locECSWorld;
    5.     private int counter = 0;
    6.  
    7.     void Start()
    8.     {
    9.         locECSWorld = new World("world1", WorldFlags.Simulation);
    10.         var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
    11.  
    12.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(locECSWorld, systems);
    13.  
    14.         locECSWorld.GetOrCreateSystem<ProjectSystem>();
    15.     }
    16.  
    17.     void FixedUpdate()
    18.     {
    19.         if (counter < 10)
    20.         {
    21.             counter++;
    22.             Debug.Log(" FixedUpdate :  " + counter);
    23.             locECSWorld.Update();
    24.         }
    25.     }
    26.  
    27.     void OnDestroy()
    28.     {
    29.         locECSWorld.QuitUpdate = true;
    30.         locECSWorld.EntityManager.CompleteAllJobs();
    31.         locECSWorld.EntityManager.DestroyAndResetAllEntities();
    32.         locECSWorld.Dispose();
    33.     }
    34. }
     
    Last edited: Feb 18, 2021
  2. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
  3. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    867
    I made case 1315688. I think it is being caused by "The systems in this group will update as many times as necessary at the fixed timestep in order to "catch up". Being bugged in this case. I cannot move threads.
     
  4. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yes, that is the intention. Imagine you wanting to render at 30 fps, but step physics at 60fps. You need 2 fixed timesteps for physics for each of the rendering steps. And similar. Are you saying this is the problem for you, or just unexpected?
     
  5. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    867
    I am saying that sometimes when I manually update a ECS world I get 2 steps per fixed time step. What you say makes sense for update but not for fixedUpdate. I would think In fixedUpdate this would just be a bug.

    It causes a problem for me being able to update the ECS world a fixed number of times over multiple fixedUpdate calls. In the example locECSWorld.Update() is called every fixedUpdate.

    I have no idea if calling locECSWorld.Update() from Update() works correctly or not. But it would not allow updating the sim the way I want anyway.
     
    Last edited: Feb 23, 2021
  6. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
  7. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    867
    That thread mentions "disable the “catch-up” semantics of the fixed timestep group entirely." But does not actually mention how to do this.

    My use case is a lock step networking sim where. I step the physics world, at a fixed step size, as I get new inputs. Sometime multiple times. Spread-out over a few frames if possible. Sometimes not at all. The graphics part of the game gets updates separately in order to smooth things out.

    The number of updates must match on all clients. I cannot just have stuff ticking away while waiting for input.
     
    Last edited: Feb 23, 2021
  8. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    You could tick your ecs world in update, not necessarly in fixedupdate, as long as you wrap it with custom time checking condition to meat you frame rate. This is just what fixedupdategroup do.
    If you want disable catchup when using
    ComponentSystemGroup
    , you could assign
    FixedRateSimpleManager
    rather than
    FixedRateCatchUpManager
    to
    ComponentSystemGroup
    's
    FixedRateManager
     
  9. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    867
    I still find it strange that ECS maintains its own fixed world time unsynchronized with Time.fixedTime.

    @BobFlame I really don't want to hack the physics code, too afraid of side effects. I guess that it is not really possible to step ECS + physics this way. I mean I can step a ECS world too some degree just not the physics part.

    I will look into having a separate ECS world I step with update() for my game play scripts. I really don't know, I may write my own physics engine that I control or try Simulation.StepImmediate and find a way to ignore ECS completely.

    I am getting the feeling that ECS / unity physics was just not designed for lock-step sims.
     
    Last edited: Feb 24, 2021
  10. BobFlame

    BobFlame

    Joined:
    Nov 12, 2018
    Posts:
    95
    I have implement a multiworld network architecture, different world represent different zones on server, all zones ticked by main game(another world). You dont need to modify unity package, only create your own group by inheriting ComponentSystemGroup. Your ComponentGroup update in a higher frequence, check time each frame to update subsystem on fixed time rate. And when it's updating, set the right TimeData to world, so all subsystem could use time correctly.

    You should look into code ComponentSystemGroup and FixedRateManager and you will know there is no magic, it's merely a time checker. You will get your solution there.
     
    Last edited: Feb 25, 2021
    milos85miki and TheOtherMonarch like this.