Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to create a pause system with jobs and systems?

Discussion in 'Entity Component System' started by calabi, Sep 24, 2019.

  1. calabi

    calabi

    Joined:
    Oct 29, 2009
    Posts:
    232
    I'm wondering how I would do this with jobs, this kind of goes with the how to I start and stop jobs but a bit more specific. I've heard it said that you remove the data, but that doesn't seem like a good idea(wouldn't I have to create extra data just for the pause system?) personally I would just set all the systems to disabled but is that not a good idea. I'm just wondering peoples opinions on this.
     
  2. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,112
    as my first opinion, the best approach will be to make all your concerned systems Exclude a Tag Component "Pause" in their Jobs and/or Queries.
    when you want to pause those systems just add to their related Entities the "Pause" CD Tag using Batch Operations, it should be extremely fast specially in your case the Pause Logic is not something happening every frame.

    Good Luck!
     
    Last edited: Sep 24, 2019
    starikcetin likes this.
  3. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,112
    also you cannot Interrupt Jobs (for the moment)
    normally your jobs should execute and do stuff every Frame and you should not think about them surviving over frames.
    so no need to think about stopping Jobs execution.
     
    Last edited: Sep 24, 2019
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,223
    Don't try to pause in the middle of a frame. Let the jobs finish the frame up and then on the next frame, disable all the systems you don't want to update. I usually have two ComponentSystemGroups, one for the pause menu and one for gameplay, and I only ever have one enabled at a time.
     
  5. calabi

    calabi

    Joined:
    Oct 29, 2009
    Posts:
    232
    Thanks for the replies. So if I'm understanding correctly, I create an entity with the a pause component tag on whatever button I want to use to pause. I then have an entity query in all the jobs that I want to pause that excludes that tag component.

    I'm not sure how make sure that the jobs have finished from an external system, especially if the jobs are designed to run constantly. I have to set completed(), and then check if completed from an external system?
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,223
    Your jobs usually only apply to one frame at a time. So instead of trying to pause jobs, you want to not schedule them when paused. I'm not sure why you are worried about ensuring the jobs completed. That seems like you have a bigger misunderstanding of how jobs work in ECS.
     
  7. calabi

    calabi

    Joined:
    Oct 29, 2009
    Posts:
    232
    I'll post my solution if anyone's curious and to help anyone else or if anyone has criticisms for my method.

    Code (CSharp):
    1. public struct PauseSystemsCompTag : IComponentData
    2. {
    3. }
    4.  
    5. [AlwaysUpdateSystem]
    6. public class PauseGameSystem : ComponentSystem
    7. {
    8.     public WayPointMoveSystem WayPointMoveSystemref;
    9.     public bool Isgamepausedornot;
    10.  
    11.     protected override void OnCreate()
    12.     {
    13.        
    14.         Isgamepausedornot = false;
    15.     }
    16.  
    17.     protected override void OnUpdate()
    18.     {
    19.         if (Input.GetKeyDown("p") && Isgamepausedornot == false)
    20.         {
    21.  
    22.             if (!HasSingleton<PauseSystemsCompTag>())
    23.             {
    24.                 var paused = EntityManager.CreateEntity(typeof(PauseSystemsCompTag));
    25.                 EntityManager.SetName(paused, "PausegameEntity");
    26.                 //WayPointMoveSystemref.Enabled = false;
    27.                 Debug.Log("The p key was pressed");
    28.                 Isgamepausedornot = true;
    29.             }
    30.             else
    31.             {
    32.                 Debug.Log("Something S*** happened with the pause system");
    33.             }
    34.  
    35.         }
    36.         else if(Input.GetKeyDown(("p"))&& Isgamepausedornot == true)
    37.         {
    38.             EntityManager.DestroyEntity(GetSingletonEntity<PauseSystemsCompTag>());
    39.             //WayPointMoveSystemref.Enabled = true;
    40.             Debug.Log(("The p key was unpressed"));
    41.             Isgamepausedornot = false;
    42.         }
    43.     }
    44. }
    I then put the below code in the OnCreate() method of any systems I want to pause and it seems to work, except this pause system stops running after pressing the key twice, that's why you have to have the [Alwaysupdatesystem]. I wish I understood these systems and why they do that.

    RequireSingletonForUpdate<PauseSystemsCompTag>();