Search Unity

Event-based game architecture question

Discussion in 'Scripting' started by customphase, Nov 19, 2021.

  1. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    246
    Im implementing an event-driven architecture for my game, similar to whats shown in this video:


    But ive ran into a situation i cant find a elegant solution to - combining that approach with physics events (collisions/triggers) and raycasts, i.e. raycast-based bullets hitting enemies.

    The way ive done it for now is like this: bullets do raycasts and whenever they hit something they raise a ColliderHit event, sending the collider hit as a parameter. Then theres Entity class, which is on basically every "object" (not on every gameObject) in the scene. It stores the list of all of its child colliders and subscribes to ColliderHit. Then, when ColliderHit fires, all entities check if the collider passed in ColliderHit is in the list of their own colliders, and if it is, then that Entity raises EntityHit event (passing itself), which is the actual event that every other system works with.

    This works, but its highly inelegant and weird to work with imo. Firstly that ColliderHit event has only a single purpose (of basically finding which Entity the collider belongs to) and its not used for anything else, which tells me that maybe it shouldnt be an event to begin with, and should somehow be an innate part of an Entity. Secondly, this makes it so that i have to subscribe all the Entities to that event manually, since im using GameEventListener (as in the video) as a separate component, to conform to single responsibility principle. But even then, if i were to subscribe to the ColliderHit event automatically in the script, that creates confusion on its own, since now we have two group of events, ones that i have to subscribe manually, and ones that subscribe automatically.

    I could use GetComponent/GetComponentInParent, but its also quite bad. So is there a better approach? Or im just overthinking it and what ive done is fine?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    That's generally what I feel whenever events go beyond a certain point in my games. For instance:

    1. Using events to decouple user interface from game logic: GOOD

    2. Using events to decouple very disparate systems such as audio: GOOD

    3. Using events to decouple physics from the game logic, two things which are inherently extremely dependent and sensitive to call order: BAD.

    Efforts to push #3 above too far always seem to result in EXTREMELY irritating code to debug, requiring you almost certainly to write little extra temporary snippets of instrumentation code to debug what is going on.

    For instance, if you have a generic "collider hit to event" script and everything has it for one purpose or another, when you have a single specific collider bug, now you cannot put a breakpoint on only that one point because that code is used EVERYWHERE, making it hard to isolate failure far up the chain, such as the collision event not even firing in the first place.
     
    customphase likes this.