Godot 101 - Part 7: Using Signals

  Рет қаралды 23,825

KidsCanCode

KidsCanCode

Күн бұрын

Пікірлер: 72
@Goldenfightinglink
@Goldenfightinglink 5 жыл бұрын
I've been marinating myself with a bunch of Godot vids and non of them went into the how of the signals. After a week of nonstop tutorials, the 4:00 mark basically rewrote everything I learned. cheers
@josephsnyder5713
@josephsnyder5713 5 жыл бұрын
After 3 weeks of watching other peoples videos and still not getting it I figured why not if kids can learn it... I have begun to set up a character and money grab system/inventory for an rpg off of just 7 videos with you, and it works. You actually know how to teach, thank you very much.
@Kidscancode
@Kidscancode 5 жыл бұрын
Glad I could help!
@chrisc.4144
@chrisc.4144 4 жыл бұрын
So basically the gem is saying “why do I have to reach up two levels to call this function from main? I’ll emit the signal, and let main do whatever it wants with it”. Awesome!
@BrookeHedrick
@BrookeHedrick 5 жыл бұрын
I was having an issue in Godot 3.0.6 where I cannot choose Begin, End, etc. for my Anchor types on the control ( around 7:35 ). It looks like it maybe is acting like it is based on ratio, but I cannot change it. I ended up with the following to match the videos behavior. Anchor Left 0 Top 0 Right 1 Bottom 1 I was guessing that 0=Begin and 1=End and that seems to work. My margin values are all 0 just like in the video.
@Pspisripoff
@Pspisripoff 7 жыл бұрын
Awesome! This is huge game changer for me.. thank you for another awesome tut!!! :)
@Kidscancode
@Kidscancode 7 жыл бұрын
Great to hear, glad it's helping!
@cloudsquall88
@cloudsquall88 7 жыл бұрын
Thank you so much for your tutorials. They have set me up to work on something at last, and not only imagining about doing it! I have just one question about this episode: How is looking for the score label using "HUD/score_label" different than looking for the main node using "../.." ? Won't it have the same problem with code breaking if the structure changes?
@Kidscancode
@Kidscancode 7 жыл бұрын
It's not just about structure changes - some structure changes will always require code changes. The idea is that it's OK to go *down* the tree, but separate, instanced scenes like the HUD or the Player shouldn't know about the structure of the tree *above* them, in order for them to still work independently.
@cloudsquall88
@cloudsquall88 7 жыл бұрын
oh ok, understood! Thanks teach :D
@jaysanprogramming6818
@jaysanprogramming6818 5 жыл бұрын
This video alone should be used as the basis for the Godot documentation about signals. The documentation is so cryptic that it doesn't help the engine to become more popular. you are really a good teacher. Thank you for your work. [edit] I've been hasty with my judgement of the documentation. It has received major improvements over time and I didn't take the time to look at it again since my first look. So apologies here.
@Kidscancode
@Kidscancode 5 жыл бұрын
I'd love to hear more about what you find cryptic in the docs. I've found them to be quite good - even when I started in Godot 2.0 when they were a *lot* less extensive. I wrote the docs tutorial on signals, so it would be nice to know what you think is different there from here. There's going to be another round of docs revisions as 3.1 releases, so please post issues here: github.com/godotengine/godot-docs/issues
@jaysanprogramming6818
@jaysanprogramming6818 5 жыл бұрын
@@Kidscancode Hi ! Maybe I was unfair with the documentation. I first looked at it nearly two years ago (before 3.0 was released) and at the time couldn't make any sense of Godot. I kept coming back and forth always stuck in a loophole of misunderstanding. It seems since that time, the documentation has received major improvements. I just found a specific section about Signals in the Getting started Step by step part (I can't believe I missed this update!) of the documentation and I will look at it today. I should carefully read the documentation from the start to see if I missed information and understand better the engine. I'm glad you asked me to investigate this matter. Thank you. (your videos helped me greatly to get passed this mental block too)
@jrc03c
@jrc03c 7 жыл бұрын
These videos are so great! Keep up the good work!
@Kidscancode
@Kidscancode 7 жыл бұрын
Thanks!
@Nouredyn
@Nouredyn 2 жыл бұрын
What if the scene where you want something to happen is a different scene than the scene where you initialize gems? So let's say I want the player to become faster for every gem grabbed, how would I connect this?
@cloudsquall88
@cloudsquall88 6 жыл бұрын
I have a question about the 'self' keyword. Does it always refer to the script we are writing in? I'm confused as to whether the 'self' keyword refers to the main class, or the g instance of each gem. Of course for this to work it has to be the former, but in the line g.connect("gem_grabbed", self, "_on_gem_grabbed"), first thing that comes to mind is that 'self' refers to that specific gem.
@Kidscancode
@Kidscancode 6 жыл бұрын
As in other OOP languages (Python, for example), "self" refers to the instance running the code. The connect function takes as its arguments a signal name, an object to receive the signal, and the named objects function that will handle the signal. Since this code is running in the "main" object, "self" is referring to main's "_on_gem_grabbed" function.
@cloudsquall88
@cloudsquall88 6 жыл бұрын
ok I believe I can remember this by heart. But when you say "self refers to the instance running the code", isn't the 'g' instance running the code? That's what confuses me.
@Svampen87
@Svampen87 7 жыл бұрын
These are great tutorials. Thank you!
@LilAngelRebel
@LilAngelRebel 5 жыл бұрын
Thank you for this. It is a very elegant method, and it cleared up a few things for me. I do (as always) have a few questions: 1) How do I connect a signal so that the main node can signal the instanced gem node? (In other words -- what you did here, but in reverse. I've tried, but only come up with null errors. I assume it's because the instanced node doesn't know of the existence of the main node.) 2) Godot assigns an ID to the instanced nodes -- is there any way that the main node can keep track of them? (I'm assuming that it's something like the "get_child_count" that you used here -- "get_child_ID" -- or is it under "get_instance_ID", which I have no clue how to implement.) 3) I'm also curious about why you would use signals in this case (unless it was purely for example purposes). Signals have a bit more overhead, in my experience, and I wondered why you just wouldn't have kept track of the points by using ".get_child_count" in main. (This is more of a case of my curiosity, and were you to say, "''Cause I felt like it. Deal with it, dude!" I would take that as an acceptable answer. LOL.) Thank you, again, for all the information you provide, both here and on the Godot forums. Your tutorials and help are very much appreciated!
@Kidscancode
@Kidscancode 5 жыл бұрын
1) I wouldn't really do that. Since the gem is a child of the main scene, it can call methods on the gem directly. If you must, then you'd do it in the same place: where the gem is spawned: connect("some_signal", g, "method_on_gem") 2) It's generally a waste to try and use node names when using instances because the engine will assign them (names must be unique among siblings). We are "keeping track of them" in the gem container, so you can use "get_children()" to iterate through them. Another useful solution is to use groups, because then you can use either "get_nodes_in_group()" or "call_group()" 3) I'm not sure what you mean by "overhead". Signals are used internally throughout the engine by nearly every node object. As for keeping score, this way is maybe a little more flexible as you could also have gems spawning randomly over time rather than a fixed number at the start, but overall I did it this way to demonstrate best practices and methodology that will apply to the widest range of projects.
@LilAngelRebel
@LilAngelRebel 5 жыл бұрын
Thanks for the fast reply! My reasons for 1) (and a little of 2): I'm trying to use the main scene to trigger events in the gem node. For instance (pun intended): Say the timer gets to a certain point, or the player gets to a certain stage, then certain gems start to do different things. (Hence why the ID of a spawned gem would also be important here. We wouldn't want all the gems to start doing these actions all at once.) So... from what you've written here, I'm under the impression I'd add the new connect("some_signal", g, "method_on_gem") command under the original g.connect (or in the same loop), then add a script to the gem container node with get_children(), pass that signal to the main scene so that main scene can connect those functions to the gem node via method_on_gem(). As for 3): Yeah, I thought that you were using a signal method for demo purposes, and it is more flexible for expansion as well. As for overhead, at least on my system, signal passing is much slower than actions contained completely in a node. (Though in this case, the performance difference is negligible.) I found this out when I was creating an input node that updated a sprite node's position via signals (by mouse X and Y input), vs. just having the input self contained in the node. So, as always, thank you so much for your guidance!
@Unavailable8923
@Unavailable8923 7 жыл бұрын
Thanks for the video. When your free the object that emits a signal, or the object that listens for it, will Godot automatically disconnect the signal?
@Kidscancode
@Kidscancode 7 жыл бұрын
Yes, there's no connection any more if either node no longer exists.
@christianvarga3580
@christianvarga3580 5 жыл бұрын
So, if I would want to connect the gem_grabbed signal to the player how would I do that? Because I can't figure out how to connect this signal to ALL the children of the gem_container. How do I load a node from one scene to an other?
@AkaiKnight
@AkaiKnight 3 жыл бұрын
nice that the event system is so simple.
@ronenosity
@ronenosity 7 жыл бұрын
great tutorial!
@TheElhoim
@TheElhoim 7 жыл бұрын
Question: isn't or not more performant to check if all gems are grabbed inside "on_gem_grabbed", instead of checking every frame?
@Kidscancode
@Kidscancode 7 жыл бұрын
You could do that, but in this game the difference in performance is going to be imperceptible. I prefer the logical separation of "on_gem_grabbed" only handling what happens to the individual gem. As always, there are multiple ways to to approach it, and you can do whatever works best for your situation. As a general rule though, my advice is to not worry about things like this, especially at this point. When you make something that really starts pushing the limits, that's when you can address performance, starting with the big things first.
@TheElhoim
@TheElhoim 7 жыл бұрын
Ok! Thank you very much :) and by the way great series and amazing teaching skill!
@ZoidbergForPresident
@ZoidbergForPresident 6 жыл бұрын
Question: It seems that queue_free() is not instantaneous, so if I were to display the remaining gems by using the get_child on the container, when would I have to update the score label to not have a discrepancy? I think I either have to update it in the _process method, which isn't great, or that I would have to save a counter that I'll initialize at the gem spawn and manually decrement. Or is there a better idea?
@Kidscancode
@Kidscancode 6 жыл бұрын
The "delay" in queue_free() is typically until the end of the frame. Your updated label won't be redrawn until the next frame anyway, no matter how you code it. The best way is when the coin is removed, send a signal to the UI to update the label.
@ZoidbergForPresident
@ZoidbergForPresident 6 жыл бұрын
That's not a bad idea, using signals. Like a "on_redraw()" or something? It can all be done in main, right?
@Kidscancode
@Kidscancode 6 жыл бұрын
It can be done anywhere you like. The two main ways people tend to code GUIs is 1) create a function on the gui that you call whenever you need to trigger an update 2) emit a signal and connect the gui so that it updates in response The second is more robust. Game objects don't need to know anything about the gui's existence. They just emit signals when properties change. It's completely up to the gui to respond to the event.
@ZoidbergForPresident
@ZoidbergForPresident 6 жыл бұрын
What exactly is the "gui" in this case? The GUI node? And you put a script there with all the methods called for each signal?
@bob64
@bob64 7 жыл бұрын
So I have copied the code exactly but when I hit "play the edited scene" and do so on the main.tscn scene, I have an issue where the gems will spawn outside of the bounds of where my player sprite can move (the testing window appears to be larger on my screen than it is in the tutorial; I am on windows 10 and using Godot 2.1.3 so I assume that either there is just a bit of "padding" on the testing window that was not present in earlier iterations of Godot or there are differences in syntax between the version used in the tutorial and 2.1.3 causing this issue). I resolved this by adding an extra 40 pixel buffer zone to the boundary for gems (giving an 80 pixel no-spawn zone between the border and where gems are allowed to spawn). Are there more elegant ways to resolve this? I also decided to test out some of the other CollisionShape2D options. I am using the capsule shape, with which I covered the sprite's oval body. I also used a custom CollisionPolygon2D to create a pentagonal shape corresponding to the gems. I am unsure if using a CollisionShape2D other than a rectangle could be causing this issue. In short, either my sprite is not reaching areas of the screen that it should be able to reach or my gems are spawning too far out and I am not sure how to diagnose the problem.
@Kidscancode
@Kidscancode 7 жыл бұрын
There aren't any differences between this project on 2.1.2 or 2.1.3. Screen size doesn't matter because we're getting that in the code during runtime. I'm not aware of any "padding" in the window size, so I doubt that would be the case. The first thing I'd check is whether you may have scaled the gems differently than I have. Your different collision shapes shouldn't be making a difference.
@bob64
@bob64 7 жыл бұрын
After messing around a bit, the best I could do was to change the lines describing character movement to the following: pos.x = clamp(pos.x, extents.width -30, screensize.width - extents.width +30 ) pos.y = clamp(pos.y, extents.height-80, screensize.height - extents.height +80) Now the sprite is properly bounded by the edges of the screen. Upon further inspection, I think there is an issue when I download the sprites... my machine appears to think the sprite is larger than it actually is.
@Xero_Wolf
@Xero_Wolf 7 жыл бұрын
You'er not alone. Had the same issue Tried a similar solution where i just divided extents.width and height by 2.
@deralligheri1784
@deralligheri1784 7 жыл бұрын
Is there a reason, why you placed the collision query in the gem and not in the player? I considered the thought to put all collision objects with the same behaviour in one group and iterate the player with the query, if player enters these objects. I really dont know what to use in this situation, would be nice if you could tell me, what suits better and add a reason to it. As usual nice video, thank you for your effort! Just a little bit too short, now I have to wait 2-3 days for the next one. :)
@Kidscancode
@Kidscancode 7 жыл бұрын
No particular reason, really. You could just as easily do it so that the player detects the gem. If you are going to have a bunch of different object types, then that might make more sense. This is just a demo exercise, to show how to use the engine, not really to build a full game. Feel free to experiment - Godot is great for that!
@cccccroge
@cccccroge 6 жыл бұрын
What if the node that I want to set it listening to another is not yet exist in editor(will be instanced later during game), how can I still use signals to communicate?
@Kidscancode
@Kidscancode 6 жыл бұрын
You can connect the signal at the time the node is instanced. We do just that in the game when we instance the gems: g.connect("gem_grabbed", self, "_on_gem_grabbed")
@cccccroge
@cccccroge 6 жыл бұрын
got it, thanks for reply!
@mikevanleeuwen4912
@mikevanleeuwen4912 6 жыл бұрын
Quest completed, i can move on now!
@Duriel181
@Duriel181 7 жыл бұрын
_goes to rewrite two thousand lines of code_
@Kidscancode
@Kidscancode 7 жыл бұрын
I had to laugh...
@bloografix
@bloografix 7 жыл бұрын
Hello and thank you for the "easy approach" and very well structured lessons. I would like to know when will the next video be produced? I have followed your videos and would like to know more about the upcoming agenda. Thank you!
@Kidscancode
@Kidscancode 7 жыл бұрын
I'm producing the videos as quickly as I can - the planning and editing always takes longer than I want it to. I'm trying to go between this series and the "Space Rocks!" one. If all goes well, I'll be posting the next installment later this week. Thanks for watching!
@bloografix
@bloografix 7 жыл бұрын
One more question. You mentioned that Godot has a similar structure to that of Phyton. How similar is GDScript to Phyton in reality? Learning and getting good at GDScript doesn't have a "full gain" outside Godot, like for example C# or other languages that can be translated to industry standards. So the question is, how similar in reality is Phyton to GDScript? - Thank you!
@Kidscancode
@Kidscancode 7 жыл бұрын
It's *very* similar. The syntax is almost identical, it's really just a few keywords that are different - "func" instead of "def", for example. I think people get too hung up on language specifics. Figuring out the steps to solve your problem and thinking through the logic is the hard part of programming - syntax is a minor problem compared to that.
@bloografix
@bloografix 7 жыл бұрын
Alright then, thank you very much for your time. Please share a link to buy you a cup of coffee! It is always inspiring when good people produce good quality material. (PS) you might see me in your python series too.
@Kidscancode
@Kidscancode 7 жыл бұрын
Currently, I can take donations via Patreon - patreon.com/kidscancode, or Paypal at chris (at) kidscancode.org
@ovaldreamx4397
@ovaldreamx4397 5 жыл бұрын
just what i needed
@rbaleksandar
@rbaleksandar 6 жыл бұрын
Great to see a popular concept like the slot-signal communication (found in Qt, boost etc.) used here. However I find the syntax rather weird for the way I imagine Godot scripting looks. Especially the use of the "self" keyword reveals the underlying Python which I find to be a rather poor design. The devs of Godot should really consider finding a more Godot-ish syntax for this.
@Kidscancode
@Kidscancode 6 жыл бұрын
What is wrong with "self"? Many languages in addition to Python use "self" as the reference to the current object. JS uses "this". What about that is poor design? Godot is fundamentally an OOP framework, and so it's going to use OOP paradigms. Since GDScript's syntax is based on Python's, I'm not sure what a "more Godot-ish syntax" would be...
@shonyne6532
@shonyne6532 5 жыл бұрын
what do you mean in Godot " 101 "
@Kidscancode
@Kidscancode 5 жыл бұрын
Colleges traditionally number their courses, with increasing numbers representing higher level topics. As a result, "Something 101" has become slang for beginner level material.
@cassiosimpliciopantojadeso9175
@cassiosimpliciopantojadeso9175 6 жыл бұрын
muito legal mano valeu pela videos aulas
@manuel5101
@manuel5101 7 жыл бұрын
new vid, new question i guess... sry to ask you so much i'm kinda disappointed how something went i wrote and actually don't even know why it is like that my code is: class Mobs(pygame.sprite.Sprite): def Attack(self, target = random.choice(partylist)): dmg = self.ATK - target.DEF + (random.randint(1, target.maxHP // 10)) dmg = int(round(random.uniform(0.8, 1.2) * dmg)) if dmg
@Kidscancode
@Kidscancode 7 жыл бұрын
The self.Attack() method is running because you put the parentheses on it. If you just want to put the *function* in the list, not execute it, then leave them off: self.actions = [self.Attack] Also, you shouldn't really be posting Python/Pygame questions on a Godot video - it's going to confuse people...
@manuel5101
@manuel5101 7 жыл бұрын
yeah, sry.. i will try to write under a python vid next time i noticed that it dont happen without the parentheses but i thought i couldnt use the function with random.choice(Wolf.actions) if i let the parantheses away so i went here for asking
@Kidscancode
@Kidscancode 7 жыл бұрын
choosing it from the list like this: self.actions[0] would just get the function's name - to call it you need to add the parens: random.choice(Wolf.actions)()
@manuel5101
@manuel5101 7 жыл бұрын
Thanks again
@godsbigbrothergloble1419
@godsbigbrothergloble1419 7 жыл бұрын
I wanna say :im not kids ,so i cant code,XD
@Kidscancode
@Kidscancode 7 жыл бұрын
But you can learn! I suggest starting with my Python videos: kzbin.info/aero/PLsk-HSGFjnaGe7sS_4VpZoEtZF2VoWtoR
Godot 101 - Part 8: Tweens and Timers
14:18
KidsCanCode
Рет қаралды 23 М.
6 Tips to Better Organize your Godot Projects
11:39
GDQuest
Рет қаралды 135 М.
WILL IT BURST?
00:31
Natan por Aí
Рет қаралды 47 МЛН
小丑和白天使的比试。#天使 #小丑 #超人不会飞
00:51
超人不会飞
Рет қаралды 43 МЛН
An Unknown Ending💪
00:49
ISSEI / いっせい
Рет қаралды 37 МЛН
My Experience Moving to Godot from Unity
16:54
DarkDax
Рет қаралды 22 М.
Godot Recipe: Multitarget Camera2D
9:16
KidsCanCode
Рет қаралды 10 М.
Godot 4.3 is Here!
19:20
Gamefromscratch
Рет қаралды 97 М.
How do non-euclidean games work? | Bitwise
14:19
DigiDigger
Рет қаралды 2,4 МЛН
Introduction to Signals in Godot (2019)
8:07
GDQuest
Рет қаралды 41 М.
How to make advanced image recognition bots using python
15:01
Kian Brose
Рет қаралды 1,4 МЛН
Using Composition to Make More Scalable Games in Godot
10:13
Firebelley Games
Рет қаралды 227 М.
4 Godot 4 Devs Make 4 Games in 44 Hours
25:19
DevLogLogan
Рет қаралды 519 М.
WILL IT BURST?
00:31
Natan por Aí
Рет қаралды 47 МЛН