Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

PlayerLoopSystem bug when Entities package is _not_ installed

Discussion in 'Experimental Scripting Previews' started by Baste, Oct 10, 2018.

  1. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    I've got a bug with the PlayerLoopSystem stuff. I don't know if it's supposed to go here, or in the Entities/Jobs subforum.

    The bug is that it seems like if I change the playerloop through doing this:

    Code (csharp):
    1. var system = PlayerLoop.GetDefaultPlayerLoop();
    2. // add callback to system
    3. PlayerLoop.SetPlayerLoop(system);
    the callback I added keeps running after I exit play mode, unless I have the entities preview package installed. If I have that one installed, the callback stops running when I exit play mode as expected.

    Anyone have any clue what's going on? I have never seen something breaking if I don't have a preview package installed. I'm assuming that entities is doing something with the PlayerLoopSystem - probably cleaning up after itself, and then inadvertently cleaning up my stuff as well?

    Here's an example script:

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEngine.Experimental.LowLevel;
    3.  
    4. public class TestScript : MonoBehaviour {
    5.  
    6.     void Start()
    7.     {
    8.         PlayerLoopSystem playerLoop = PlayerLoop.GetDefaultPlayerLoop();
    9.         var subSystemList = playerLoop.subSystemList;
    10.  
    11.         var newSubSystems = new PlayerLoopSystem[subSystemList.Length + 1];
    12.         for (int i = 0; i < subSystemList.Length; i++)
    13.         {
    14.             newSubSystems[i] = subSystemList[i];
    15.         }
    16.  
    17.         newSubSystems[newSubSystems.Length - 1] = new PlayerLoopSystem
    18.         {
    19.             type = typeof(TestScript),
    20.             updateDelegate = Test
    21.         };
    22.  
    23.         playerLoop.subSystemList = newSubSystems;
    24.         PlayerLoop.SetPlayerLoop(playerLoop);
    25.     }
    26.  
    27.     private static void Test()
    28.     {
    29.         Debug.Log("I am running");
    30.     }
    31. }
    Place that on a GameObject in a scene, enter playmode, and exit playmode. Then interact with Unity in a way that makes code run internally - the easiest is to resize a window. You'll see the log message show up.

    Now, install the Entities preview package. The bug will go away.

    I've created a bug report, will update when I get a bug #.
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Case 1089518
     
  3. carsanlop

    carsanlop

    Joined:
    Dec 12, 2017
    Posts:
    11
    Did you manage to find a fix for this?
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    It was marked as "by design" (!!!). So that's bonkers.

    The fix is to set up a thing that manually resets the player loop after you exit play mode, by taking a copy of the default player loop before you start changing things, and then setting the player loop back to that after.

    I created a wrapper for creating player loop systems, and put it on Github. You can check the code in PlayerLoopInterface.EnsureSystemFetched and PlayerLoopQuitChecker to see how resetting works. It's not very complex.
     
  5. carsanlop

    carsanlop

    Joined:
    Dec 12, 2017
    Posts:
    11
    Thanks for your quick reply.

    That is surely some strange design! So the solution ends up requiring a GameObject. Too bad. My use case is being able to call lifecycle events (e.g. Update) on non-MonoBehavior objects. I already had a singleton object to provide the functionality, and wanted to experiment with improving the code by using the PlayerLoop. Guess I will stick with what I have.

    I will take note of your code in case my requirements expand on the future.

    Again, thanks!