5 Handy Signal Uses You Might Not Know

แชร์
ฝัง
  • เผยแพร่เมื่อ 27 มิ.ย. 2024
  • Most people know how to use signals in their Godot projects but here are a few methods you might not be familiar with. Or maybe you are? Let me know in the comments how many you knew.
    • People Seem Split on T...
    • I Bet You Don't Know T...
    • This Godot 4 Scene Man...
    0:00 - Intro
    0:29 - Why Use Signals?
    0:53 - bind()
    1:52 - Lambdas
    3:33 - Event Bus
    5:15 - Method Track
    7:06 - Await
    8:10 - Outro
    #godot4 #godotengine #godottutorial #gamedevelopment #gamedevtutorial
  • เกม

ความคิดเห็น • 81

  • @dibaterman
    @dibaterman 20 วันที่ผ่านมา +5

    I believe your lamda's are anonymous lamda's you can do the same thing with a name and well it would be a lamda no?

    • @dibaterman
      @dibaterman 20 วันที่ผ่านมา +1

      @@baconandgames Also worth noting is you can't pass lamda's from within static methods, or rather you can but they lack object information or any reference to object they came from.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +3

      @dibaterman I never thought about that but it makes sense that you can’t. Great tip 👏

    • @skaruts
      @skaruts 20 วันที่ผ่านมา +3

      A lambda function is an anonymous function. If you give it a name, then it's no longer a lambda. It could be a closure, if it carries the surrounding state with it. Otherwise, it's just a regular function.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +1

      @skaruts oh good, then I didn’t mess that up 😅 I tend to second guess myself too quickly.

    • @dibaterman
      @dibaterman 20 วันที่ผ่านมา

      @@skaruts
      Okay got it, so any lamda is by also anonymous, naming them makes it a function even if the rest of syntax is similar.
      So:
      var foo = func bar(x): return 0
      Is a regular function, while without bar would be an anonymous function or a lamda or anonymous lamda.

  • @PreRenderedRealities
    @PreRenderedRealities 20 วันที่ผ่านมา +10

    Man, you are a great teacher. This video helped me synthesize some concepts that were sort of floating around in my head but not fitting together quite yet. Thanks for the education as always.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +3

      Nick, you flatter me. Thank you so much. 🙏

  • @WaytoOblivion
    @WaytoOblivion 16 วันที่ผ่านมา

    I learned more in 5 minutes about Godot than in 10 hours of tutorials.

  • @ghostradiogames
    @ghostradiogames 20 วันที่ผ่านมา +4

    it's good to see some of the lesser known things explained in tutorials. good on ya. In my game I have a SignalManager class, which is my implementation of EventBus pattern but for C#. For anyone making a C# Godot game, using a static ref of your signal class allows you to call signals from Interfaces or anything else that doesn't include Godot.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +3

      👏👏👏
      Oh how I miss interfaces… I might find my way back to C# one day just over those alone.

  • @OHTASISAN
    @OHTASISAN 20 วันที่ผ่านมา +2

    lots of great tips/reminders! the method track is such a handy feature

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +2

      That’s a sleeper feature for sure 😜

  • @ince55ant
    @ince55ant 20 วันที่ผ่านมา +2

    loving these wee vids. nice work

  • @3db-
    @3db- 20 วันที่ผ่านมา

    I never thought of the bind thing - that's neat.
    Something that trips me up is the Event/Signal Bus. Ultimately, knowing when to use one. I've heard counter-arguments to the pattern such as:
    "Personally, I would avoid using an event bus. It just circumvents the hierarchical tree structure that is purposefully built to control the flow of data. Parents have children, and can call their methods. Children are unaware of their parents, so they emit signals to communicate back up the tree. When you sidestep that, you end up with spaghetti code that is hard to maintain and reason about. Suddenly things “just happen” implicitly, and it becomes a nightmare to troubleshoot."

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +3

      Here's my personal opinion, which you may take or leave :) Most things in life are OK in moderation. So I would NEVER tell someone to use only the Event bus patterns nor would I tell then to NEVER use it at all. But whether it's "OK to use" generally comes down to a few things:
      1. Scope of the project
      2. Whether you're working with a team
      3. Whether you intend to reuse the code from this project
      4. Other constraints like time or budget
      5. What the purpose of a project is (which might just be to learn and grow as a developer so you can make more informed decisions in future projects)
      I could go on. But the thing is, there is no universal answer to this debate. The choices you would make when creating a tiny clicker game by yourself would probably not be the same choices you'd make if designing an MMO with a team of 50 people. And I'm not trying to be hyperbolic, but if you look to the extremes you'll find reasons to use or not use just about any approach. Paying someone by writing a check seems fine when you pay them once a month... but if you're writing checks by hand daily or more... you'll probably start wondering about digital auto-pay solutions. So to bring it back around... if you're putting every damn signal on an event bus, yes you're overdoing it. There's no reason to not have a parent listening for signals from its child. That's what they're made for and I do that all the time (as you saw in the video through the hero power ups example) But for a few, game-wide stuff I don't see any problem with it. Anyone who tells you otherwise is getting into a purist debate about what's "the right way" the same may some developers will die on the hill of "the MVC model is the only way to organize your project". It's not, there are many ways. The truth is, programming and game design are arts, not sciences. Pretty much every option should be at your disposal and only by considering YOUR specific use case and trying different patterns out for yourself will you find what's best for you and your project. And you can only gain that knowledge by trying out different combinations of techniques out there and deciding for yourself what's ok and what's not... which again, depending on the application, might be OK for some games and less OK for others.
      The best thing you can do is to focus on understanding the tradeoffs you have to accept when choosing any approach. Less important is finding the universal answer to whether or not something is OK, or correct, or best. If you understand what you gain or lose with any choice, you will make the right decision more often than not (and when you don't, you'll carry that knowledge forward into your next project).
      Focus on what you give up or gain when you make a choice rather than a universal right or wrong way to do something. This debate will never go away, bit's an important thing to talk about and ponder. The fact that you're curious about it is a good sign ❤️

    • @3db-
      @3db- 20 วันที่ผ่านมา

      @@baconandgames Great response, thank you! Curious what would be examples of times you'd use an Event/Signal bus.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      @3db- The example in the video is a decent one, globally a listening for a setting change that affects the whole game. I often have at least one Autoload to make it easy to access some static classes or things like a save file, so I don’t use this pattern a TON but for some game-wide stuff I find it helpful without much or any drawback.

  • @zuruikyoku3817
    @zuruikyoku3817 8 วันที่ผ่านมา

    In my game I have a "Team Select" and I have a lot of different teams. I had gone through and connected all the signals through the interface and it made the code very long. I used your button binding method using a reference to a button container and a loop and it cleaned up my code so much. Thank You!
    Just had a thought that the way I did it would make a quick and simple level selector that would only take a few lines of code using your scene manager!

    • @baconandgames
      @baconandgames  4 วันที่ผ่านมา

      I'm glad that helped you! Good point about the level selector too. I like that!

  • @TheMegamanan
    @TheMegamanan 17 วันที่ผ่านมา

    Great video, some excelent ideas, some is too advanced for me, but definitely will come back for future references

  • @johnst.pierre6485
    @johnst.pierre6485 18 วันที่ผ่านมา

    Quickest subscribe of my life! Great content. Your attitude inspires me to try new things :)

    • @baconandgames
      @baconandgames  18 วันที่ผ่านมา

      What a lovely thing to have pop up on my phone. Thank you so much, for all of that 🙏

  • @Weahl
    @Weahl 19 วันที่ผ่านมา

    Amazing explanation, thanks a lot!

  • @KevinIndreland
    @KevinIndreland 20 วันที่ผ่านมา

    always a pleasure to watch and learn your videos!

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +1

      Thank you so much, that’s very kind of you to say! I see a little one in your photo. Are they a budding gamer/developer? 😀

    • @KevinIndreland
      @KevinIndreland 20 วันที่ผ่านมา

      @@baconandgames She's a budding 21 yr old these days. She was around 4 in that pic. Time flies when we're having fun developing and raising kiddos. Hope all is well with you and your family and look forward to more content from you in the future sir!

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      @KevinIndreland holy cow. That photo is a teenager! Thank you, my friend. Doing well enough. I’m enjoying making the content. Thank you for watching and saying hello. Best to you and yours!

  • @starbarzs7160
    @starbarzs7160 20 วันที่ผ่านมา

    Holy cow that last tip of awaiting animation player is exactly what I was looking for weeks ago, I've even used the await ...timeout syntax before - thank you for connecting those dots

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      You’re welcome! ☺️

  • @MrAidaslit
    @MrAidaslit 20 วันที่ผ่านมา +1

    The method track and await tricks are really nice, when I discovered that I can track methods it made so many things easier, absolutely one of my favourite features when working in Godot. The lambda part was new to me, maybe because I was a bit scared to mess with them in the past, but for the example use case here I think it's gonna be worth a shot in my projects too.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +2

      That’s wonderful 🙏 It’s my hope people find at least one useful nugget in this little vids. If I can do that much for people, it’s all worth it. ❤️

  • @headmill
    @headmill 17 วันที่ผ่านมา

    Thank you, I love these tutorials. I'm often worried that someone is showing me a sloppy way to get a specific result instead of a clean way to apply a flexible concept. Never the case here! I'd be interested to see how you'd set up the effects manager you referenced; that's the kind of thing I always feel like I'm doing incorrectly.

    • @baconandgames
      @baconandgames  13 วันที่ผ่านมา

      That’s very kind of you. Thank you!

  • @speggeri90
    @speggeri90 20 วันที่ผ่านมา +1

    Another great tutorial! There are very few advanced godot tutorial makers out there, so your channel is a gold piece in amongst the dirt.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      I appreciate that 🥹 though there are some great godot tutorial makes on YT. Are there any specific topics you’re after? I might be able recommend a channel or two.

    • @speggeri90
      @speggeri90 20 วันที่ผ่านมา

      Well I’m making as a serious hobby a relatively classic point&click game with godot in my spare time after my day job and I’m still relatively uncertain how I’m going to implement the dialog system. All the best from Finland!

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      @speggeri90 you might want to check out Dialogic (there’s a second one in the works that’s in alpha so you probably don’t want to mess with that). I don’t think it’ll solve the UI portion of your dialog windows (though maybe) but if you have a lot of talking in your game it might save you a ton of time.

    • @speggeri90
      @speggeri90 20 วันที่ผ่านมา

      @@baconandgamesI’ll definately check it out. :)

    • @victorlapin2080
      @victorlapin2080 9 วันที่ผ่านมา

      There is also Dialogue Manager addon, but it's more focused on the script part. I'd have a hard time choosing between the two

  • @skaruts
    @skaruts 20 วันที่ผ่านมา +1

    One thing I would love to see more videos on is how to make the communication between popups and the relevant parts of the application. I've built a couple apps for my own personal usage in Godot, and I did come up with something, but it seems hacky. My popups don't change the data immediately either. They take in a dictionary with the settings through a custom function to "popup" the popup, and when you click ok they poop out the dictionary through a signal (or null if you cancelled, iirc). The code that calls the popup "awaits" for that signal and then checks the dictionary for changes.
    I wonder what other ways there are to do this kind of stuff though. It took me a while to wrap my head around how to work with popups.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      When you say pop up, are you talking about an “are you sure want to quit” kind of dialog with an ok/cancel set of buttons? That’s sort of thing?

    • @skaruts
      @skaruts 20 วันที่ผ่านมา

      @@baconandgames more like the one you had there with the game settings. That sort of thing.

    • @freenull
      @freenull 20 วันที่ผ่านมา

      Could you not simply pass the real dictionary object to the node/scene that implements the popup? Then the popup can change values directly, and you can use signals additionally when other nodes have to be notified to update. Alternatively, if you want a Cancel/Apply/OK-like system where you have to specifically click a button to save the modified settings, you could store both the real dictionary object and a copy of it (dict.duplicate()), then when Apply/OK is clicked you could go key-by-key and copy data from the duplicate dictionary to the real dictionary.
      You should also consider using resources instead of dictionaries. You can create a script that `extends Resource`, and that resource can have @export fields which you can both edit through the Godot editor and also save/serialize just like any other object in Godot.

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      @freenull I second the Resources implementation +

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      Oh gotcha. I think I cover how I made that in my SceneManager video (the first one with the red knife in the thumb, not the yellow one). It’s not exhaustive and it’s certainly not the ONLY way to do it… there are many, but that might be a start for you. It really depends on how/when/how often you need to access something like this that determines how “complicated” or maybe robust/extensible your implementation needs to be. The example in my SceneManager is probably the bare minimum.

  • @morganp7238
    @morganp7238 20 วันที่ผ่านมา +1

    great vid, do more

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +1

      Thank you very much! I will do more 😀

  • @ckorp666
    @ckorp666 19 วันที่ผ่านมา

    global signals are a lifechanger ngl, never occured to me to use an autoload like that

  • @calebbennetts3559
    @calebbennetts3559 19 วันที่ผ่านมา

    Handy, indeed! I found a use for await timer a day after watching this. (giving bullets a lifetime so they don't escape the world geometry and live in memory forever)

    • @baconandgames
      @baconandgames  19 วันที่ผ่านมา

      That could certainly work, though it might be safe to just check their position and free them if they go “out of bounds” You probably don’t want to halt code execution waiting for that signal.

  • @gennadiyshvetsov4115
    @gennadiyshvetsov4115 15 วันที่ผ่านมา

    Hello, thank you for the informative video. I have one question to ask, if you don't mind. How to distinguish cases when bubling up signals is ok and when event bus should be used? At which node such decision should be made? E.G. shot from a gun ideally should emit signal locally - to play player anims, effects,etc. - as well emit event bus signal - to alert montsers or enemies .

    • @baconandgames
      @baconandgames  4 วันที่ผ่านมา

      It's more of an art than a science, but it often comes down to how many things need to know about a certain action and where they are in the game (ie how hard it will be to drill you want into a signal to connect to it)
      So I tend to use event bus for big, game-level stuff like changing the music volume, pausing the game, or writing data. But for more local stuff, like a child node reporting to a parent node, tends to be managed without a bus. Does that help?

    • @gennadiyshvetsov4115
      @gennadiyshvetsov4115 4 วันที่ผ่านมา

      @@baconandgames hello and thank you. I'm gathering a list of "rule of thumb" for godot - switched from unity3d some time ago but still trying to get used to it. And static or global signals is one of those things. I use classes inherited from resource classes this way don't have to hardcode name autoload in code and it's just a matter of dropping instance of event-bus resource from project assets. The issue with both approaches - autoload, resource - is that both emitter and receiver need to know about difference between local and global signals. Anyway, thank you for your answer.

  • @H0lley
    @H0lley 20 วันที่ผ่านมา

    I'd be careful with using await in game entity logic, however a good application I think are things like scripted sequences where anything other than the sequence is halted

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      Yeah. You saw the face I made at the beginning of the segment 🤣 I use it sparingly and only in places where I know the wait will always be very brief and VERY unlikely to fail. But since it falls under “lesser known signal stuff” I wanted to mention it. Perhaps I should have made my disclaimer for that segment stronger 😜

    • @graydwarf22
      @graydwarf22 20 วันที่ผ่านมา

      My hot take on this is that I agree that await is generally something you want to avoid in most cases. However, awaiting signals, animations and etc is super important. I get into some of this in a couple of my videos and demo projects. await is a game changer.

    • @H0lley
      @H0lley 19 วันที่ผ่านมา

      @@graydwarf22 listening for signals is important, not necessarily using the await keyword. pretty much all cases where one may use `await my_signal` can be solved in a cleaner way with a signal connection. await causes coroutines to be kicked off (functions being kept alive across several ticks asynchronously) and if not being fully aware of that, this can easily become a source of unexpected behavior and bugs.
      still, fully agree that await occasionally comes in handy :)

  • @morganp7238
    @morganp7238 18 วันที่ผ่านมา

    Why not connect to the functions directly? Why use the handle_menu_press.bind() instead? It works without it.
    I fail to see the advantage of this intermediary function. Apologies if you explained why and I missed it.

    • @baconandgames
      @baconandgames  18 วันที่ผ่านมา

      Both are valid approaches. I like this method because connecting stuff through the interface hides logic in sub-menus, your signals will break if you rename your code, I don’t like having to create a new signal every time I add a button, and it’s easier to collapse one signal to hide code than having to collapse one for each button (plus when you collapse it into one like rather than the number of signals you have). This is not really the primary use case for bind, but it was staring me in the face when making the video so it’s the one I used. No worries. Fair question. As I say in the video, it’s hardly a game changer. Mostly about preference. Many people prefer lots of clicking and property setting in the inspector. I prefer to do as much through code as I can so I don’t have to hunt through menus to see my intent.

  • @adventuretuna
    @adventuretuna 20 วันที่ผ่านมา

    When you connect a signal, is there no need to disconnect it manually?

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +2

      It’s a best practice to disconnect signals when you know you no longer need them however I’m told the reference counting in godot does a pretty good job of figuring out what can be freed for you. I usually create a method that disconnects all my signals before I destroy an object. It’s also a good practice to check that a signal is not connected before connecting and that it is before attempting to disconnect, to avoid errors. You’re generally safe to skip this in onready as it’s JUST being created but I still tend to do it. I didn’t cover those in this video due to wanting to keep it short and different from other “this is the basics of signals” tutorials. Great question! 👏

  • @graydwarf22
    @graydwarf22 20 วันที่ผ่านมา

    Didn't know about bind() so that's cool. I might pass an enum in that situation. Enums.ButtonTypes.Start, handle_menu_press(buttonType : Enums.ButtonType), match buttonType:, ... Enums.ButtonType.Start

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา

      I had actually started with an enum but it was just extra code to show on screen. I couldn’t come up with a good enough reason not to just pass the button itself in this particular scenario

    • @iamsecrets
      @iamsecrets 19 วันที่ผ่านมา

      Something I do is bind a buttons text (I have dynamically loaded and named buttons in my ui) so I can see what the user pressed.

    • @baconandgames
      @baconandgames  19 วันที่ผ่านมา +1

      @iamsecrets oh nice, there you go! 👍

  • @murifox_
    @murifox_ 20 วันที่ผ่านมา +2

    I like my signals to be very verbose, so I always do things like:
    some_button.pressed.connect(on_some_button_pressed)
    func on_some_button_pressed:

    • @baconandgames
      @baconandgames  20 วันที่ผ่านมา +2

      Very readable. I dig that. 🫡