10 Things We Wish We Knew EARLIER (6) | Godot Engine

Поделиться
HTML-код
  • Опубликовано: 29 июн 2024
  • It's always a great time to learn some new Godot tricks! This time we show you how to use enums, singletons and signals, as well as many other things.
    Playlist with all our Godot tricks videos: • Things About Godot You...
    --
    Wishlist our action roguelite Furcifer's Fungeon: store.steampowered.com/app/17...
    Join our discord server: / discord
    Follow us on twitter to stay updated on Furcifer news and tutorials:
    / tweetfurcifer

Комментарии • 94

  • @PlayWithFurcifer
    @PlayWithFurcifer  2 года назад +29

    We're always hungry for more Godot tricks, so feed us!

    • @DevJeremi
      @DevJeremi 2 года назад

      you didn't mention any tricks that I wrote about on your discord :(

    • @PlayWithFurcifer
      @PlayWithFurcifer  2 года назад +1

      @@DevJeremi Stuff can easily slip through the cracks! Where have you posted them?

    • @disguisedpuppy
      @disguisedpuppy 2 года назад +2

      @@PlayWithFurcifer can i say sus?

    • @patrickseeber8115
      @patrickseeber8115 2 года назад

      Maybe I'm doing it wrong but I like to use add_to_group(X) and get_tree().get_nodes_in_group(X) to globally register nodes. That way I can call specific nodes without having to know where there are placed in the scene. I prefer this over NodePath export variables. Wanna show only the current menu? Hide all other nodes in the "Menu" group and show the current one. A custom key binding menu? Just get the nodes in group "Action_KeyBind_(youraction)" because you set them up to hold the captured input events for that action. Then simply replace the inputEvents in the InputMap.

    • @jeffvenancius
      @jeffvenancius 2 года назад

      I'd just tested this one:
      As it's usually done in react, you can make a statement like this in GDScript:
      var foo = true
      foo and print("if foo is true I'll be printed!")

  • @SmeddyTooBestChannel
    @SmeddyTooBestChannel 2 года назад +19

    the color picker one gives me vibes of when i'd leave something in plain sight in my room and think it's missing until i realized i'd grown so complacent to it being there i didn't even think of it being the thing i was looking for

  • @herorobb
    @herorobb 2 года назад +38

    The bitwise enums idea is brilliant. Also being able to copy and paste bitmasks on tilesets is wonderful.

    • @PlayWithFurcifer
      @PlayWithFurcifer  2 года назад

      :)

    • @MasterofBlubb
      @MasterofBlubb Год назад

      In case you ever need that in C#, add the Flag attribute (those with square bracket) to your enums and give them the proper values (bitshifted 1 is preferred as its more redable). Now you can use HasFlag on your Enum variables

  • @bagandtag4391
    @bagandtag4391 2 года назад +1

    That enum bitwise shit is some big brain stuff

  • @Montegasppa
    @Montegasppa 2 года назад +5

    This is the most useful “things we wish we knew earlier” you’ve ever published! Thank you very much!

  • @KlausWulfenbach
    @KlausWulfenbach 2 года назад +9

    Notifications are also great for when you need to know if the mouse has left the window.

  • @NonUnknownDev
    @NonUnknownDev 2 года назад +6

    I shared this video with my grandma, she said that will leave unity and start using godot :D thanks guys!

    • @PlayWithFurcifer
      @PlayWithFurcifer  2 года назад +3

      Amazing! I'm sure grannys games will be the best :)

  • @pete275
    @pete275 2 года назад +9

    Groups also work as event busses, without having to define a global. Add everyone to the group, then do "call_group" and everyone on the group gets called

  • @Roleplay78
    @Roleplay78 2 года назад +3

    Nice one!
    Keep in mind that the color picker is just local to your machine. It is stored along godot settings and not saved in the project.
    This means that if you wipe clean your machine, or works on multiple machines (like me), you are out of luck.
    To solve this problem, and store the palette as a project file, you need the colour palette plugin.

  • @FloMinicHD
    @FloMinicHD Год назад

    I rarely comment on videos but this is great, thank you! Especially that small part alone about using a singleton for signal management made me feel like I finally got the last important piece of knowledge to understand how to properly implement signals :)
    Had that thought before in my head - just not as properly formulated, so this was really helpful ❤

  • @Artichokeee
    @Artichokeee 2 года назад +10

    Thank you for the nice content lately! Really enjoying it and learning a lot. Hope you keep this up since I feel like this is one of the best if not the best Godot-related Channel out there :D

  • @Theraot
    @Theraot 2 года назад +12

    Alright, you are ready for: Resource Based communication!
    The insight is that when you load a resource from multiple places, you are getting the same instance (yes, even if you changed scenes). This means that one Object can write to it, and others can read it. Furthermore, you can put signals on your resources.

    • @Turnercore
      @Turnercore 2 года назад +1

      Yes! I've discovered signals in Resources and resource sharing and it's like a superpower. You can use Resources to easily share data among nodes, or even have them save themselves to disk when they change.
      You can also define custom setup() functions for your resources so when you do need to create more than one, you can have their defaults or data defined by the input variables.
      Also setget can be used for some pretty great tricks within custom resources, such as escaping and unescaping when asking the player for input.
      The only issue I've found so far is saving custom resources inside custom resources doesn't work great.

    • @hilfazer
      @hilfazer 2 года назад

      Strange, i'm getting 2 different instances of a Resource. How exaclty do i do that Resource based communication? I loaded a Resource and called new() but it looks like it's not the way.

    • @Theraot
      @Theraot 2 года назад +1

      ​@@hilfazer You called new, of course those are new instances. That suggests to me that what you loaded is the resource class. Your own custom resource class, I presume. But we want to load instances, not the class.
      Godot knows how to save and load instances of your resource class. The files from would be tres or res files (unless you define a plugin to load or save them as something else).
      To create those files, you can open the context menu of the secondary click on the FileSystem panel and select "New Resource…", then Godot asks you of what resource class, and you pick your own custom one.
      Alternatively, from code you can use the save method of the ResourceSaver class to save an instance of your resource class (which you would have created with new, like you did). I don't suggest this workflow resource based communication, but I'm letting you know it can be done. I suggest a good read of the documentation on resource paths, if you want to use ResourceSaver.
      Once you have your resource file, you can then load them from code with load or preload. Or you can have an export (Resource) var, which shows up in the Inspector panel, you can set your resource file to it. For example by dragging a resource file from the FileSystem to it.
      Although you will run into some long standing usability issues with custom resources in the Inspector panel. Try the addon "improved resource picker for Godot" by MakovWait, you can get it form Github or from Itch. It makes life somewhat easier.
      ---
      Built-in resource classes don't have problems in the Inspector panel. But we want a custom one, so we can define what properties and signals it has, and how it behaves.
      By the way, load is a shorthand for the load method of the ResourceLoader class. Which I want to mention to avoid misconceptions. And yes, that has some implications, but I'll not go into that rabbit hole in a RUclips comment.

    • @hilfazer
      @hilfazer 2 года назад

      @@Theraot Thanks for an explanation. I tried that and i got the same instance when using preload() but not when using load().

    • @Theraot
      @Theraot 2 года назад

      @@hilfazer Hmm… I believe sometimes load works, I'm not sure about the rules. But yes, preload works for sure.

  • @SaiponathGames
    @SaiponathGames 2 года назад +4

    If you want to have a closing screen like credits after you close the game, then you can use the _notification function to get the NOTIFICATION_WM_QUIT_REQUEST. You need to make sure that Auto Accept Quit to be disabled (thanks Nisovin).

    • @embyrdev
      @embyrdev 2 года назад

      Please for the love of god don't do this, it's infuriating.
      Just stick them on the main menu at the bottom of the screen.

    • @SaiponathGames
      @SaiponathGames 2 года назад

      @@embyrdev Well.. maybe when the close button is pressed, you might want to close up some resources, or do something, it might be helpful.

    • @SaiponathGames
      @SaiponathGames 2 года назад

      @@embyrdev Closing screen is just one example, but this thing could be used in much better ways.

  • @rocket007
    @rocket007 Год назад

    2:25 "like animals". Cracks me up cuz I keep doing it

  • @rosthouse
    @rosthouse 2 года назад +2

    Resources can also have signals. If you have two nodes that use the same Resources (let's say a health resource), you can set the health from one node, and the other can listen to a signal 'health_changed'. This makes it extremely convenient to stitch together separate scenes.

  • @RHGameDev
    @RHGameDev 2 года назад +5

    omg, I was copying and pasting colors like an animal the whole time

  • @belzecue
    @belzecue 2 года назад +2

    Double encrypted at 6:39. Can never be too careful.

    • @ezrawallet
      @ezrawallet 2 года назад +1

      Lmao this is a very under appreciated joke

  • @coreybarnett2158
    @coreybarnett2158 2 года назад +3

    These tips and tricks videos are my favorite! Thanks for putting them together! I'd love to see content about UI controls. I feel like I figured it out eventually but really struggle with sizing them and understanding the size flags.

  • @shmolyneaux
    @shmolyneaux 2 года назад +1

    As always, this is a great video! Thanks for making these!

  • @millerbyte5579
    @millerbyte5579 9 месяцев назад

    Fantastic, thank you for this!

  • @digitalman2112
    @digitalman2112 2 года назад +1

    Another great one. Thanks!

  • @john1995
    @john1995 2 года назад +2

    That was very helpful video. Nice job guys

  • @brunch1572
    @brunch1572 2 года назад +1

    I like the event bus thing a lot.

  • @question_mark
    @question_mark Год назад

    ohh the anonymous enum thing is so sweet

  • @mightymochigames
    @mightymochigames 2 года назад +1

    The event bus is a thing I've been wondering about how to do. Thanks for the tips!

  • @NightKawata
    @NightKawata Год назад

    this is the best one yet

  • @Chevifier
    @Chevifier 2 года назад

    That second tip will be a life saver

  • @KekLuck
    @KekLuck 2 года назад +2

    Thanks!

  • @voidboi0
    @voidboi0 2 года назад +1

    You guys are the best

  • @BlendFin
    @BlendFin 2 года назад +1

    Thankyou!

  • @thelumberjack8838
    @thelumberjack8838 2 года назад +2

    Amazing

  • @staticsteam636
    @staticsteam636 2 года назад +1

    I am lurking within the walls of your home, and am waiting for an opportune time to exact my vengeance upon you, and relieve this world of your existence(sorry for bad english)

    • @PlayWithFurcifer
      @PlayWithFurcifer  2 года назад

      uhm, you ok?

    • @w0nnafight
      @w0nnafight 2 года назад

      Yes please kill them, they are annoying. Torture them first though ( feed them their own guts)

  • @hectora.3220
    @hectora.3220 2 года назад

    very usefull!

  • @Pulkz
    @Pulkz 2 года назад

    Sehr nice

  • @gofastutos
    @gofastutos 2 года назад

    Good tricks to accelerate development

  • @godev1563
    @godev1563 2 года назад +2

    "Like animal's" 🤣🤣

  • @GodotDev
    @GodotDev 2 года назад

    The channel where I share the projects I made with godot engine ruclips.net/channel/UClPkdVpYamtO31RZnFSJA7A

  • @johnplainview6118
    @johnplainview6118 2 года назад

    5:15 Tactical Defense Poop ...

  • @BlackViperCat_62
    @BlackViperCat_62 2 года назад +2

    noice

  • @rocket007
    @rocket007 Год назад

    OK my grandmother says she loves it

  • @Theraot
    @Theraot 2 года назад +1

    Alright, do know that yield returns, right? If you are calling a function that yields, using yield, you do something like this:
    var result = yield(function_call(), "completed")
    Well, when you yield, the function actually returns a GDScriptFunctionState, and you are connecting to the "completed" signal of it. So, how do signals return? Let me tell you: if the signal has one parameter, it returns the argument you pass when you emit it. Otherwise it returns an array with all the arguments.
    This also means that when I'm refactoring my code to not use yield, I can instead return a custom object has a completed signal with one parameter, and that way the code that uses yield to call it does not break. Meaning that I can do my refactoring incrementally, instead of all at once.

    • @maxg5196
      @maxg5196 2 года назад

      Im a Godot noob, and my brain isn't big enough yet to fully understand.
      When you refactor your code to not use yield, what does that look like? Like what's the before line with yield and what's the after refactoring line with yield?

    • @Theraot
      @Theraot 2 года назад

      ​@@maxg5196 I have refactor the function, not just the line.
      On the replies on the comment where I mention CONNECT_ONESHOT I explain a little of the process.

  • @nyuh
    @nyuh 2 года назад

    yoomy eenoom

  • @hainguyentrung3358
    @hainguyentrung3358 2 года назад +1

    It'd better if you listed the contents in the description menu ( for e.g.: The name of each tip) so viewers can easily access useful tips without going through all of them.

  • @duaneanthony2304
    @duaneanthony2304 Год назад

    OK, how have I never just tried the plus button to save colors -_-

  • @Boildroid
    @Boildroid 2 года назад

    How to make blade mode in godot?

  • @firasalshouli4222
    @firasalshouli4222 2 года назад

    Do godot need a script app? Or you can script from godot it's self?

    • @PlayWithFurcifer
      @PlayWithFurcifer  2 года назад

      There is a pretty good integrated script editor (the one we us in the video!)

  • @errolecleston2548
    @errolecleston2548 Год назад

    ,🧐

  • @igorigor3960
    @igorigor3960 2 года назад +2

    before these series I was using Godot LIKE ANIMAL

  • @Theraot
    @Theraot 2 года назад +3

    By the way, are you using CONNECT_ONESHOT?
    I have been refactoring my code to use CONNECT_ONESHOT instead of yield. I know, shocking!
    The issue is that when a Node is freed while it was waiting on yield, when the signal comes it causes a runtime error. But when a Node is freed, all its signal connections are removed. It takes some work to refactor, but it is worth it.

    • @SaiponathGames
      @SaiponathGames 2 года назад

      How would you use it? Seems cool to hear!

    • @Theraot
      @Theraot 2 года назад

      @@SaiponathGames They are continuations.
      On the simpler case, you have a function that does something A, then yields and then does something else B.
      That would become a function that does something A, connects the signals you are yielding on with CONNECT_ONESHOT to another function and returns. Then the other function does the something else B. The other function is the continuation.
      You, of course would want to pass some extra arguments, which you can do with the binds parameter of connect. In fact, sometimes you don't need a new function, if the new function would be a one line call, you might be able to connect to that directly.
      It gets more complicated when you call yield in a loop. Again, you have two functions. One main function that connects the signal to the continuation one, but that one connects the signal to itself, making the loop (if you are doing a for, you would pass the index in binds, for example). But first you might need to rotate/unroll some of the instructions of the the loop, so it can start on the yield. That way you can extract a function that does what happens from yield to yield (it would take whatever result from the signal, process it, decide if it has to do another iteration, connect itself, and do whatever triggers it), which would be the continuation function. And the main function has to everything until the first yield (the loop probably becomes an if).
      You might have the logic for what happens after the loop on the same continuation function (since the function decides if it has to do another iteration, it can also handle the case where it does not have to). Or, you know, have more continuation functions.
      And, as I mentioned in another comment, you can return an object with a "completed" signal, so the code that used yield to call the function you are refactoring does not have to change. And that allows you to refactor a function at a time instead of all at once.
      One more thing that I've found useful: use call_deferred on emit_signal. I have found myself declaring that "completed" signal on the same object, then returning self, and emitting it with call_deferred.

  • @Theraot
    @Theraot 2 года назад +2

    You can emit signals of other objects! C'mon! You don't need to add a broadcast method to your signal/event bus. You just need to go EventBus.emit_signal(blahblah)