Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to create a event system in ECS

Discussion in 'Entity Component System' started by zyc_dc, Jun 21, 2018.

  1. zyc_dc

    zyc_dc

    Joined:
    May 11, 2018
    Posts:
    42
    For games driven by events. How to create an appropriate system to generate/process events? Normally, I will create an EventSystem to provide interfaces for registering listeners and firing events. When an event is fired, callbacks listening to the event will be called immediately.

    It's fine in OO, but it might not good in ECS because invoking a callback when an event happens means that memory from anywhere could be loaded and cause cache misses.

    Are there some good approaches to implement an event system? Thanks in advance.
     
    sidespin likes this.
  2. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    335
    You may use entities as events and components as event data. Listeners become systems that filter for the event data.
     
  3. zyc_dc

    zyc_dc

    Joined:
    May 11, 2018
    Posts:
    42
    Thanks for the reply. It should be something like you said, but could you be more specific?
     
  4. coldasfrost979

    coldasfrost979

    Joined:
    Jun 9, 2018
    Posts:
    25
    Can you please go into specifics?
     
  5. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    In rough implementation. When event must fired, attach component data with event args to entity, then system will be inject this entity, and in system update loop do stuff and remove component data from entity after all.
     
  6. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Or instead of attaching to existing entity create a new empty entity with event component data (no data inside, or maybe some event arguments inside). The system looking for it will run and only once if you properly destroying that entity after all is done. The advantage is you can do this easily from inside the job via EntityCommandBuffer. (It might be difficult to reference existing entities from inside the job)
     
  7. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    It's two different event types, I think. If you need send some event with some abstract data, epidemy in city for example, is a good way, but many times you need to now who send event, or on who fired event in this case existing entities more usable, because you use them for transfer event data IMO. Anyway booth examples can be useful.
     
    Last edited: Jun 22, 2018
  8. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    That reminds me of a built in attribute [RequireComponentTag] for IJobProcessComponentData that Unity officially define the term "component tag". So yet another way maybe try to use tags for events but you cannot remove a tag inside the job as it does not give you an entity, so maybe create an another system that run at the end of frame to clean up all events if you only want it run once. (You do not get to access the data in those tags but you can specify more than generic parameter limit)

    Code (CSharp):
    1. [RequireSubtractiveComponent(typeof(EcsTestData3))]
    2. [RequireComponentTag(typeof(EcsTestData4))]
    3. struct ProcessTagged : IJobProcessComponentData<EcsTestData, EcsTestData2>
    4. {
    5. }
     
  9. Necromantic

    Necromantic

    Joined:
    Feb 11, 2013
    Posts:
    116
    The Reactive Systems that are coming should be helpful with this. They will allow systems to process "events" when components are added, removed and filter to only process changed components.
    That way you should be able to add an event component with data and have a system handle it right then and remove it again. Alternatively just have a component for the event permanently on the Entity and just add event data to it and process it when it changes.
    They are also working on array support for IComponentData so you can have multiple events per component.
     
    zyc_dc likes this.
  10. avvie

    avvie

    Joined:
    Jan 26, 2014
    Posts:
    74
    adding and removing component data a lot will be a hit in performance. I am pulling this out of my ass a little bit though.
    My reasoning is that if you want to keep memory tightly packed, then adding removing a little means that you are shifting a lot of stuff around.
    if your component data had an enabled disabled state as well. so when the system that run it can check for it, you would reduce allocation/deallocation and still have good control over it.
    I am absolutely not sure about anything i just said :D but i will probably go and test this out in the near future as it is interesting to me as well. Obviously though i am trying to approach theoretically what happens when events scale up

    EDIT: i just saw the berlin talk from joachim and reactive systems seem to be exactly what is being discussed. its very event oriented in philosophy
     
    Last edited: Jun 26, 2018
    zyc_dc and coldasfrost979 like this.
  11. sidespin

    sidespin

    Joined:
    Jun 22, 2018
    Posts:
    20
    What if you want to fire a chain of events in the same frame?
     
    cloudlinxx and benzsuankularb like this.
  12. Necromantic

    Necromantic

    Joined:
    Feb 11, 2013
    Posts:
    116
    Populate an Event component with multiple event data sets. We still need better support for Collections or arrays first though.

    It's one of the reasons why I think multiple Components of the same type on an Entity may make an ECS way more dynamic.
     
  13. sidespin

    sidespin

    Joined:
    Jun 22, 2018
    Posts:
    20
    I'm afraid that won't be sufficient. If an event callback triggers other events and you want the entire even chain happen in one frame, you would want to run the same system multiple times in the same frame until all EventData is consumed.