How to do MORE with the Observer Pattern

Поділитися
Вставка
  • Опубліковано 18 лис 2024

КОМЕНТАРІ • 58

  • @git-amend
    @git-amend  Рік тому +7

    Hi everyone! Today we're going to walk through creating a streamlined Observer class to demystify some concepts and discuss how to serialize and persist Unity Events using the UnityEventTools class. Links to more resources in the description, including a similar but much more powerful FREE asset version of what I'm discussing today from Infinity Code. Hope you find it useful!

  • @kingbling7571
    @kingbling7571 Рік тому +6

    bro i got to learn so much new stuff just by watching a few of your videos. Of course I wont remember all of the stuff but I believe once I start incorporating them little by little over and over in my code I will eventually get the hang of using these patterns and stuff.

    • @git-amend
      @git-amend  Рік тому

      Right on, that's the way to do it!

  • @geddy21twelve
    @geddy21twelve Рік тому

    This is fantastic! I'm someone who's been recreationally dabbling in game dev since the covid lock downs. I'm loving this content because it's helping me escape the limbo between rookie and intermediate.
    I never just watch your videos start to finish. I'll pause when you do use some syntax I'm unfamiliar with, or start using concepts I've never seen before and I'll take them over to GPT to have it explain them to me and give me some other examples of where those ideas might be applicable. I get SO MUCH out of that! Keep 'em coming so I can keep struggling along!
    Sending a big thank you to you, sir!

    • @git-amend
      @git-amend  Рік тому

      Awesome, love to hear comments like yours!

    • @drottningu
      @drottningu 8 місяців тому

      Same!! I love the depth of the content on this channel. You can watch a video from this channel ten times and still catch new information!

  • @TheAndyW19
    @TheAndyW19 Рік тому

    Another great showcase of essential design patterns in a Unity specific context. Keep it up.

  • @GeniusPancake
    @GeniusPancake Рік тому +1

    That is awesome, I use something similar (my own thing) where I have ObservableProperty and IObservableProperty so that I can bind values and on every change of the value it fires an event automatically. IObservableProperty is always public and ObservableProperty is private so everyone binds via IObservableProperty and not directly to the ObservableProperty.
    So, on start of the game I bind all of the values that are needed (to UI, controllers, animations, etc.) and when something changes it updates everything.
    For example, when I have:
    public IObservableProperty IsShooting => _isShooting ;
    private readonly ObservableProperty _isShooting = new();
    and inside the ShooterController I would bind that property on awake by getting the centralized state controller and binding the IsShooting property. So, when it changes, it fires an event and because ShooterController is listening it starts to fire. The only one who can change the state of "IsShooting" is the centralized StateController because it acts as a brain to everything else happening.
    This way, it doesn't matter if I have InventoryController, ConsumableController, DialogueController, etc... it all goes through StateController and listens to their properties. Learning how to do this made my life so much easier. If I remove "InventoryController" the game works just fine.

    • @git-amend
      @git-amend  Рік тому +1

      Sounds great! Isn't it so satisfying to be able to remove components and not break your whole game!

    • @GeniusPancake
      @GeniusPancake Рік тому

      ​@@git-amend Yes, it is. Took a year-two to get to this point but it is a major benefit to understand the patterns correctly. Your whole video is a huge deja-vu moment for me. But I really hope some people understand how powerful every pattern can be in specific situations.

  • @yashaswiification
    @yashaswiification Рік тому +2

    Another great video!! Many teach how to get started with basic tutorials. But advance videos like this really help us to build a complex projects and def it will come handy and reduce the work in long run. Once again thanks a lot

    • @git-amend
      @git-amend  Рік тому +1

      Glad you enjoyed it! More to come!

  • @omeryilmaz1021
    @omeryilmaz1021 7 місяців тому

    we should consider the scenario that we have many more events in a game, drag drop will create a chaos in long term, but tools that you ve used are amazing.

  • @SirSone7
    @SirSone7 Рік тому +5

    You're a legend, thanks!

    • @git-amend
      @git-amend  Рік тому +2

      Thank you! You're welcome!

  • @Cloud-Yo
    @Cloud-Yo 8 місяців тому

    Wow, this is really powerful - Thanks!

    • @git-amend
      @git-amend  8 місяців тому

      Awesome, thanks!

  • @aljinolambino2533
    @aljinolambino2533 Рік тому

    I just recently subscribed and binged your programming patterns. One of the best, if not the best, I've watched so far as always! One question though. Wouldn't it be technically that the UI is the one actually doing the "observing"? And your "generic observer" is the one being "observed"? If that's the case, wouldn't "Observable" be the more apt name for this generic class?

    • @git-amend
      @git-amend  Рік тому

      Haha, that is a great observation and something I struggled with before creating the video. Does Observer refer to the T being wrapped or the class that is wrapping T and notifying the listeners when T changes? Or is the Observer really the UI and any other listeners? In the end I decided to name it after the wrapper, though I was very tempted to call it Observable because that would also be a meaningful name. Glad you like the videos, lots more to come!

  • @mongreldesigns9195
    @mongreldesigns9195 Рік тому

    I am loving the content you are doing, learning so much with each new video you drop.
    The first thought I had when watching this was that I feel like it could be rolled into the Event Bus you covered previously, do you think this is viable or would it be better to keep these things separate?
    Thank you for all the work you put into these.

    • @git-amend
      @git-amend  Рік тому +1

      Thank you so much! My thoughts about combining the two would be to keep them separate, because the Event Bus lives outside the Unity ecosystem - it is pure C# - whereas the observer, as presented here, ties into Unity Events and couples game objects and their properties together - for example, the Observer needs to reference the Health Bar - in the Event Bus, the Hero and the Health Bar would not reference each other at all. This Observer is also limited to the current scene. However, that's not to say that you couldn't use the Observer to raise an Event on the EventBus when the Observer notices a change - that would be a more typical usecase that makes the most of both systems.

    • @mongreldesigns9195
      @mongreldesigns9195 Рік тому

      @@git-amend Thank you for the insight. As a self taught 'dabbler' this is the kind of info most tutorials are lacking.

  • @shadyleegamer
    @shadyleegamer 5 місяців тому

    Love these videos. Also, where do you find these thumbnails? The art is pretty cool

    • @git-amend
      @git-amend  5 місяців тому +1

      Glad you like them! Most of my thumbnails have been mad with Midjourney.

  • @BigDaddyGameDev
    @BigDaddyGameDev 10 місяців тому

    Amazing video! Do you have an ECS tutorial in the pipeline?

    • @git-amend
      @git-amend  10 місяців тому +1

      Not yet! But that does seem to be a very requested topic...

  • @kecia9988
    @kecia9988 7 місяців тому

    Wonderful video! By the way I have some questions: 1) When should I use the GenericObserver instead of Event Channels(ScriptableEvents) and viceversa? 2) for updating the UI which one is better (90% of the times) GenericObserver or Event Channels ? 3) Is using a lot of "static event Action MethodName;" a code smell (mainly because of the static keyword)?

    • @git-amend
      @git-amend  7 місяців тому +2

      Those are some thoughtful questions.
      1) I would choose Observable for direct and immediate reactions to data changes; choose Event Channels for decoupling and broad communication needs across different parts of the game.
      2) For UI updates, Observable is generally better as it allows for real-time, direct updates to UI elements based on specific data changes. You might want to watch the video about the Inventory system if you are using UI Toolkit, becasue it allows direct data binding.
      3) Excessive use of static event Action MethodName can be a code smell because it risks tight coupling and memory leaks; prefer instance events and use static events sparingly and thoughtfully.

    • @kecia9988
      @kecia9988 7 місяців тому

      @@git-amend Thank you very much!

  • @anthonygiannotti4228
    @anthonygiannotti4228 11 місяців тому

    Very cool. Using this to implement a ton of stuff in our game. Mind if I ask what theme / configuration you're using for Rider?

    • @git-amend
      @git-amend  11 місяців тому

      Thanks! No special configuration, but I think at the time I recorded this I was using the Early Access version, so it might look a bit different than the usual version of Rider.

  • @Jona-v5r
    @Jona-v5r 4 місяці тому

    That Observable class is great. I added some code to make it also invoke when we change the value in the inspector.
    We will add a T oldValue field to the class.
    The Set Method will be changed to the following:
    if (Equals(oldValue, value)) return;
    oldValue = this.value;
    this.value = value;
    Invoke();
    we will add a public OnValidate Method like this (we have to call this method in the Monobehaviour that has the Observable in OnValidate())
    if (!Application.isPlaying) return;
    Value = value;
    Not sure if this is ideal for what I want. Any thoughts?

    • @git-amend
      @git-amend  4 місяці тому

      Your approach is valid, but integrating it directly with MonoBehaviour classes could be streamlined. Consider creating a custom property drawer for Observable that automatically invokes changes when edited in the inspector.

    • @Jona-v5r
      @Jona-v5r 4 місяці тому

      @@git-amend Thanks a lot! :)
      I was hoping for an answer like this. Didn't rly like my approach that much. I'll have to look into it

  • @pankster4169
    @pankster4169 Рік тому

    Hi thank you for your game pattern videos they are incredible can you make a video about how to implement Single Responsibility Principle to unity projects It would be great

  • @elliottk68va
    @elliottk68va Рік тому

    Thanks for doing this video. It's just what I was looking for. I'm building it along with you as I go. I'm up to 5:50, and it all works fine. But for some reason, my "Health" value doesn't show in the inspector on the Hero object in its script component. As far as I can tell I have followed along with you exactly in both Observer and Hero scripts. Just wondering if there was something else that needed to be done? Once again, I appreciate your work on this.

    • @elliottk68va
      @elliottk68va Рік тому +1

      Never mind. I forgot to make the Observer class serializable. I was going to delete this out of embarrassment, but thought I would leave it incase someone else forgot has well. 😁

    • @git-amend
      @git-amend  Рік тому +1

      @@elliottk68va Cool, glad you figured it out!

  • @sirius-27
    @sirius-27 5 місяців тому

    Can you make a video about Observer Pattern for beginner ? thx love your video.

    • @git-amend
      @git-amend  5 місяців тому

      Maybe one day, or maybe will fit that into a video about another topic at the same time.

    • @sirius-27
      @sirius-27 5 місяців тому

      @@git-amend thankyou sorry for bothering bacuase i'm still confused

  • @omriovadia98
    @omriovadia98 Рік тому

    Question please,
    Is it possible to do the Observer Pattern which i assume is like Events Manager .. as a Scriptable Object scripts?
    Basically if I want to preserve the events and also decouple more if I have various scenes so I won't get reference exceptions and such..
    I want to know what's cleaner to do

    • @git-amend
      @git-amend  Рік тому

      Yes, it is possible and I have a video about using Scriptable Objects for messaging, including between scenes, which I refer to as an Event Channel.
      I'll see if I can link that here: ua-cam.com/video/h8ZAOWY_5LA/v-deo.html

  • @ugurkarabulut8598
    @ugurkarabulut8598 Рік тому

    how do you decide whether you use observer or visitor

    • @git-amend
      @git-amend  Рік тому

      That's a good question - and another commenter asked that as well; scroll down to my response from @ reversamente 's question from yesterday

  • @TheKr0ckeR
    @TheKr0ckeR 11 місяців тому

    I love unity events, until we spawn things in run-time, so how would you reference if Player is spawned, not existing in scene? Would you call Add Listener by custom in script?

    • @git-amend
      @git-amend  11 місяців тому +1

      Great question. Generally speaking you would setup some hooks that would start setting up dependencies at spawn time - for example, connecting the correct camera in a multiplayer game to the Player. Listeners can be handled the same way. There are less coupled approaches, which are actually the subject of a future video! Stay tuned!

  • @reversamente
    @reversamente Рік тому

    when i should use observer vs visitor pattern?
    there are situations that both seems to be viable for me

    • @git-amend
      @git-amend  Рік тому +1

      Both are often viable options for getting the same end result. At a high level, I'd use the observer pattern when I need my code to stay updated with changes in other parts of my game, like if I want to instantly update scores or health bars. Think of it more like watching for changes in a specific thing being observed and then reacting.
      I'd pick the visitor pattern when I want to perform a task on an object without altering the code of the object, like I want to apply different operations to various objects in my game that can be visited. Think of a visitor like a handyman coming into your home (object) with a specific toolbox ready to perform some task on your object.

    • @HappyHippo0609
      @HappyHippo0609 Рік тому

      ​@@git-amend @reversamente @ugurkarabulut8598
      I am also new to this topic, but could we just combine these two patterns.
      What do I mean by that:
      We have an Observer, which is the "interface" between Logic and Presentation. Therefore, we can apply changes on several stats by using the PowerUps (Visitor Pattern), and detect this changes (Observer Pattern) toUpdate the UI.

  • @xSalenaMS
    @xSalenaMS Рік тому

    Hey Adam, I would love to ask for your advice
    I'm still a junior unity developer with self made projects and tools (1 year since i started) trying to get into the industry (so far I mostly lose to seniors but I do pass the stages like technical interview and such.. )
    All this high level programming approach that you teach is very interesting and I very much feel like I want to master it
    I want to be a pro developer and knowing the patterns and write clean codes and good habits like you do.. it's very hard to master
    But since chatgpt exists , I use it for almost every task and I feel like without it I can't really code so it's kinda like I'm an Imposter in some way. I know how to read the code and I know what most of it does.. but writing by myself from start it's tough
    for example if I want to start a new project , so I must let chatgpt start it or else I feel lost..
    what is your suggestion to tackle this problem or maybe it's not that much of a problem?

    • @git-amend
      @git-amend  Рік тому +1

      Thanks for your question - hopefully, these thoughts will help you and maybe a few others as well.
      My first suggestion is to read this blog post, which I think is 100% accurate.
      www.thinkful.com/blog/why-learning-to-code-is-so-damn-hard/
      ChatGPT is a useful resource, but it's important to balance its use with developing your own problem-solving skills. To tackle a feeling of imposter syndrome, try incrementally reducing your reliance on ChatGPT. Start small: maybe tackle the initial planning or one part of a project on your own before consulting ChatGPT. Over time, increase the complexity of what you handle before turning to tools. Remember, using tools is okay, but building your confidence through hands-on experience is crucial. Everyone starts somewhere, and even seniors were juniors once.
      Another excellent thing to do at any level is to start reviewing other people's code that they have made public, such as open source projects or tools you have from the Asset store. Subscribe to Game Dev Digest, and once a week, spend an hour looking at an open source project that catches your interest from the list they publish (every Friday). The more you are interested in what the project is about, the easier it will be for you to absorb it. At any point where you get stuck, then turn to AI to help you gain some insights into that specific blocker, and then keep going. This is especially useful for beginner programmers who don't participate in daily code review at work.
      twitter.com/GameDevDigest
      If you are interested in reading, 3 books that I recommend to any junior dev on my team (these are not game dev books, just programming books).
      Clean Code
      Code Complete 2
      Pragmatic Programmer
      Keep learning and practicing, and you'll find your footing. Your persistence and willingness to learn are key assets. Keep going!

    • @xSalenaMS
      @xSalenaMS Рік тому

      @@git-amend
      thanks a lot for your advice, I'll start working on it accordingly
      and keep up your great work please

  • @SLthenus
    @SLthenus 5 днів тому

    if we can use unityaction, why some people use action instead?

    • @git-amend
      @git-amend  5 днів тому +1

      Most programmers will choose to use C# Action and delegate since they are easier to use and are much faster. The only benefit of using a UnityEvent / UnityAction is that they support serialization in the editor without custom code.