I'm currently in the process of architecting a small RPG-style dungeon crawl (in Unity), and am a little stuck on how to update various objects when things change, while not updating unrelated objects. For this question, I will be using my current project as an example, but the question itself can be applied to any situation where multiple different kinds of Observers each watch a single Subject.
The design I'm currently leaning towards for object interactions in my game implements the Observer Design Pattern, where I have a single Subject (let's call it GameEventManager
), and each interactive object is an Observer of this Subject (this includes things like the player, enemies, interactive items on the ground, etc.).
When an event occurs (let's say a User hits Spacebar to shoot an arrow at a selected enemy), the current plan I have for the action's lifetime can be broken into steps:
- The Input system (not an Observer, but contains a reference to the Subject), sends an
Event
to theGameEventManager
for broadcasting to the right place. I haven't designed theEvent
class yet, to keep the problem simpler and in case I need to redesign things. - The
GameEventManager
broadcasts theEvent
to thePlayer
with the relevant information. - The
Player
, realizing anEvent
came in saying to shoot an arrow, does some internal math (like subtracting from the total ammo it has, maybe performing some sort of animation visually), and emits a newEvent
to theGameEventManager
telling it that thePlayer
shot an arrow at "enemy2". - The
GameEventManager
broadcasts theEvent
to "enemy2". - "Enemy2" receives the
Event
, realizes that it got shot, and dies in some fashion.
So the question is, how does GameEventManager
know where to pass around all these different types of events (i.e. the movement event should only go to the player, and the arrow should only go to "enemy2"). Also, once the event gets to its designated target(s), how do these Observers know what to do with the event (i.e. how does the player know to shoot an arrow, and not take damage?).
I've done some research on Observer examples, but most are either obscenely complex and abstract, or are just simple "Subject emits event to ALL observers, and ALL observers interact with EVERY event they get", which is not what I want at all (an arrow shot at "enemy2" should not impact "enemy1" in any way).
Sorry if this is a little abstract, I like to have a plan before I start to actually build the code.
Also, as an aside, I am fully aware that in Unity I can have one GameObject directly interact with another, but the purpose of this entire project is to make everything as polymorphic and re-usable as possible, and most Unity tutorials simply don't touch on extensibility at all.