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/"
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! ✨
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.
@@dropyourself I bought GDquest courses They’re pretty high-quality ngl
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.
Best comment, thank you for sharing
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 !
@@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
@@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.
@@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 😊.
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.
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.
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!
These latest tutorials are so sharp! Love the little animations. GDQuest raising the bar again!
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
Could you explain more? I've never heard of this
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.
@@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.
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.
@@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 ;)
nice.. following the concept of Qt signal/slot. i like this.
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
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 ?
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.
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.
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?
I notice it looks like bones in the sprite, animated with keyframes. :)
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.
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.
@@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.
@@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.
Do the courses teach in an interactive style similar to the free intro course? I completed the free one, and absolutely loved it. :)
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.
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 !
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()
Is there any advantage to using one method over the other? With the interface approach you get that green icon that can be clicked
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.
Why do they always use a button instead of using it with a different example?
¡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.
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?
If the 2 scenes are siblings, then you need a node higher up in the hierarchy and an autoload is a good option.
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.
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
Why there is no autocomplete after pressed?
Did your voice change? Just slightly? Either way, it's nice, and it was nice before too. But something sounds different.
sometimes a new microphone really makes a difference
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.
Well, it's great, man. Wonderful channel/company you have here. @@Gdquest
WHat the difference between using %node and $node ?
$NodePath
Shorthand for get_node("NodePath")
%UniqueNode
Shorthand for get_node("%UniqueNode")
ua-cam.com/video/LKjPvtFopII/v-deo.html
$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.
@@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 :')
i read $node as "snode" and i think i've found a new shorthand to use
@@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
If I click and drag the button it has a $ instead (I'm working with 3D).
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.
I help on it to😢
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.
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.
That's what I was thinking aswell
@@Gdquest Particularly with “THE EVENTS BUS SINGLETON” ^^
You mean, THE EVENTS BUS SINGLETON 😎😎😎
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?
just think of it as an action that's triggered when the node is interacted in any way
on simpler javascript terms: it's like events
Timers for example, they can emit signals without the user input.
Signals are used to communicate with other objects in your game in a way that doesn't couple objects together.
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.
Second haha
from the river, to the sea! ^_^
Third haha
Fourth haha
Fifth haha !?
Fifth haha
First haha!
I stopped watching it at 0:50 beacause of ads, can somebody beat that score?
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.
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
@@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.
@@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.
Yeah, watching a video about ads is somehow stupid. Sady i watched a few seconds longer, so the 👑 goes to you.
goodbyee GDQuest i have come back to unity my last message is to change the godot engine for good
@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.
Good luck my friend, see you when Godot becomes the next blender potentially
75 bucks?? Wow nice way of milking Godot...
TBH, it is very low price for a good course
No, it's a $75 DISCOUNT! The actual course is $259.95! Feels kinda too pricey to me.
@@ResoluteGryphon that's even worse!!!
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).