How to Use Signals in Godot 4 - Editor vs. Code

Поділитися
Вставка
  • Опубліковано 13 гру 2023
  • 🗨 GDQuest Discord Community : / discord
    ▶︎ GODOT 4 COURSES : school.gdquest.com/godot-4-ea...
    Early Access Starting Jan 30
    🎓 FREE APP "Learn GDScript From Zero" : www.gdquest.com
    🎮 Free Interactive Tour - The Godot Editor - www.gdquest.com/tutorial/godo...
    ------------------------------------------
    🖋 SYNOPSIS
    This video introduces signals, a fundamental feature of Godot that you use to run a piece of code when an event occurs in the game. For example, when pressing a button, this button node emits a signal named "pressed". If you connect to that signal, upon receiving it, you can run code that opens a menu, opens a link in the browser, purchases an item in the game, and so on. The video shows the two different ways to connect signals in the engine: using code, and using the editor interface.
    🕶 New in Godot 4 : First Class Signals covered in more detail in this video: • First Class Functions ...
    -------------------------------------------
    CC-BY 4.0 LICENSE
    Terms: creativecommons.org/licenses/...
    Attribute To: "CC-By 4.0 - GDQuest and contributors - www.gdquest.com/"

КОМЕНТАРІ • 115

  • @ahnmichael1484
    @ahnmichael1484 5 місяців тому +58

    I can't believe people are complaining about your paid content/courses or ads, in the face of all the awesome free content you've provided *and* the quality of all your content. Please keep creating and to anyone reading, please keep supporting! ✨

    • @dropyourself
      @dropyourself 3 місяці тому +4

      I don't have a problem with it but paid courses are almost always not worth the cost as you can get most info elsewhere for free.

    • @TheGreenYoutuber
      @TheGreenYoutuber 2 місяці тому

      @@dropyourself I bought GDquest courses They’re pretty high-quality ngl

  • @Evitrea
    @Evitrea 5 місяців тому +56

    One trick when connecting through code:
    If you have multiple entity, say 30 buttons connecting to single function, you can use bind() to detect which entity sent the signal.
    For example,
    for button: BaseButton in buttons:
    ->| button.pressed.connect(is_button_pressed.bind(button))
    Then have an argument in is_button_pressed, it'll be able to tell who sent the function.

    • @dorianvedel1910
      @dorianvedel1910 5 місяців тому +3

      Best comment, thank you for sharing

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

      While this is possible, this should usually be avoided. Part of the point of the signal system is to not know the caller, just to know you've been called !

    • @Evitrea
      @Evitrea 5 місяців тому +3

      @@DevilBlackDeath Why? I mean I did the same binding trick for my RPG project to know what entity was finished, I'd like to know the downside of the approach

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

      @@Evitrea My bad I had a brain fart. Signal emitters are meant to not know their callEE (as opposed to receivers not knowing their callers). Your approach is perfectly valid and is proof I should not comment on technical stuff right out of the bed ! So please do ignore my first post !
      Actually your approach is exactly you handle sending informations to signal receivers when needed.

    • @htspencer9084
      @htspencer9084 5 місяців тому +12

      ​​@@DevilBlackDeathDon't be too hard on yourself man, many paradigms can be tricky to fully grok at the best of times and there's so many of them!
      Good on you for being humble and accepting the correction tho, you're gonna go far in whatever you pursue with a mentality like that my friend 😊.

  • @ahettinger525
    @ahettinger525 5 місяців тому +26

    It's worth noting, rather then a open and close animation, you can make an open animation and tell godot to just run it backward. That's what I'm doing in with a stasis pod in my project.

    • @DevilBlackDeath
      @DevilBlackDeath 5 місяців тому +9

      Yeah and you don't run the risk of the player moving out of the area mid-animation and having the animation "teleport" to the fully open door to close up because now you can just run it backward from its current point.

    • @captainnelson9833
      @captainnelson9833 10 днів тому

      The only gripe about this is that I add sound effects in my animations, so simply playing it backwards wouldn't do. But this is a very good idea for prototyping!

  • @DarthLateralus
    @DarthLateralus 5 місяців тому +3

    These latest tutorials are so sharp! Love the little animations. GDQuest raising the bar again!

  • @LmAnubis
    @LmAnubis 5 місяців тому +9

    You Missed what I think is the absolute most crucial thing about signals. Generally, if you set a variable in another node to something, that node will not perform any processing until its "turn" in _process, signals immediately call the function even if it's in a different node. Understanding the placement of signals is very important, and can be used to change stuff immediately, rather than waiting till the next full run of all _process() calls

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

      Could you explain more? I've never heard of this

    • @DevilBlackDeath
      @DevilBlackDeath 5 місяців тому +2

      To be fair, in a game scenario that relies on visual and physics frames I'm not sure how important it is. Plus you can always call a function in that other node rather than set a variable, and that function can execute logic as well. If you have an intricate connection between 2 nodes that require them knowing each other, then you're better off calling a function yourself than using a signal actually.

    • @htspencer9084
      @htspencer9084 5 місяців тому +2

      ​@@UhGoombaI think what he is trying to say is remotely changing a variable versus a signal triggering a method means that the latter option gaurentees that the logic will be run as and when the signal is recieved, whereas doing the former approach will require you to wait for that logic to be run independant of that signal event.

    • @htspencer9084
      @htspencer9084 5 місяців тому +1

      You don't always want to change things immediately too though. It depends on whether you want logic to execute immediately vs changing the environment for the next time the "step" in your execution occurs.
      For instance, let's say I have a strategy game that has one in-game day pass every twenty seconds. Let's say your income affects your current gold amount at the start of each new day.
      There are some events that may want to change your specific gold amount "right now" and some other things that may change your current income amount.
      So it really depends on the context as to which approach you take.

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

      @@htspencer9084 Indeed but as I said, if it's a children or a sibling you might as well hold a reference to that other node and call a function inside, and that function can execute logic just as well. This is not a good reason for using signals.
      Plus in a game scenario where you only really care about handling (dependant on physics frame) and what's on screen (dependant on visual frames) it doesn't matter all that much to have logic execution wait a few ms before the next frame. But to be honest many people start using Godot for non-game applications. And it's not even really the mattrr, depending on your framework it may be easier to have logic execute immediately rather than just change a variable (there may be a race problem, even without multithreading and you may want to react to each individual change) but on the other end you may want to only react to the latest change and let multiple other nodes do various operations on the value before executing any logic based on its value when the game frame happens.
      As you pointed out with your own example, it's quite complex and highly depends on what you need. But never use signals just because you want your logic to execute immediately. If you're supposed to know the other node (because it's a sibling or a sibling of your parent or any other reason), just have a method in your node and call it to execute that logic. If you're not supposed to know about the other node (it's a children, or you're broadcasting a signal) then the signal is the way to do it. But then again if you're not supposed to know about the other node you're impacting, there's either no way or no reason you can change a value in that other node anyway !
      Edit : note some of my comment was written before your second one so yeah some of it is fairly irrelevant ;)

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

    nice.. following the concept of Qt signal/slot. i like this.

  • @sosasees
    @sosasees 3 місяці тому +1

    i already know how to connect signals in the editor
    but thank you for showing how to connect them in GDScript:
    this is very convenient to connect the Node's own signals
    and the only way to connect signals of Autoloads

  • @OldM8
    @OldM8 4 місяці тому +1

    Love the vids, and I just payed for your early access. Can’t wait. Is there an easy way to connect to signals if they’re not in the current scene tree ?

    • @Gdquest
      @Gdquest  4 місяці тому +1

      I'm glad you like the videos!
      I'd be able to answer better with some more info about the signal you're connecting to and why it's not in the current scene tree. The short answer is: if you need to do this, consider changing your project structure so you don't have to. If there's no way around your current structure, then you need to connect to the signal in code.

  • @htspencer9084
    @htspencer9084 5 місяців тому +1

    Does Godot have an efficient, intuitive way to register signalling nodes to a list and then have others listen for signals from that list?
    My understanding of how this pattern should work is that it's preferable for signals to just be fired in the void, and the source node should not have to care who the listeners are.

  • @pixelby_
    @pixelby_ 5 місяців тому +2

    how do you make the wiggle effect on the sprites at the beginning of the video? is it a shader, or is it just an editing effect?

    • @ArcangelZero7
      @ArcangelZero7 5 місяців тому +1

      I notice it looks like bones in the sprite, animated with keyframes. :)

  • @PunCala
    @PunCala 5 місяців тому +4

    Could you please make an intermediate tutorial about about finite state machines for a player character with 2D-movement (e.g. top down). There aren't many good tutorials about it, the ones that exist are too basic and don't really help when you try to build one.

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

      When you say FSM for a top down character what do you mean specifically?
      Are you talking about the character controller, animation blending or something else?
      A finite state machine is just a graph with nodes and transitions, it's a tool/format rather than a specific *thing* exactly.

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

      @@htspencer9084 Well, let's take a typical top-down 2D player character with 8-directional movement. Usually you have idle, a melee attack, dash, run, walk, block/parry, combo. 8 directions present a lot of trouble, for example when I tried doing it, the character seems to prefer north and west directions instead of north-west diagonal position (in blendspace, animationtree). Or, when the game starts, the character is facing south but if you press attack, they attack north. There are a lot of things like that that beginners face and at least I found getting 8-directional movement animations to work difficult. These issues never come up in tutorials, and I don't think I've seen a tutorial on 8-directional movement yet.

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

      @@PunCala ah, I see what you mean.
      If you don't want to play around with an FSB, I genuinely feel like nested ifs (and elses) are more than fine for capturing movement input.
      For example: Have an if for left, then nest two If-elses for up and down and then an else for neutral. Put your diagonals in the if-else blocks and your orthorganol left in the else block.
      Then repeat for right.
      To avoid having to repeat this (per frame) you can do something like setting an enum in the branched ifs. Then for the rest of the frame just check the enum.
      Something like that is down and "dirty" but gets the job done and doesn't require messing around with FSBs I'd they're not your strong suit.

  • @mayedalshamsi
    @mayedalshamsi 24 дні тому

    Do the courses teach in an interactive style similar to the free intro course? I completed the free one, and absolutely loved it. :)

    • @Gdquest
      @Gdquest  23 дні тому

      I'm glad to read you liked it!
      There are a few lessons that are completely interactive like the editor Tour you're referring to. We use such tours whenever it makes sense to teach that way. Most lessons are web based. They integrate text with other media and interactive elements, such as: quizzes, glossary of terms, study guides, challenges and practices that are automatically tested inside the Godot editor. The whole learning platform is basically built around teaching gamedev with Godot. Below each lesson, there's a Q&A section that we support every day.
      If you like, you can explore it, and you have 2 months to ask for a full refund. We don't ask questions.
      As a heads up: There's a lot of material and it's shaping up to be an extensive program: easy to follow and truly learn from but not short.

  • @Blender.Quebec
    @Blender.Quebec 5 місяців тому +4

    what is the difference between a property and a method ? Sorry, basic question, but I still don't get it after a few hours into Godot :D !

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

      The property is a variable attached to an object like nodes. The position, rotation, and scale of a sprite are three of their properties.
      A method is a function attached to an object. It gives it behavior. Almost all of the functions built into Godot, that are attached to nodes, are methods. For example, show() and hide(), or move_and_slide()

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

    Is there any advantage to using one method over the other? With the interface approach you get that green icon that can be clicked

    • @user-tm2vn5yj9r
      @user-tm2vn5yj9r Місяць тому

      The correct way from a objective oriented and observer pattern perspective is to use code. Because with code you have an observer subscribe to an event and therefore your signal emitting object is de-coupled (it should not know about anything other than it's job responsibility). Obviously this prevents spaghetti and follows good object oriented principles.
      If you set the signal in the inspector, you are reversing that principle and now you are coupling objects with other game logic that they should not know about; in large projects this spaghettification will lead to hard to debug code and problems re-using objects.

  • @chloestudio9215
    @chloestudio9215 5 місяців тому +1

    Why do they always use a button instead of using it with a different example?

  • @gustavoaguilargarcia9665
    @gustavoaguilargarcia9665 8 днів тому

    ¡Nice video! Thanks for it.
    I've been trying to do something similar to the first part of the video, but using an area2d instead of a button, and I've found some issues:
    - When writing the code, nt all signals are offered by the autocomplete tool, just those inherited from Node and Object, but not those which are specific of Area2D.
    - Anyway, I can write the code for an Area2D signal and ¡it compiles! -> but ¡¡it doesn't work!!
    ¿What is the reason for that? ¿What am I doing wrong?
    Thanks in advance for your help.

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

    is this possible to do through scenes? At the moment i'm sending signals through an autoload scene, then connecting it to a node in another scene. IS there a better way?

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

      If the 2 scenes are siblings, then you need a node higher up in the hierarchy and an autoload is a good option.

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

    I'm assuming the body_entered and body_exited signals care about masking layers? Like if I want players to be able to open a door, but not enemies.

    • @Chitor
      @Chitor 2 місяці тому

      Yes, it cares about masking layers. In this Video for example, you could make it so the door does open for the Player but not for enemies. Either with Code or with masking layers

  • @bladekiller2766
    @bladekiller2766 3 місяці тому +1

    Why there is no autocomplete after pressed?

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

    Did your voice change? Just slightly? Either way, it's nice, and it was nice before too. But something sounds different.

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

      sometimes a new microphone really makes a difference

    • @Gdquest
      @Gdquest  5 місяців тому +2

      It could be the audio processing, it could be the fatigue as well as we crunched quite a bit this year, and it can also be in part thanks to the people who report words I mispronounce - each time people do, I practice these a bit.

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

      Well, it's great, man. Wonderful channel/company you have here. @@Gdquest

  • @adiandrianto888
    @adiandrianto888 5 місяців тому +2

    WHat the difference between using %node and $node ?

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

      $NodePath
      Shorthand for get_node("NodePath")
      %UniqueNode
      Shorthand for get_node("%UniqueNode")
      ua-cam.com/video/LKjPvtFopII/v-deo.html

    • @RoundSixStudios
      @RoundSixStudios 5 місяців тому +11

      $node is a reference to the node in the tree via a path. If the node gets moved or the tree rearranged, the path will no longer work and your code will break.
      %node is a direct reference to the node itself. You can rearrange the tree, give the node a new parent etc. and everything will still work. It's often used with UI elements since you often find yourself moving the nodes all around the tree.

    • @SastredelDesastre
      @SastredelDesastre 5 місяців тому +1

      @@RoundSixStudios But then wouldn't it be better to always use %node for everything? I imagine the answer is no because $node probably offers some other advantage that I'm unaware of, but I didn't want to remain in doubt :')

    • @SmeddyTooBestChannel
      @SmeddyTooBestChannel 5 місяців тому +1

      i read $node as "snode" and i think i've found a new shorthand to use

    • @koresaliva
      @koresaliva 5 місяців тому +3

      @@SastredelDesastre Don't quote me on this I might be wrong but I've been using %node for pretty much everything in my scene trees. You can have the same names as long as they aren't together in the same scene. For example if you have 2 chair scenes in your main game scene, both chair scenes can have a single node with the name %Body.
      UA-cam doesn't allow links but there's a debate about it and so far really no problems using it except for dependency, which is in case you use a lot of %Node and decide to change the name of the %node which isn't a big deal since you can literally just use the replace all function.
      You can google any_drawbacks_to_using_lots_of_scene_unique_names since youtube doesn't allow links

  • @binyot5505
    @binyot5505 5 місяців тому +1

    If I click and drag the button it has a $ instead (I'm working with 3D).

    • @Gdquest
      @Gdquest  5 місяців тому +4

      The percent sign only appears when you right click on a node and you set it as unique name. This is a feature that allows you to reference a node by name regardless of its position in the scene dock.

    • @Shawn-cq7qy
      @Shawn-cq7qy 5 місяців тому

      I help on it to😢

  • @FrancoisMathey
    @FrancoisMathey 5 місяців тому +3

    I think it's bad practice to connect a signal with a lambda function. The "connect" or "disconnect" functions cannot check if the signal is already processed. In a larger project this can quickly cause problems with multiple calls.

    • @Gdquest
      @Gdquest  5 місяців тому +4

      Most of the time connections are just one way and one offs, you connect a signal to a single use function and you never touch it. That's when I would recommend using anonymous functions.
      In the few cases where you need to disconnect signals manually, then of course you need to either store the function in a property or to define a method in your class. You couldn't use an inline anonymous function in that case in the first place.

    • @skvader4187
      @skvader4187 5 місяців тому +2

      That's what I was thinking aswell

    • @FrancoisMathey
      @FrancoisMathey 5 місяців тому +2

      @@Gdquest Particularly with “THE EVENTS BUS SINGLETON” ^^

    • @Gdquest
      @Gdquest  5 місяців тому +3

      You mean, THE EVENTS BUS SINGLETON 😎😎😎

  • @nevertoolate5325
    @nevertoolate5325 5 місяців тому +6

    Nope. I still dont get it. When is a signal not a signal? Its seems its not only for user input? Why 'send' a signal when all the components of the program are right there? Isnt it more of a 'switch'? Why isn't this stuff just handled with if statements?

    • @harveyhans
      @harveyhans 5 місяців тому +10

      just think of it as an action that's triggered when the node is interacted in any way

    • @harveyhans
      @harveyhans 5 місяців тому +13

      on simpler javascript terms: it's like events

    • @bruno-leonardo
      @bruno-leonardo 5 місяців тому +7

      Timers for example, they can emit signals without the user input.

    • @americoperez810
      @americoperez810 5 місяців тому +11

      Signals are used to communicate with other objects in your game in a way that doesn't couple objects together.

    • @americoperez810
      @americoperez810 5 місяців тому +46

      A signal stops being a signal if you manually check for it every frame using an if statement. The reason we don't use if statements is because it would be unmanageable and very unperformant. Imagine having to create if statements for every object in your game that could be interacted with, having to check every frame if something actually interacted with it. Instead we use signals so that we can be notified of when things happen.
      It's mos definitely not just for user input. It's for anything that needs to communicate with something else.
      The reason we send a signal is because it keeps things decoupled. This is important when games become complicated, as they usually do. This makes it so that objects don't have to know anything about each other to communicate. One object says "for anybody that cares, this just happened to me". Then all other objects that care can say "hey we heard you and what happened to you. Let us do our thing in response". Here is a good example. Say I have a box. If the player touches the box, then a door opens. In that case, you could get a reference to your door in the box's code and call the open function on the door object. Simple. But let's say that instead, if the player touches the box, then I want a door to open, I want to clear all enemies in the area, I want to spawn a boss, and I want to show the bosses health bar and create a save point in my game. Having to get references to all of those things inside the box's code would be very messy and if anything ever breaks, you are now debugging code for all of those different things in an area of your code that was created for the box. See how ugly and unmanageable that gets. And that's not even that complicated.
      So, instead, we use signals. The box says "hey I just got touched by the player". Then, anything that cares, like the door, the enemies, the UI, etc can all say "we heard you loud and clear. Let's do our thing". The box never has to know anything about anything else except itself.

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

    Second haha

  • @unicomplex
    @unicomplex 5 місяців тому +1

    from the river, to the sea! ^_^

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

    Third haha

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

    Fourth haha

  • @amosf.2780
    @amosf.2780 5 місяців тому +1

    Fifth haha !?

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

    Fifth haha

  • @ikmalsaid
    @ikmalsaid 5 місяців тому +1

    First haha!

  • @delqyrus2619
    @delqyrus2619 5 місяців тому +2

    I stopped watching it at 0:50 beacause of ads, can somebody beat that score?

    • @Yusuf-ok5rk
      @Yusuf-ok5rk 5 місяців тому +12

      they are able to create free courses for you because they are monetizing some other courses. it is fair deal. what are you expecting? as long as there is no dishonest practice, it is fair.

    • @flatterghast
      @flatterghast 5 місяців тому +3

      It's for a course that the people behind this channel have been working on for a while, of course they're gonna mention it somewhere. It's not like they're trying to get you to play World of Tanks or something lmao

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

      @@Yusuf-ok5rk They are able to create the whole engine without monetizing, but a stupid course about signals has to be monetized? I don't get it.

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

      @@Yusuf-ok5rk They are able to use free and open source software to tell me how to use it. Wow, don't tell this the developers of the man pages. So much hard work instead of developing an Engine. Profiting on free, open source market doesn't make you a parasite anymore.

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

      Yeah, watching a video about ads is somehow stupid. Sady i watched a few seconds longer, so the 👑 goes to you.

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

    goodbyee GDQuest i have come back to unity my last message is to change the godot engine for good

    • @Gdquest
      @Gdquest  5 місяців тому +14

      @nito8066 The important part is that you keep making the games you want to make even if you change tools as many times as you need to. They're exactly that: Tools.

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

      Good luck my friend, see you when Godot becomes the next blender potentially

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

    75 bucks?? Wow nice way of milking Godot...

    • @COOP1606
      @COOP1606 5 місяців тому +2

      TBH, it is very low price for a good course

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

      No, it's a $75 DISCOUNT! The actual course is $259.95! Feels kinda too pricey to me.

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

      @@ResoluteGryphon that's even worse!!!

    • @Gdquest
      @Gdquest  5 місяців тому +4

      It's 74$ for one course right now to be precise. At $184 it's for 3 courses, not accounting for coupons or regional discounts.
      We contribute and have funded work on Godot (sponsored developers for over $40,000 total, not counting any benevolent contributions). While Godot is free to use, it isn't free to make, nor is education. If you get the software, UA-cam videos, etc. for free, or even free public education or healthcare, it's just that someone else paid for that. A lot more money than people realize (public education costs several thousands per year per kid for example - 8000 EUR in my home country, about $20,000 in the US).