Search Unity

ICustomBootstrap.Initialize() is called multiple times

Discussion in 'Data Oriented Technology Stack' started by PublicEnumE, Aug 20, 2019.

  1. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    103
    My ICustomBootstrap is having its Initialize() method called three times, each time I enter play mode.

    Is this expected behavior?
     
    Last edited: Aug 20, 2019
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,650
    "Yes" - it will be called for every world type - default, scene optimization, game object conversion.
    However to me this does not seem ideal as there is no built in way to check which type it's executing in so needs to be fleshed out.

    I have this snippet of code to only execute in default.

    Code (CSharp):
    1.             // We only want to install in default world groups, not GameObjectConversion or EntitySceneOptimizations
    2.             var attrib = systems.First().GetCustomAttribute<WorldSystemFilterAttribute>(true);
    3.             if (attrib != null && (WorldSystemFilterFlags.Default & attrib.FilterFlags) == 0)
    4.             {
    5.                 return systems;
    6.             }
    Bit hackish but works how things are setup atm (as no system exists in both default and conversion/optimization. You might have to loop the entire systems collection if this changes. Might be a better way to check, I wrote this ages ago and it still works so haven't updated.
     
  3. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    103
    Thanks - you know, this makes me wonder if I’m trying to use ICustomBootstrap in a way that Unity wouldn’t like:

    I want to use it to set up some data in a Singleton component, so it’s ready for systems to use later.

    Is that an inappropriate use of ICustomBootstrap? I’m just looking for a place to initialize some data, after a world has been created. It would be nice to not do this work in a system, since it only ever needs to run once.

    Ty!
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,650
    ICustomBootstrap was added so we could create custom worlds and systems without having to disable the automatic default world creation.
     
    Last edited: Aug 21, 2019
  5. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    103
    What would be the best way to write run-once initialization code? Do you do this in your work? If so, where?
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    422
    The run once for me happens using IConvertGameObjectToEntity and a ConvertToEntity component. You can also have a system that disables itself once it runs once. You can remove it from the world and leave it to die by GC.

    I also have a custom bootstrap. I use it to allocate some pretty crazy data structures and paradigms my core tech is built on, but I make sure to keep that bootstrap game-independent.

    The main thing is to make sure your Bootstrap does not touch World.Active unless you are creating custom worlds inside the bootstrap.
     
    PublicEnumE likes this.
  7. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    103
    Thanks, I didn’t know about this. How is this done?

    Why is this? I had not heard this before.
     
  8. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    422
    There's an enabled field. You can remove the system from a ComponentSystemGroup's update list, or you can call DestroySystem on the world..

    World.Active is a static, and in 2019.3 statics won't get reset if you want fast playmode. I'm still on 2019.2 so I don't know the behavior of automatic world initialization yet, but you're going to want to leave that variable well alone because it is very volatile and the only means to keep track of what Unity is doing.
     
    PublicEnumE likes this.