Search Unity

Feature Request: Register Systems to world via Inspector

Discussion in 'Entity Component System' started by Soaryn, Feb 18, 2019.

  1. Soaryn

    Soaryn

    Joined:
    Apr 17, 2015
    Posts:
    328
    Right now, when hitting play, the default world initialization goes about its day filling in the world with all systems not marked for disabled auto creation. This is neat and useful for lots of systems running; however, my hope, is that potentially in the future we could edit which systems would run in the editor. Prototyping/testing new systems or have different scenes have different systems connected to them.
     
    recursive likes this.
  2. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    186
    For all who trying to create multiple worlds with immutable system, you can achieve this with Reflection.
    But still I would prefer World System editor like timeline for debuging than drag'n'drop System via inspector.

    Code (CSharp):
    1.    
    2. [AttributeUsage(AttributeTargets.Class, Inherited = false)]
    3. public class AutoCreateInExtraWorld : Attribute
    4. {
    5. }
    6.  
    7. public class WorldInit : MonoBehaviour
    8. {
    9.     public string WorldName = "ExtraWorld";
    10.     private void Awake()
    11.     {
    12.         var world = new World(WorldName);
    13.         world.GetOrCreateManager<EntityManager>();
    14.         CreateAllManagers<AutoCreateInExtraWorld>(world);
    15.     }
    16.     /// <summary>
    17.     /// Use Reflection to find all class with [T] header and create all manager from that class in the world.
    18.     /// </summary>
    19.     /// <param name="world">The world the manager will be created</param>
    20.     /// <param name="sampleName"> profiler name</param>
    21.     /// <typeparam name="T"></typeparam>
    22.     public static void CreateAllManagers<T>(World world, string sampleName = "ReflectionHeader") where T : Attribute
    23.     {
    24.         Profiler.BeginSample(sampleName + typeof(T).Name);
    25.         var typesWithMyAttribute = from a in AppDomain.CurrentDomain.GetAssemblies()
    26.                                    from t in a.GetTypes()
    27.                                    let attributes = t.GetCustomAttributes(typeof(T), true)
    28.                                    where attributes != null && attributes.Length > 0
    29.                                    select new {Type = t, Attributes = attributes.Cast<T>()};
    30.         var array = typesWithMyAttribute.ToArray();
    31.         foreach (var t in array) { world.GetOrCreateManager(t.Type); }
    32.         Profiler.EndSample();
    33.     }
    34. }
    35. // Sample class
    36. [DisableAutoCreation, AutoCreateInExtraWorld]
    37. public class SomeSystem : ComponentSystem
    38. {
    39.     protected override void OnUpdate()
    40.     {
    41.     }
    42. }
    43.  
     
    sngdan likes this.
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Have you considered just unit testing your systems instead?

    Not only can you test them in isolation as per the request of the thread, you now have the benefit of having tests for the future to detect bugs. Also when you need to retest systems again in the future you don't have to go about setting up another test environment potentially screwing with the workflow of other team members.

    This won't solve the, different scenes different systems problem. This may differ for other teams, but personally I feel the project is easier to maintain if it doesn't matter if every system runs. You can use UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP to stop the default bootstrap and setup your systems yourself on a per scene basis. It's also probably only 30minutes work to throw it in a UI.
     
    Last edited: Feb 18, 2019
    Deleted User likes this.