Feedback 1: Unity ECS really needs Reactive System to make easier to code to the next level. Basically the main purpose of Reactive System is to avoid having a lot of tag components as it will only execute the system when specified component(s) has been add/replace. More info about why it is important can read at here: https://medium.com/@icex33/my-wish-list-for-unity3d-ecs-1f3985bbe308. Inspired from: https://forum.unity.com/threads/entity-debugger-feedback.522893/#post-3449823. I propose the way to write Reactive System that I think is nice. There are 2 possible implementations: 1) Still using the same ComponentSystem Code (CSharp): struct Group { public int Length; [Trigger]public ComponentDataArray<Sprite> Sprite; [Filter]public ComponentDataArray<Sprite> Sprite; [Filter]public SubtractiveComponent<View> View; } [Inject] private Group _group; From above sample code it's very intuitive that [Trigger]public ComponentDataArray<Sprite> Sprite will make sure when there is Sprite Component add/replace, it will enter this system. [Filter]public ComponentDataArray<Sprite> Sprite and [Filter]public SubtractiveComponent<View> View will make further check whether the entity has Sprite Component and does not have View Component. If everything pass, it will call OnUpdate() function once. 2) Introduce new system called ReativeComponentSystem Code (CSharp): struct Group { public int Length; [Trigger]public ComponentDataArray<Sprite> Sprite; public ComponentDataArray<Sprite> Sprite; public SubtractiveComponent<View> View; } [Inject] private Group _group; Another implementation with less attribute as it will auto consider non-attribute variable as Filter.
Feedback 2: I think not only putting ReactiveSystem into top priority to-do list but also converting current Unity components to ECS. I envision in the future, Unity components will become inherit from IComponentData instead of Component. It also means that every Unity Components will work just like before that able to attach at Game Object and the Game Object can become a prefab. So, Unity Components will become reserved IComponentData that is deeply integrated into ECS. It is able to tweak the value and configuration at inspector just like before and writing user defined ComponentSystem/JobComponentSystem to implement the logic for that specific Unity component. User defined ComponentSystem/JobComponentSystem will run first before running internal Unity Engine ComponentSystem/JobComponentSystem to execute logic for Unity Components. But currently one of the problem will be whether to put all data into one component or split it out for better memory layout. If it's able to put all data into one component but the Burst Compiler will do the magic to compile then it will no longer a problem anymore. Besides that, IComponentData created by Unity developer can directly attach to Game Object without needing to implement wrapper anymore and the variables inside the IComponentData is automatically become configurable at inspector and Game Object Entity will no longer needed to attach to Game Object anymore.
We are going to make IComponentData more native by attaching it directly to a game object. But lets be 100% clear. Moving all our existing components into pure mode entities that can be accessed from any job etc. is not a thing that will happen. Mostly because its impossible without breaking every single project out there. Instead the idea is to slowly build a similar set of features on top of the Entity Component System / IComponentData etc in C# in packages. The part about "every single unity feature" is what will take a long time. However Hybrid mode works today, so you can always get started and make the majority of your game code jobified. And many games don't need all builtin features, so it depends on the specific needs if a project can move into pure entity mode.
I see. I think as long as similar set of features internally are reworked to make it highly optimized and efficient should be fine. I'm not expecting all existing components will be converted to pure mode entities and jobifiable but is that possible to make it able to put Unity Component as variable so I can access it as a reference? If it's not possible, can you introduce alternative solution like for example IUnityComponent? The reason I need this is because sometimes I have a Game Object that has child objects attach with Unity Component like UI Image. I need the ability to get the reference and store it into IComponentData so I can always able to access it and do something at it easily. Currently, it needs MonoBehaviour to do that. If IComponentData is not possible, I hope I can have alternative solution like IUnityComponent to replace MonoBehaviour so we still can make it get tightly packed memory layout and able to get and configure Unity Component easily in ECS way. If going IUnityComponent road, it should able to do the operation like IComponentData to AddComponent, SetComponent, RemoveComponent with EntityManager. The best is it's still using the same IComponentData EntityManager APIs. Furthermore, slow GameObject.Find() API to get a reference of Game Object can be replaced by [Inject] struct Data at ComponentSystem. Tile Image refer to Image component from NumberedCell child object and Tile Text refer to Text component from TileNumber child object Does it means that in future we will have access to low level stuffs like MeshInstanceRenderer for developers who wish to make it jobified and more precise control to code?
Feedback 3: I think it needs a better way to store NativeArray<> and NativeList<> into IComponentData or introduce another new component as there is usecase for me that I need to store NativeArray<> / NativeList<> into ComponentData and transform and get the data throughout various systems. Create and get a lot of ComponentData not able to solve my problem. Currently I can do it with SharedComponentData but I have no way to jobify it. Before that I try create a NativeList<> variable at JobComponentSystem to jobify it and feed back the result back to SharedComponentData with EntityManager.SetSharedComponentData(_entity, new ColumnList() {List = list}); but sadly it does not work as passing a reference to SharedComponentData. So, in the end not data found at SharedComponentData.
Seems like there is something like this available but I want something that can support list too. Code (CSharp): entityManager.AddComponent(entity, ComponentType.FixedArray(typeof(PolygonId), 10) );
There are a few technical problems in adding NativeArray and in general, any native data structures support to IComponentData. The main one is that they are not blittable, due to the DisposeSentinel that we use to validate safety. Being safety one of our main goals, we cannot remove this. Another one is related to efficient serialization. Our current prototype implementations are extremely efficient (close to a memcpy plus some simple patching), and we would love to retain this. Adding any reference type in the IComponentData will make it impossible. And there is more, related to work we are doing for automatically tracking changes on entities, and stuff like that. We have a few ideas regarding how to deal with all of this, and we are considering all the alternatives before proceeding with the implementation. We might come up with something completely different that still satisfies all the use cases. We would love to relax the restrictions we have today. But we need to be careful to make sure that we can do this while still following all the principles that are driving ECS development.
I see. Maybe you can introduce another new component called IReferenceComponent other than IComponentData just for handling reference type. So, now I can throw away MonoBehaviour and use IReferenceComponent to reference current Unity Components. And also I can freely put NativeList<> and NativeArray<> into IReferenceComponent. I think it's the solution that can retain the current performance and safety of IComponentData and still I can use IReferenceComponent to do store current Unity Components, NativeList<> and NativeArray<> etc that cannot support in IComponentData.
This is definitely one of the options, and we are considering it. My main goal though would be to find a solution that doesn't allow the introduction of a new type, so at the moment we are focusing our efforts around that approach and see what we come up with.
Feedback 4: I think most wanted Unity Components that needs to support ECS seamlessly are Rigidbody/Rigidbody2D, Collider(BoxCollder/BoxCollider2D, SphereCollider/SphereCollider2d etc.), Animator, Audio and UI. For Rigidbody/Rigidbody2D and Collider, I think it will no longer use OnCollisionEnter/OnTriggerEnter that kind of MonoBehaviour thing in ECS anymore. Same with other Unity Components also, they need new way to access and configure Unity Components. I'm not really sure how similar set of features on top of the Entity Component System / IComponentData going to implement. Perhaps you can share a little about how it's work. What I imagine is Unity Component will become a special component that it is not inherit IComponentData and it's still work just like IComponentData that able to get it with [Inject] attribute and configure the Unity Component inside ComponentSystem but it will not able to jobify inside JobComponentSystem. There will be corresponding highly optimized and jobified internal Unity Component systems that will take care the details for you.
@Joachim_Ante, is that possible to make it like one is still the regular Unity component that built on top of the Entity Component System / IComponentData etc for backward compatibility and another one is lightweight IComponentData Unity component that is able to jobify that is still using the same set of Entity Component System / IComponentData etc?
We are working on it. It is not a long way to go, but we are experimenting with different approaches to find one that we are confident with. It will come sooner than later.