Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Are custom worlds broken or no longer supported?

Discussion in 'Data Oriented Technology Stack' started by Sibz9000, Mar 24, 2019.

  1. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    84
    Right here's a working example. It's all a bit confusing, and very likely to change in future releases for that reason.
    Code (CSharp):
    1. [AlwaysUpdateSystem]
    2. public class MyCS : JobComponentSystem, IMyInterface
    3. {
    4.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    5.     {
    6.         Debug.Log("Is Running");
    7.         return inputDeps;
    8.     }
    9.     protected override void OnCreate()
    10.     {
    11.     }
    12. }
    13.  
    14. interface IMyInterface { }
    15.  
    16. public class Bootstrap : ICustomBootstrap
    17. {
    18.     public List<Type> Initialize(List<Type> systems)
    19.     {
    20.         // Get a list of systems with interface
    21.         var systemsWithInterface = systems
    22.             // Where type has any interface with name of my interface
    23.             .Where(type => type.GetInterfaces().Any(iface => iface.Name == nameof(IMyInterface)))
    24.             .ToList();
    25.  
    26.         // Remove from default systems list so they are not created in default world
    27.         systems.RemoveAll(type => systemsWithInterface.Contains(type));
    28.  
    29.         // Create our world
    30.         var MyWorld = new World("World with systems that have IMyInterface");
    31.  
    32.         // To Change 'Default world'
    33.         // `World.Active = MyWorld`
    34.  
    35.         // Update player loop
    36.         // `ScriptBehaviourUpdateOrder.c(MyWorld);`
    37.         // NB this moves the default systems to this world,
    38.         // but they are moved to default world again if you return anything but null from this method
    39.         // So call UpdatePlayerLoop if you want your world to be the default world
    40.         // and host the default systems and be automatically updated
    41.         // (and remember to return null from this method)
    42.  
    43.         // If not changing default world
    44.         // World.Active is intialized with 'shared' default systems here
    45.         ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.Active);
    46.  
    47.         // We must use 'shared' default systems
    48.         var simGroup = World.Active.GetExistingSystem<SimulationSystemGroup>();
    49.  
    50.         // Add systems
    51.         foreach (var type in systemsWithInterface)
    52.         {
    53.             var system = MyWorld.CreateSystem(type);
    54.             // If you want to support [UpdateInGroup] you need to do reflection
    55.             // and add to correct group here.
    56.             simGroup.AddSystemToUpdateList(system);
    57.             simGroup.SortSystemUpdateList();
    58.         }
    59.  
    60.         // Return systems for default world
    61.         // Return null if you changed the default world
    62.         return systems;
    63.     }
    64. }
    65.  
     
    Last edited: Apr 21, 2019
  2. Piefayth

    Piefayth

    Joined:
    Feb 7, 2017
    Posts:
    58
    Ahh, I get the approach now. I was missing the fact that UpdateBefore/After are processed in SortSystemUpdateList, which, of course, makes sense in retrospect.

    My criticism here is, aren't you just repeating the work that DefaultWorldInitilization would do for you? You can get the same effect using it to create your world, AND each world then gets a unique CustomBootstrap Initialize call during which you can filter your systems. Plus it should automatically support UpdateInGroup.
     
    Sibz9000 and wobes like this.
  3. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    84
    I think you are right. There was a reason I didn't use DefaultWorldInitialization to begin with, I first started with that, but something made me go for this alternative approach. but I can't rebember now what it was. I'm going to try it and see what happens.
     
  4. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    84
    Ah yes, For the purposes of automatically populating worlds, DefaultWorldInitialization only populates the last world.
    Given the example below, the default world is empty and DefaultWorldSystem does not update.
    So while I repeat what DefaultWorldInitialization does, this is the only way I can get two worlds that are hooked up to the Initialization/Simulation/Presentation update groups.

    If that's not necessary, and you don't mind not seeing systems in the entitydebugger. You can just add systems to a world and manually call update.

    Note UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP is defined hence I Initialize the "Default World" myself in this example.
    Code (CSharp):
    1. public class Bootstrap : ICustomBootstrap
    2. {
    3.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    4.     public static void Init()
    5.     {
    6.  
    7.         DefaultWorldInitialization.Initialize("Default World", false);
    8.         DefaultWorldInitialization.Initialize("Test World", false);
    9.     }
    10.  
    11.     public List<Type> Initialize(List<Type> systems)
    12.     {
    13.         if (World.Active.Name == "Test World")
    14.         {
    15.             systems.Remove(typeof(DefaultWorldSystem));
    16.             return systems;
    17.         }
    18.         systems.Remove(typeof(CustomWorldSystem));
    19.         return systems;
    20.     }
    21. }
    22.  
    23. public class CustomWorldSystem : ComponentSystem
    24. {
    25.     protected override void OnUpdate()
    26.     {
    27.  
    28.     }
    29. }
    30.  
    31. public class DefaultWorldSystem : ComponentSystem
    32. {
    33.     protected override void OnUpdate()
    34.     {
    35.  
    36.     }
    37. }
     
  5. drhodor

    drhodor

    Joined:
    Aug 18, 2013
    Posts:
    20
    What are the best ways to filter systems between worlds? I am trying to get just what I need to run Unity Physics into a custom world, but none of the other stuff that comes from a Default World Initialization.
     
  6. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    84
    For separating Unity.Physics system groups, a guess would be to filter on that namespace. But I do not know if there are other systems outside that name space that may be dependent on.
    If you used
    DefaultWorldInitialization.Initialize("MyPhysicsWorld", false);

    you could use the code below. Be aware that calling DefaultWorldInitialization.Initialize may have unintended consequences for the default systems. You may want to call
    DefaultWorldInitialization.Initialize("Default World", false);
    after, but that may muck up how the physics systems update.
    Note: this may not actually work as intended, but shows how to filter on namespace.
    Code (CSharp):
    1.     public List<Type> Initialize(List<Type> systems)
    2.     {
    3.         var physicsSystems = systems.Where(type => type.Namespace != null && type.Namespace.StartsWith("Unity.Physics")).ToList();
    4.         if (World.Active.Name == "MyPhysicsWorld")
    5.         {
    6.             return physicsSystems;
    7.  
    8.         }
    9.         systems.RemoveAll(type => physicsSystems.Contains(type));
    10.         return systems;
    11.     }

    If you want to use https://github.com/Sibz/CustomWorldBootstrap then the following should work:
    Code (CSharp):
    1. public class Bootstrap : CustomWorldBootstrap
    2. {
    3.     public Bootstrap()
    4.     {
    5.         WorldOptions.Add(new WorldOption("My Physics World")
    6.         {
    7.             CustomIncludeQuery = (systems) => systems.Where(type => type.Namespace != null && type.Namespace.StartsWith("Unity.Physics")).ToList()
    8.         });
    9.     }
    10. }
    NB: this will update the systems in their intended groups and hopefully work without an issue, however I have not worked with the Unity.Physics namespace so can not be sure that this is all you need to do to isolate physics into it's own world.

    edit: added null check to namespace
     
    Last edited: Apr 23, 2019
  7. Sibz9000

    Sibz9000

    Joined:
    Feb 24, 2018
    Posts:
    84
    Just tested with CustomWorldBootstrap, it works as far as setting up the systems goes, haven't tested any actual physics in world.
    There's one warning though: