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.
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).
@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
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.
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
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.
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.
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.
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!
With more practice, you will get it. (It sounds cliche, but itās true)
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.
ā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.