How do you understand the Observer Pattern?

Did this lecture make sense to you? What new knowledge did you take away?

I understand it as a very flexible and expandable way to let classes react to certain things without the need of tight dependencies due to the fact that I can broadcast any event and let anyone who is interested in this event subscribe to it. The beauty is that the broadcaster does not care about itā€™s subscribers, which makes the system maintainable and expandable and easy to refactor. I use it a lot for bossfights for example. When a boss hits a certain life threshold, he broadcasts an event and I can try out different things and see what I want to do with it. Like having enemy spawners that start to spawn adds on event call or make rocks falling from the top of the level.

2 Likes

I havenā€™t used the observer pattern much before, but I definitely see how useful it can be!
I had to pause the video a few times to think about how it was all working together, but I think you did a great job of explaining it all (and doing the FakePlayableDirector to help us see whatā€™s going on behind the scenes).

1 Like

@sampattuzzi The link seems wrong to me (it point me to the course homepage), anyway I want to suggest a better implementation (in terms of design) thatā€™s the publisher/subscriber pattern (event bus in other disguise)

to see differences between observer and pub/sub there is a nice article here that explain it without going into implementation details: https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c

Giving my background (C# dev since inception and Java knowledge) this pattern (pub/sub) is really useful in my daily job (unluckily itā€™s not gamedev heh) to decouple completly subsribers from publisher, so a suscriber just have to publish in a ā€œchannelā€ that something has appened and then any other component aware of that specific event (without knowing whoā€™s the publisher) can consume that event.

I donā€™t know unity implications in terms of performance, but about design this is a big relief, any component that have to consume any event has just to have a reference to the broker class (e.g. EventBus)

In my implementation any publishable event is a type itself (a class) and the consumer has just to know that it exists to be able to subscribe and receive it whenever anyone publish that event type.
No need to declare events anywhere, just declare a type and then you are able to publish it anywhere.

I leave here just an example of a simple eventbus implementation I did for a project Iā€™m collaborating with to see how it can be used/implemented

My Unity knowledge isnā€™t high, maybe unity has its own message bus (I think I remember about unity messaging in the past, but it was just a string, not typed and not as powerful as pub/sub) anyway would be nice to know how an event bus works in Unity

2 Likes

I was looking at that article indeed as I prepared this lecture. We are definitely using the observer pattern but sometimes the eventbus is a good way to go. But I think it can be overkill for situations where the observer pattern would do.

Loved the content of this lecture. Very informative and easy to follow. Creating FakePlayableDirector first was very helpful.

1 Like

Hey Sam, I found this lecture to be a whole lot more challenging than any of the previous ones. Iā€™m reading up on delegates, observer pattern, etc. using the links you provided.

Iā€™m wondering about this line though:
GetComponent().onFinish += EnableControl

What datatype is ā€œEnableControlā€? If this were a string it would make more sense to me. I canā€™t grasp how the computer is going to use this unless itā€™s being used as a string to call it directly, kind of like how you would use SetFloat(ā€œsomethingā€, 1f). That accesses the property ā€œsomethingā€ on whatever youā€™re trying to change.

Is a function itself a datatype? Is it a different datatype if it has () after it? Iā€™m not sure if Iā€™m even asking the right questions, but this just seems really odd to me. Any help would be appreciated.

Function signatures can match the expectation for event/delegate data types, I donā€™t know if they are having a type themselves, or even if thatā€™s really important.

You can reference the event/delegate definition (when you are creating them) to see what they expect.

In the case of a delegate you have something like:

public delegate void SomeFunc();

From this you can create instances of SomeFunc that are assigned a method with a matching signature. C# will refer to the type of that instance as the delegateā€™s name, so create/assign a SomeFunc instance, and itā€™s type will be SomeFunc.

In this lecture (took a while to hunt it down btw ! that link in the original post does not take you there anymore), they are using events with an Action delegate. Like this:

public static event Action<float> SomeEvent;

Which you later see being assigned with the += accumulation syntax. These too have to meet a specific signature format, but they are declared and typed differently, partly because of generics and partly because Actions are provided by the language instead of yourself. So in this case, it has the type: System.Action`1[System.Single], which if I recall equates to a ā€œSystem.Action with 1 parameter, that is a float/singleā€.

Try it: https://dotnetfiddle.net/bjFwX7

1 Like

EnableControl in this case is a references to the method EnableControl that is elsewhere in the scriptā€¦

public void EnableControl()
{
    ///enable the controls
}

So the onFinish+= EnableControl is simply passing the address of the method EnableControl to the onFinish event. It can get confusing, since we donā€™t use the () or strange pointer types like ^ or * (C++). In C#, all that is require/allowed is the name of the method. The signature of the method must match the signature of the event, but the compiler handles that.

1 Like

Iā€™m starting to understand this pattern better after going through part 2 and using it for updating the UI. Iā€™m thinking I would be able to change the buff/debuff system I have in place to use the observer pattern. Currently, each time a stat like Attack or MaxHealth is needed, the code runs recalculates from BaseStats and runs through all of the modifiers.

With the observer pattern, when an effect is started/ended, it would notify the scripts that care about stats and theyā€™d be able to update themself. Given that scripts like HealthBar are already checking BaseStats every frame, Iā€™d hope this doesnā€™t introduce any stutter as long as thereā€™s only a few scripts subscribed.

I think this would be very similar to how Equipment and Inventory invoke their action when theyā€™ve been updated.

Edit: I think I got it sorted. One of the Discord users had posted a video of using a Sciptable Object for Unity Events, so I went with that method so that I wouldnā€™t need to tangle the namespaces from Health to Combat and Inventory. Reading through the article posted earlier in this thread, it seems like a pub-sub pattern instead of a simple Observer? Either way, now whenever a Stat Modifier script makes a change, it raises an event that has a receiver to call the relevant recalculations:

Going back through also let me streamline how the combat system drops buffs, so it was worthwhile all around.

1 Like

Real life analogies?

Pub/sub:

Tuning into a radio station to listen to it. The radio station doesnā€™t know (except via popularity polls after the effect) how many listeners there are - maybe there are none and the DJ is screaming into the void - but it broadcasts anyway, in case someone should want to listen and pay attention to it.

Observer:

Subscribing for email notifications. The subscriber often (hopefully) gets to choose what types of topics they will receive updates on, and the company/service sending out the notifications is now obligated to only contact those email subscribers it knows about and upon topics on which they are interested. **

.

** A little idealistically perhaps given we know how spammers operate with no regard to subscription opt-in choices. Iā€™m referring to a legit business you would subscribe to such as your bank, a game dev education company, etc., not spammers.

1 Like

In Unity 2019, thereā€™s a better way to stop player movement when timeline played.


I think this is a better way to pause and play controller when timelines run. But itā€™s only featured in unity 2019.

Good morning,

Honestly I feel I need to see it used more or read more about it to fully understand but itā€™s almost like a broadcast.
I failed the challenge since I could not figure out why the lines where red (did not understand I had to pass the pd parameters in the methods).
Canā€™t wait to understand better!

1 Like

With more practice, you will get it. (It sounds cliche, but itā€™s true)

1 Like

Iā€™ve had no issue following each segment so far, did most of the challenges without too much trouble, answered every quiz accurately etc.

This is the first lesson where I feel completely lost. The entirety of the content went way over my head, from start to finish.

I donā€™t understand the pattern. Why make a ā€œfakeā€ class? This is unlike anything weā€™ve seen in this course so far, I ā€œfollowed alongā€ as suggested and the entire time I was just lost and didnā€™t know if I was supposed to actually do anything. Whatā€™s with the ā€œnonsenseā€ float?

I took a break from the course to come back to it later and Iā€™m honestly just as confused. I donā€™t understand any of this. I donā€™t even understand what this video was aiming to teach, but it certainly failed to teach me anything.

1 Like

ā€œ66. The Observer Pattern In C#ā€ through me for a loop for quite a while, because I entirely overlooked the difference between ā€œOnFinishā€ and ā€œonFinishā€ for quite some time. GAH!

I couldnā€™t for the life of me, understand why we would have it call itself, until I slowed the video down, listened step by step, and understood that we were calling the event and not the method. lol The entire point of the lesson was the event, and I missed it. Maybe Iā€™m a little too tired tonight.

To me, sounds like the same logical as the event listener in JS.

The event listener is an application of the Observer pattern, so it sounds like youā€™ve got it.

Hi folks.

Iā€™m trying to improve my understanding of the Observer pattern and its usage, compared to what Iā€™m calling (perhaps confusingly) as Direct Dependency - i.e., calling functions from other classes. Iā€™d really appreciate your corrections/thoughts.

My understanding is that the key purpose of subscribing to events is to minimise and reverse dependencies.
Minimising: The observer reacts to an event taking place, and so is dependent on the event. But the observer does not depend on the class that triggers the event.
Reversing: the observe has no dependency on whatever is reacting to its events. So the observer can make stuff happen with actually having to call on any functions from other classes.

Which is kinda cool.

So an obvious question is how come we donā€™t use the Observer pattern more widely?

Observing/Reacting to events is one-way only, and there are many cases why weā€™d want classes to be able to ā€˜talkā€™ to one another, within or across namespaces. For example, while it might be easy to imagine handling a Playerā€™s Health being an Observer for some Hit() event, it would be very awkward to make movement and combat work purely as a series of events.

Does this sound right?

Youā€™re pretty close to the right ideaā€¦

Just remember that weā€™re looking to avoid cross dependency altogetherā€¦ so itā€™s less about talking to one another, and more about a class that says ā€œHey, whoeverā€™s listening!ā€ā€¦ While the listener needs to know about the class itā€™s listening to, the reverse is not true.

1 Like

Privacy & Terms