Search Unity

Advice on moving forward: ECS or Event System? Trouble grasping generic event systems...

Discussion in 'General Discussion' started by johajo, Aug 14, 2018.

  1. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Hello everyone,

    First of all, I’m rather new to coding in C# so I apologize if my lingo is wrong here when I explain my situation or if I’m way of in my questioning.

    I realise the issue described is kind of vague as it is not a specific problem but more of an advice-situation.

    ---Some history---
    I’m programming on my free time and have no education in programming. In my first attempts to make a small game (Asteroids clone) I was fairly successful but one major issue was that I did not decouple my game objects so when I tried to expand on the design, I kind of broke it.

    So I see the importance of a decoupled design. I started out in making an Event System with delegates and events to register listeners which react to events. I did not use Unity-events but C#-events. I kind of got it to work for one “type(?)” (as in int, float, etc.). In order to get a more versatile event system I tried to make it generic but at this point I kind of feel lost and that I’m not grasping the concepts anymore.

    I know there are MANY tutorials on the generic event systems but I do not seem to get it.

    I then pursued the route of Unity ECS (Hybrid) and that seemed to work better in my attempt to decouple objects for me – I know the basics and manage to have systems act upon entities (with components on) and so on.

    But one thing I noticed when programing a collision system was that it felt like I had to write a lot of functionality which is already in place using the “old way” of coding. I realise that a big reason for this is that the ECS is new and more functionality is coming.
    ---

    At the moment, I’m kind of discouraged and wonder which way is the right to go?

    Should I pursue ECS-style of coding or an event system based route? Maybe it is logical to use event manager and ECS in same project when my project grows? Maybe I should learn both or maybe it is not relevant which way of coding I use? My gut is saying that it might be overkill with an event system on top of an ECS architecture...?

    Can anyone point me in the direction on some good examples on event systems or material to read to increase my understanding of how generic event systems work?

    Thank you for all your advice

    Jonathan
     
  2. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    OK this might help or it might confuse even more...

    ECS with the addition of its Reactive features, creating new components triggers the systems that act on them, can be viewed as an event system.

    The event is the creation of the component the event listener is the system that processes that 'component' or event.

    Events are uses of the Observer Pattern https://en.wikipedia.org/wiki/Observer_pattern
     
  3. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Thank you for your answer.

    What you are saying is clever, I did not think about that! I will play around with it.

    Still, do you think it is wise to use ECS in its current state considering the not yet implemented content?

    Thank you again!

    Jonathan
     
  4. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    ECS needs a lot more features to be comparable to Classic so hybrid is probably the best way to go.
     
  5. hard_code

    hard_code

    Joined:
    Aug 29, 2013
    Posts:
    238
    Welcome to game development where programmers constantly go in search for the one framework to rule them all. It has not been discovered yet, but many believe it's out there somewhere...
     
  6. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Thank you! In my search, I will learn!
     
  7. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Thank you for your help!
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Unity ECS isn't currently in a state where novice programmers should touch it. Novice programmers we also have challenges implementing an ECS on their own. So that rules out ECS as an option.

    I'm also not sure that an event system will solve your coupling problems. Just adding in another system without understanding why will likely make your coupling worse.

    Learn to write decoupled code without relying on event systems or ECS. Then you can switch when/if you need it.
     
    vexe, xVergilx and Deleted User like this.
  9. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Thank you for your answer, much appreciated!

    The thing I thought was neat with an eventsystem/event manager was that it felt like an general approach for communication between gameobjects in the game. For example enemy register listener for when a collision with it occurs and then invokes an event where it takes damage.

    In that way the enemy does not need to know about the projectile but only to listen after the collision.

    Now, I realise that you know all this already but I want to verify that I understand that part correctly?

    But I agree with you, I feel like I'm in over my head and that I'm lacking required knowledge to understand the general eventmanagers I find online.

    So with that said, can you point me in the direction to start learning decoupled coding in c# (preferably in unity)?

    My previous solution has been a lot of dragging prefab to inspector and using a lot of GameObject.FindObjectsWithTag or GameObject.GetComponent in order to acess fields and/or methods to communicate between objects. I found this to be kind of a mess...

    Thank you so much for your advice
    Jonathan
     
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Start with the basics. Calling GetComponent on an interface tends to make things pretty decoupled. For many games that's enough.
     
  11. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Alright, thank you!
    Sounds like my next step is to properly learn how to use interfaces! I only have a vague memory of reading about them and trying them out.

    Any more specifics which is good to get into except for interfaces for good decoupled code?

    Jonathan
     
  12. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,853
    For each subsystem mechanic i make a separate GameObject and possibly a child hierarchy to cover the bells and whistles and subsystems of the mechanic. The mechanic handled by that GO and its component script can be turned off without affecting the game logic..i.e..no console errors or null refs. I call these controllers. If there is complexity in these in that this one and that one should be turned on if the other one is and turn off that and another as well then i implement a manager that tells the controllers how to behave under given circumstances. If some data point is shared amongst controllers will store a reference to that variable in the controllers manager so it will always be available to the controllers. This may or may not be considered decoupling by system architects but is bloody well a totally serviceable setup in Unity.
     
  13. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    UnityEvents allow full decoupling, but only because they can be visualised in the inspector, so it doesn't need to know about anything, not even an interface. I only use them on GameObjects can can exist in the same prefab, so the connection can be maintained.

    For your collisions, functions like OnCollisionEnter are special event functions themselves. You can use it to make a modular collision detection script.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine.Events;
    5.  
    6. public class CollisionDetector : MonoBehaviour {
    7.  
    8.    public UnityEvent<Collision> _onCollisionEntered, _onCollisionExited;
    9.  
    10.    void OnCollisionEnter(Collision collision)
    11.    {
    12.         // Send event with collision data
    13.         _onCollisionEntered.Invoke(collision);
    14.    }
    15.  
    16.    void OnCollisionExit(Collision collision)
    17.    {
    18.         _onCollisionExited.Invoke(collision);
    19.    }
    20.  
    21. }
    Now just use the inspector to choose the function you want to run. For example, click-drag your Health component in, then choose TakeDamage function or whatever.
     
  14. ADNCG

    ADNCG

    Joined:
    Jun 9, 2014
    Posts:
    994
  15. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    Interesting! If I understand you correctly, wouldn't this generate a lot of gameobjects in the hierarchy? Also, do you just "DontDestroyOnLoad" in order to keep structure between scenes?

    Thank you for your answer
    Jonathan
     
  16. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23
    The reason I haven't really checked out Unity events is that I've read that they are slower and the benefit of using them over native c# delegate and events is not worth it. I will review this and check them out!

    Thank you for your answer!
    Jonathan
     
  17. johajo

    johajo

    Joined:
    Apr 1, 2014
    Posts:
    23