Search Unity

Resolved Long wait when entering play mode (Application.EnterPlayMode & Application.UpdateScene)

Discussion in 'Physics for ECS' started by Interjection, Sep 19, 2020.

Thread Status:
Not open for further replies.
  1. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    Ever since I changed over to the Universal Render Pipeline for rendering and DOTS for physics it has started to take a lot of time when entering play mode in the editor.

    From me pressing play in the editor it takes 13 seconds until it actually plays and something moves. If I go to Project Settings > Editor > Enter Play Mode Options (Experimental) and have both "Reload Domain" and "Reload Scene" unchecked the time goes down to 8 sec. Turning off Safety Check or Leak Detection for Jobs does nothing.

    It may not sound so bad with 13 or 8 sec but thing is before I changed over to URP and DOTS it took less than 2 seconds. My developing "style" is to make a small change and check/verify the results before changing something else, having to keep waiting 13 unresponsive seconds between every change is driving me insane.

    When I enter play mode a "Hold on" window shows up with "Application.EnterPlayMode" and then later it changes to "Application.UpdateScene". The second message shows longer than the first one.

    Is there a way to see what Unity is doing while it is showing these "Hold on" messages? That way I could figure out if it is indeed DOTS that is the bulk of the delay or if it has to do with me modifying textures or someting.

    Other tips of speeding up the waiting when entering play mode is of course also welcome. Other than buying a faster CPU. ;)
     
    Edy likes this.
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    Are you doing runtime conversion or using subscenes?

    You can just use the profiler to see what's taking long
     
  3. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    What are your Burst settings (synchronous?)? Also, do you have meshes in your scene? They have synchronous Burst compilation on creation, so it would be great to keep the "enter playmode settings" ticked with the other 2 options unticked.
     
    xploreygames likes this.
  4. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    For some reason I was sure this was something that didn't show up in the profiler, that it was work Unity did before entering the first frame meaning the profiler wouldn't catch it. But yeah, seems like whatever it is doing does show up in the profiler. Problem is it just says that all of the work is being done on "self" inside an Update() of a single component (my GameController, which calls my game loop with all the logic).

    Self ms was 7822.30 of "PlayerLoop/Update.ScriptRunBehaviourUpdate/BehaviourUpdate/MyGameControllerClassName.Update()". Turning on deep profiling causes Unity to crash after a while with this dialog: "Microsoft.ServiceHub.Controller.exe - System Error: A new guard page for the stack cannot be created."

    (Side note, got stuck on "Hold on: Application.Message" for 3 minutes while selecting the MemoryManager.FallbackDeallocation entry in the profiler (something that was called over 38 thousand times on that frame, adding 9 ms total to the frame time). Wasn't sure if Unity had frozen or not so it would be useful to see what is going on while showing the "Hold on" message. Could show subtasks or something, but maybe it's hard to show any kind of information there without too much overhead.)

    Anyway...

    After a lot of manual searching with System.Diagnostics.Stopwatch to find out what was taking so much time it seems like it all comes down to Unity.Physics.MeshCollider.Create(), which is a helper method by Unity to create mesh colliders in DOTS.

    I only call it 224 times with less than 1000 vertices and less than 6000 triangles, yet it took 7290 ms out of the 8779 ms needed for that frame. It's used for my terrain.

    Anyway (again), starting to look like a faster CPU is needed because I doubt I could construct a MeshCollider for an Entity faster than Unity's Create() helper method. I guess I could use a much smaller terrain during testing but here I was thinking it was already too small. Testing too far from how it's supposed to be played isn't good.

    Btw1 another annoying message I'm getting is when tabbing back into Unity from changing code, then I get "Hold on: AssetDatabase.Refresh". I'm guessing this is the usual delay everybody gets but it never showed up before until I changed "Busy Progress Delay" to 1 in Preferences > General.

    Btw2 if I take the time from pressing play to something happening on screen with a stopwatch on my phone it took a couple of seconds longer than adding together the CPU times recorded in the profiler, so there's something the profiler isn't catching in terms of real wait time between pressing play and stuff starting to move.

    Btw3 to answer some of your questions, if by "runtime conversion" you mean generating lots of stuff then yeah, I generate basically everything. There are no subscenes. I have meshes in the scene but only generated ones (not imported by Unity). I don't have Synchronous Compilation for burst (the default).

    Hm, come to think of it I don't call Unity.Physics.MeshCollider.Create() from inside a burst-compiled job, I guess that would speed things up a lot. But boy would I need to rewrite a lot of stuff for that. Unless I could isolate only that call inside a Job and wait for it to finish before continuing creating the terrain, might be worth looking at. Guess this thread has been a bit "rubber duck" but thanks a lot anyway fellas. :)
     
  5. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    I'm just curious, if you press play and wait these 8 seconds or so, then stop it and immediately press play again, does it start immediately or you have to wait 8 seconds again? Because at least if nothing was changed then mesh job Burst compilation should be reused instead of being started again.
     
  6. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    @petarmHavok: The times below are taken with a stopwatch on my phone.
    After restarting Unity: 14.34 sec
    Pressing stop, waiting 30 sec, pressing play: 13.96 sec
    Pressing stop, waiting <1 sec, pressing play: 14.09 sec
    Pressing stop, waiting <1 sec, pressing play: 14.81 sec
    Pressing stop, waiting <1 sec, pressing play: 15.13 sec
    Pressing stop, waiting 30 sec, pressing play: 14.82 sec

    Doesn't seem to be any difference. But unless it's something internal in DOTS I don't think I have any mesh jobs (see the final paragraph in my previous post). Note that the meshes are generated by the game every time it starts, they aren't read from disk.
     
  7. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yeah seems like that performance is coming from actual mesh creation, not the job compilation, that's what I was trying to check.
     
  8. WildMaN

    WildMaN

    Joined:
    Jan 24, 2013
    Posts:
    128
    Was much worse for me (10k entities scene). The problem is that scene gets converted to dots every single time. The solution was to switch to subscenes, now Play is nearly instant and loading time on Android ~3sec. Be wary though that with subscenes you'll be stepping into a horrible scripted build pipeline nightmare with completely undocumented, broken and half-baked *platform packages, missing Cloud Build etc.
     
    jdtec likes this.
  9. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    @WildMaN: Thanks, I'll keep that in mind. I assume you're converting GameObjects to Entities using Unity's convert script? I don't have that in my project but maybe it'll be added someday.
     
  10. WildMaN

    WildMaN

    Joined:
    Jan 24, 2013
    Posts:
    128
    Conversion way doesn't matter. Subscene acts like a prefab - converted once and good to go. The main scene gets converted every time you press Play, change hierarchy etc. So it seems the best practice for "big" DOTS is the same as for Tiny - put everything into prefabs and subscenes and keep your main working scene as clean as possible.
     
  11. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    I've just finished putting my call to Unity.Physics.MeshCollider.Create() inside a Job and have reduced the Application.UpdateScene wait time from 9.3 sec to 1.3 sec.

    The job struct has [Unity.Burst.BurstCompile(CompileSynchronously = true)] and the only thing happening in the Execute() method is the call to Unity.Physics.MeshCollider.Create(). The main thread waits until it completes right after starting the job. Such a small change yet it still shaved 8 sec off my wait time when entering play mode.

    Edit: After entering play mode a couple of times more the execution of Create() went under 1 sec inside a burst compiled job so almost 8.5 sec was shaved by this small change.

    @WildMaN: Good advice, I generate everything from code though so I don't think I can use subscenes (I have no converted GameObjects yet).
     
    Last edited: Sep 26, 2020
    roryo, steveeHavok and petarmHavok like this.
  12. roryo

    roryo

    Joined:
    May 21, 2009
    Posts:
    1,479
    @Interjection - thanks for posting this solution. I am also trying to generate lots of MeshColliders. Out of curiosity, are you running the job from a monobehavior or a system?
     
  13. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    @roryo The job starts from Unity's regular main thread, I have no custom DOTS systems yet so the answer is I run the job from a MonoBehaviour.

    My Unity.Jobs.IJob is started with a call to Unity.Jobs.IJobExtensions.Schedule<MyIJobStructName>(theStruct); via UnityEngine.MonoBehaviour.Update().
     
    roryo likes this.
  14. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    By the way, since I've already bumped this thread I will mention something in regard to its topic (the "Hold on" window with Application.EnterPlayMode etc).

    This weekend a friend and I did a little game in Unity just for fun. For the project we used Unity 2020.1.7f1 and my friend noticed that he was now also getting a bunch of "Hold on" windows when entering play mode. This was a new experience for him who usually still works in Unity 2019.X and he was getting increasingly annoyed. Eventually he almost couldn't wait for our project to be finished so he could go back to Unity 2019 and stop getting these "Hold on" delays when entering play mode.

    So by the sound of it I wasn't hallucinating when I noticed that it takes longer to enter play mode in the editor these days. However it seems to be an issue with Unity 2020 and not an issue related to DOTS; the project we did together didn't use DOTS. We did use URP though, perhaps the "Hold on" delays are due to URP in Unity 2020? I'm not sure if he uses that in Unity 2019 but I think he does.

    Edit: I checked with him and he does use URP in Unity 2019. So it's not URP itself that's the problem (doesn't cause "Hold on" in 2019), the delays in entering play mode has something to do with Unity 2020.X. Maybe it's something in combination with URP, I have no idea.
     
    Last edited: Oct 11, 2020
    P_Jong and petarmHavok like this.
  15. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    If I remember right, hold on dialog was new in 2020.1 and it's purpose was more of make users aware of the wait times. In past the editor would have been frozen for the same time for the same operation but without separate indication it is still processing. Many people have since gotten annoyed by the hold on dialog - thinking it's actually slower now (some operations could still have different cost between 2019 and 2020 versions but the main difference here is really just showing the wait time rather).
     
  16. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    It's not impossible it's all in our heads but I wonder. It's not like the thought didn't occur to me that I might have just imagined it taking longer, but turning off the "hold on" dialog (increasing the time before it appears to several minutes) doesn't make it feel like it took just as long as it did in 2019. I'm not switching my project back to 2019 just to compare the delay now, I'll just hope that things eventually get more efficient in newer versions of Unity. If not the time will come for me to get a better CPU.

    Hm, now where's the sage button to not bump the thread needlessly...
     
  17. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    Check in your Editor Settings whether the experimental Enter Play Mode options are on (just the top checkmark).<

    That caused the "hold on" to go away, and the play mode switch time was reduced from 10 to 30 seconds down to 500ms.

    There are problems with UnityEvents that live in Assets and the Scene (which is a pattern that I used in a game jam), other than that, I had no problems without the domain reload.
     
  18. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    Static Singletones and code that runs in the editor can be nasty. Doozy UI is an example that breaks pretty horrible and I am on the edge of removing it for that reason. At some point the reload costs you more time than what those assets would save me.
     
    Thygrrr likes this.
  19. xploreygames

    xploreygames

    Joined:
    Jun 14, 2020
    Posts:
    6
    That solved it for me, thanks!
     
    petarmHavok likes this.
  20. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    Wow I was having some serious editor hangs that were delaying my work until I looked this up and saw your suggestion, simply ticking that top tickbox fixed it for me in 2020.3.0f1 and IMO it should be on by default going forward as those editor hangs were atrocious even in an empty scene!
     
    harleydk, ubbelito and Thygrrr like this.
  21. Shreddedcoconut

    Shreddedcoconut

    Joined:
    Jul 30, 2021
    Posts:
    61
    @Thygrrr, you helped me big time! After ticking that top tickbox, it almost never hangs anymore.

    This saved me a lot of time, thanks!
     
  22. harleydk

    harleydk

    Joined:
    Jul 30, 2012
    Posts:
    41
    @Thygrrr Same as the rest, helped a bunch. Unity 2021.2 here.
     
  23. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    To further clarify this, we were using a video call plugin that didn't by default clean up the resources it was using on enter/exit play mode in the editor which was also exacerbating this issue.
     
Thread Status:
Not open for further replies.