How to do MORE with the Observer Pattern

Поділитися
Вставка
  • Опубліковано 31 лип 2024
  • Unity C# Architecture: Learn how to observe variables using a streamlined generic Observer class aided by the UnityEventTools class. This video covers play and edit modes, focusing on the serialization and persistence of UnityEvents programmatically in the Editor.
    🔔 Subscribe for more Unity Tutorials / @git-amend
    #unity3d #gamedev #indiedev
    ▬ Contents of this video ▬▬▬▬▬▬▬▬▬▬
    0:00 C# Observer/Delegate Basics
    3:00 Generic Observer
    6:25 Unity Event Tools
    Generic Observer Source Code:
    gist.github.com/adammyhre/353...
    Resources
    Unity Event Tools Documentation
    docs.unity3d.com/2023.2/Docum...
    Creating Observable Variables with Delegates in Unity Using C#
    copyprogramming.com/howto/uni...
    Unity C# Creating Observable Variables with Delegates
    stackoverflow.com/questions/7...
    Value Observer (FREE tool from Infinity Code)
    assetstore.unity.com/packages...
    C# Implicit and Explicit Operators: A Comprehensive Guide
    / c-implicit-and-explici...
    Assets Shown In This Video (Affiliate Links)
    Dmitriy Dryzhak Models and Animations: assetstore.unity.com/publishe...
    Odin: assetstore.unity.com/publishe...
    Dungeon Mason Tiny Hero Duo: (FREE): assetstore.unity.com/packages...
    Chromisu: Handpainted Forest MEGA Pack assetstore.unity.com/packages...
    SineVFX: Better Crystals assetstore.unity.com/packages...
    VFX Trees: assetstore.unity.com/packages...
    Kronnect Volumetric Fog & Mist 2: assetstore.unity.com/packages...
    Kronnect Cloud Shadows: assetstore.unity.com/packages...
    Kronnect Beautify: assetstore.unity.com/packages...
    Kyeoms Hyper Casual FX 2: assetstore.unity.com/packages...
    MalberS Animations: Forest Golems: assetstore.unity.com/packages...
    REXARD SpellBook Icons Megapack: assetstore.unity.com/packages...
    ARCEY Vampire Skill Icons: assetstore.unity.com/packages...
    Follow me!
    linktr.ee/gitamend
  • Ігри

КОМЕНТАРІ • 56

  • @git-amend
    @git-amend  8 місяців тому +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 8 місяців тому +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  8 місяців тому

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

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

    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  8 місяців тому

      Awesome, love to hear comments like yours!

    • @drottningu
      @drottningu 4 місяці тому

      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 8 місяців тому

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

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

      Thanks, will do!

  • @GeniusPancake
    @GeniusPancake 8 місяців тому +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  8 місяців тому +1

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

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

      ​@@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.

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

    Wow, this is really powerful - Thanks!

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

      Awesome, thanks!

  • @SirSone7
    @SirSone7 8 місяців тому +5

    You're a legend, thanks!

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

      Thank you! You're welcome!

  • @yashaswiification
    @yashaswiification 8 місяців тому +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  8 місяців тому +1

      Glad you enjoyed it! More to come!

  • @omeryilmaz1021
    @omeryilmaz1021 3 місяці тому

    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.

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

    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  8 місяців тому +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 8 місяців тому

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

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

    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  8 місяців тому

      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!

  • @shadyleegamer
    @shadyleegamer Місяць тому

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

    • @git-amend
      @git-amend  Місяць тому +1

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

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

    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

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

      Great suggestion!

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

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

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

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

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

    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  7 місяців тому

      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.

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

    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 8 місяців тому +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  8 місяців тому +1

      @@elliottk68va Cool, glad you figured it out!

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

    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  8 місяців тому

      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

  • @Jona-v5r
    @Jona-v5r 13 днів тому

    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  13 днів тому

      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 12 днів тому

      @@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

  • @kecia9988
    @kecia9988 3 місяці тому

    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  3 місяці тому +1

      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 3 місяці тому

      @@git-amend Thank you very much!

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

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

    • @git-amend
      @git-amend  8 місяців тому +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 8 місяців тому

      ​@@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.

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

    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  8 місяців тому +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!

  • @sirius-27
    @sirius-27 Місяць тому

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

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

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

    • @sirius-27
      @sirius-27 Місяць тому

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

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

    how do you decide whether you use observer or visitor

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

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

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

    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  8 місяців тому +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 8 місяців тому

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