Interact With Objects in Godot 4 | Let's Godot

Sdílet
Vložit
  • čas přidán 22. 08. 2024
  • 👇Dialog Tutorial👇
    • Cute and Simple Dialog...
    Let's make an interaction system in Godot that allows players to press a button to trigger an event. You can make your NPCs start dialogs, implement save points, toggle lights, and anything else you could want your player to be able to do in your game world with a press of a button. By following this tutorial you'll also learn about Callables in Godot 4, as well as how to use composition in place of inheritance to make your code modular and take your indie gamedev skills to the next level.
    If you enjoyed the video leave a like :)
    🎵 HOME - Head First
    🎵 Less Gravity - Shhhh! Golf Is On - Lofi
    🎵 Towerz - while it lasted
    🎵 l'Outlander - Soul Searching

Komentáře • 361

  • @Archimond6
    @Archimond6 Před 11 měsíci +44

    Please keep making this, all of your tutorials helped me a lot to polish my game - it's a matter of time you will blow up due to the quality of materials and Godot getting more popularity.
    Thank you very much!

  • @robertgoodberry
    @robertgoodberry Před 8 měsíci +41

    When adding the interaction area scene to your interactable node, you must add it exactly as they do at 8:23! Don't use "Add child node". Use "Instantiate Child Scene". You can do this a few ways:
    - Click the chain link button in the top left of the node list
    - Right click -> Instantiate child scene
    - Drag the interaction area scene (tscn) file into the node list
    If you add it as a child node, you can see that it won't have the little WiFi symbol in the node list (no signals attached). If you add it with "Instantiate Child Scene", it will have the little WiFi symbol, carrying over the signals you defined in the interaction area scene.
    I was having trouble getting the _on_body_entered/_on_body_exited signals to fire like some other here but finally figured out what I was doing wrong. Hopefully this helps someone else!

    • @tik2243
      @tik2243 Před 5 měsíci

      Thank you! That was exactly what I was missing :D

    • @bersi
      @bersi Před 4 měsíci

      Thanks man, this answer should be pinned!

    • @MCNeko6554
      @MCNeko6554 Před 4 měsíci

      MVP comment right here! I couldn't figure out why it wasn't working when it looked all correct in the code. Thank you!

    • @onurcanari
      @onurcanari Před 3 měsíci

      thx.i was searching comments for solution to this :D

    • @PoissonedApple1
      @PoissonedApple1 Před 3 měsíci

      Thanks for your comment, I triple checked the video but did not notice this.

  • @artdirectorgiraffe1003
    @artdirectorgiraffe1003 Před 11 měsíci +19

    I can notice the ammount of work you are putting into these videos!!! Looking forward to more of these!

  • @fanfugdyx
    @fanfugdyx Před 5 měsíci +11

    For those that having trouble with the label not showing above the NPC, try replace label.global_position.x = label.size.x / 2 to label.global_position.x = active_areas[0].global_position.x - 50 , it worked for me, the label is centered above the NPC.

  • @NicolasEmbleton
    @NicolasEmbleton Před 11 měsíci +13

    Really high quality code here. Thanks for sharing.

  • @thelaserraccoons374
    @thelaserraccoons374 Před 10 dny

    Thank you so much! Please keep making such awesome tutorials.

  • @Dahras1
    @Dahras1 Před 11 měsíci +11

    I really like this tutorial and the architecture of this interact system!
    One thing I would suggest, though, is trying to used .distance_squared_to() rather than .distance_to() in cases where you are directly comparing the length of two vectors. Obviously in this case, the .distance_to() function wouldn't get called that much, but its still a good thing to do ahead of time since from your perspective the two options are identical. For example, if someone wanted to use this code to implement picking up loot drops in a Diablo-like ARPG, there might be a lot of interactables in the queue, in which case the difference between the two variables would make a difference.

    • @DashNothing
      @DashNothing  Před 11 měsíci +6

      Thanks for the tip. I had no idea those two can be used interchangeably and that the squared one comes with a performance boost. Will keep that in mind

    • @derek-rogers
      @derek-rogers Před 10 měsíci +5

      @@DashNothing Probably good to note that they aren't interchangeable in *every* case, like if you really do need the specific value for distance. But if all you need to know is which object is closer, .distance_squared_to() is the way to go! Great video, I definitely learned something new!

  • @Beryesa.
    @Beryesa. Před 11 měsíci +4

    No way you're still sub-thousand with such videos! Here before this'll blow up! :D

  • @TheRealMadJack
    @TheRealMadJack Před 4 měsíci +1

    The amount of work you did to make that video is astounding. Excellent work. Also, great content!

  • @Exeggutive
    @Exeggutive Před 11 měsíci +3

    I don’t know why the hell I’m watching this when I’m still doing the official tutorial thing but it’s just too damn interesting

  • @americoperez810
    @americoperez810 Před 11 měsíci +4

    This is fantastic! Please keep making these sorts of videos

  • @henryaudubon
    @henryaudubon Před 11 měsíci +5

    Excellent tutorial! I subbed and will be watching your other Godot content. Thanks for making it!

  • @haydenap
    @haydenap Před 10 měsíci +2

    This is excellent. New subscriber as I'm building up courage to dive back into Godot after a long break.

  • @Taylor-ib8od
    @Taylor-ib8od Před 9 měsíci +1

    Great tutorial, thanks very much. I've been looking for one that worked for a few days and hadn't managed until finding this. Really high quality code too. Liked and subscribed.

  • @thesomeone2nd
    @thesomeone2nd Před 11 měsíci +2

    Bro literally that's really hard but pretty amazing thanks for the help man!

  • @_xtel
    @_xtel Před 11 měsíci +3

    Awesome! Great tutorial as always.

  • @antonlytvynenko
    @antonlytvynenko Před 11 měsíci +1

    A legend, an unsung hero, cute animal saver
    Thank you sir, keep up the great work

  • @Over_Xelis
    @Over_Xelis Před 7 měsíci

    These are honestly so well done, great job man. Keep em coming!

  • @matias-dev
    @matias-dev Před 3 měsíci

    Loved the video, explained all i needed to know, will watch the rest of your videos, thank you for making them

  • @sWonexe
    @sWonexe Před 4 dny

    Well played. Now I have to watch the DialogManager-Video aswell. ;-)
    Very good Video, I learned a lot!

  • @indierusty
    @indierusty Před 11 měsíci +1

    Concise yet clear! Amazing video

  • @mkrojwvl8745
    @mkrojwvl8745 Před měsícem

    Process is a preset function that is called every frame. Sorting an array every frame has a big toll on the perfomance if the array is getting bigger.

    • @DashNothing
      @DashNothing  Před měsícem +3

      @@mkrojwvl8745 True, but I imagined the player would be around maybe half a dozen interactables at one time at most, which isn't that bad. If performance is an issue sorting could happen in a timer's timeout callback which would be called a few times a second.

  • @TheGamesRandons
    @TheGamesRandons Před 11 měsíci +2

    Great video! Quick and easy to understand. Thanks!

  • @andreypekarskiy3697
    @andreypekarskiy3697 Před 2 měsíci

    This is really great tutorial. You are doing amazing job mate! Subscribed, for sure.

  • @ajinkyax
    @ajinkyax Před 9 měsíci +1

    Subscribed. really appreciate you are sharing good design patterns here

  • @TeaOS
    @TeaOS Před 4 měsíci

    I've never done programming before and this was so easy to follow thank you for this

  • @haluz2281
    @haluz2281 Před 3 měsíci +1

    I tried to figure this by myself with almost zero knowledge in programming... I thought I was still far from the right result, but not by THAT much :D This seems so complicated for such a simple thing in a game

  • @jazibobs
    @jazibobs Před 7 měsíci

    Came for the Godot information, stayed for the Hot Mulligan lo-fi. Thanks for such a great video!

  • @abranubes9571
    @abranubes9571 Před 7 měsíci

    Amazing video, clear, well edited and produced, and super helpful with good practices and explanations, thanks you! +sub

  • @slothinahat
    @slothinahat Před 11 měsíci +1

    Composition makes me happy I strive to be like you

  • @SanitoGonzalez
    @SanitoGonzalez Před 23 dny

    Thanks for the great video! It helps a lot.
    I'd like to suggest an improvement for `interaction_manager.gd`
    ```
    func register_area(area: InteractionArea):
    _active_areas.push_back(area)
    _active_areas.sort_custom(_sort_by_distance_to_player)

    func unregister_area(area: InteractionArea):
    _active_areas.erase(area)
    _active_areas.sort_custom(_sort_by_distance_to_player)
    ```
    - `erase` method can simplify the find & remove.
    - only sort whenever the area is registered or unregisted; no need to sort the array on every process cycle

  • @Mohrahn
    @Mohrahn Před 10 měsíci +1

    interaction area could have a signal that has a callable as the first argument that allows you to tell the interaction area when you're done interacting, instead of needing to create a reference then pass a callable to the area. Mainly because the current setup means only one function can be run to interact with the area, but if it's a signal any number of things could also happen when interacting.

    • @DashNothing
      @DashNothing  Před 10 měsíci

      Fair, but even this, in my opinion simpler approach, can easily be expanded with an interact or interaction_finished signal on the interaction area which can be emitted from the manager

  • @Pixelmoh
    @Pixelmoh Před 7 měsíci

    I have no idea about programming, like absolutely zero and it's like learning mandarine for me when I try to watch these tutorials as I just started to make games with Godot. But your Video was exactly what I was searching for. Thanks!

  • @schleicher47able
    @schleicher47able Před 9 měsíci

    this so great. i love this approach. You are awesome! thank you SO MUCH! ♥

  • @tengentopka727
    @tengentopka727 Před 9 měsíci

    Thanks for the video, I'm creating dialogues using Dialogic addon and this method really helped.

  • @steeldash740
    @steeldash740 Před 11 měsíci +1

    Amazing as always

  • @jeromealday614
    @jeromealday614 Před 10 měsíci

    This is much better than my raycast method, Good job 👍

  • @dankay9202
    @dankay9202 Před 2 měsíci

    perfect for what i needed, thanks!

  • @violet5980
    @violet5980 Před 9 měsíci

    Im a unity refugee so this has been a massive help!

  • @soorajmp6526
    @soorajmp6526 Před 5 měsíci

    nice video as always thankyou,
    i also implemented the same in 3d ,so simple and reusable

  • @carlosmarcelinomartinezsus1113
    @carlosmarcelinomartinezsus1113 Před 11 měsíci +2

    Muy buenos tus videos, aprovecha el declive de Unity y métele mas a Godot, te va a ayudar mucho a crecer, tus videos son muy interesantes!

  • @uncarpinchomatero
    @uncarpinchomatero Před 2 měsíci

    This implementation has potentially a lot of bugs for an actual game, but its good enough to get the idea

    • @DashNothing
      @DashNothing  Před 2 měsíci

      I'd love to know so I could potentially improve on this solution - what do you think would cause bugs?

  • @elranchodejuancho1609
    @elranchodejuancho1609 Před 7 měsíci +2

    hello, i have an small problem running the code, so, everything works fine until I change to another scene, then when it enters another interaction area the game just stops and gives me the error:
    Invalid get index 'global_position' (on base: 'previously freed').
    Hope you can respond to me.

    • @elranchodejuancho1609
      @elranchodejuancho1609 Před 7 měsíci

      oh and i forgot to mention that to change scenes I used get_tree().change_scene_to_file("res://niveles/nivel test/world_test.tscn"), dunno if it is the best way to do it but... it works

    • @DashNothing
      @DashNothing  Před 7 měsíci +2

      My bad, the issue is with the way of getting the player node in the InteractionManager script. When a new scene is loaded and the old player is deleted, the script doesn't fetch the new player. Good thing you found this!
      Here's the solution with a bit more info:
      gist.github.com/DashNothing/dd25d62a264bd581ee2ea2ffdac026a4

    • @elranchodejuancho1609
      @elranchodejuancho1609 Před 7 měsíci

      @@DashNothing Oh. My. GOD, you have done it, and so fast too, you have saved me (and many others), you are stablising a new generation of programmers, thank you for your very important service

    • @babyjay1386
      @babyjay1386 Před 6 měsíci

      Thank you! I was having this same problem too and had no idea what was going on.@@DashNothing

    • @izurutaika
      @izurutaika Před 4 měsíci

      @@DashNothing I was having the same issue, thanks for this!

  • @BirbDoy
    @BirbDoy Před měsícem

    Really awesome, your tutorials speed up my dev process by a ton, thanks!
    I just wanted to ask something, whenever I reload a scene, the InteractionManager doesn't because it's a singleton, which doesn't update the player variable and thus creating an error in the func _sort_distance_to_player because the variable player's value is null after a reset. What I did was just updating the player variable constantly.
    Am I doing it right lmao

  • @jamesallen5890
    @jamesallen5890 Před 2 měsíci

    wow. needed this

  • @olatot
    @olatot Před měsícem

    Nice implementation! One thing had me thinking though; what's the use of the "Action name" variable on this system? (The one you input "talk" for the player and "toggle" for the lamp), i've watched the video twice and I still don't think it has much of an use hehe

    • @DashNothing
      @DashNothing  Před měsícem

      It's for the interact prompt label ([E] to ..). So you can change the prompt based on the context of the interaction.

  • @looves132009
    @looves132009 Před 10 měsíci +2

    I'm super new to this and would love to have seen how you set up the lamp from the beginning in order to implement it into the game. Woud there be a chance that you could show that in the future? Or lead me to a resource that would show me how to set up an object with an animation to interact with the player?

    • @DashNothing
      @DashNothing  Před 10 měsíci +3

      In the case of the lamp I really didn't use any animations. I just changed the frame of the sprite, as you can see in the code. To learn more about the topic check out Godot's documentation for Sprite2D, AnimatedSprite and AnimationPlayer. Hope that helps!

  • @rainbowthumb9979
    @rainbowthumb9979 Před 2 měsíci +2

    does this work with 3d?

  • @bestyesecretclub
    @bestyesecretclub Před 11 měsíci +2

    sorry im getting "Invalid set index 'global_position' (on base: 'Label') with value of type Vector 3" everytime my player collides with the area :/
    it redirects me to the "label.global_position = active_areas[0].global_position" line in the process function but i'm not seeing any typos so :(

    • @DashNothing
      @DashNothing  Před 11 měsíci +1

      It looks like you used an Area3D node instead of an Area2D for the interaction area. Hope this helps!

    • @bestyesecretclub
      @bestyesecretclub Před 11 měsíci +1

      @@DashNothing sorry aahah i forgot to mention that my project is in in fact 3D

    • @DashNothing
      @DashNothing  Před 11 měsíci +1

      @@bestyesecretclub Okay, then you can use the Label3D node instead, which is the easiest alternative. Check out your options here: docs.godotengine.org/en/stable/tutorials/3d/3d_text.html

  • @PiglioXDD
    @PiglioXDD Před 7 měsíci +1

    Amazing video, helped me a lot on developing my first 2d game I'm making! But I got 1 question though, how did you switch the sprites of the lamp with no Animation Player or AnimatedSprite2D? I have the open and closed sprites for a chest and im trying to make it change to that open sprite.

    • @DashNothing
      @DashNothing  Před 7 měsíci +1

      I used a texture with both frames next to eachother. Then I set the sprite's hframes property to 2, telling Godot to split the texture into two parts. To change which part is shown I change the frame property.

    • @PiglioXDD
      @PiglioXDD Před 7 měsíci

      @@DashNothing Oh thanks a lot!

    • @PiglioXDD
      @PiglioXDD Před 7 měsíci

      @@DashNothing Also is there a way to make the interact option appear and work only once?

    • @DashNothing
      @DashNothing  Před 7 měsíci

      @@PiglioXDD at the end of the interact function you can do one of the following:
      - get interaction area's collision shape and set its disabled property to true
      - call interaction_area.queue_free() to delete it permanently
      This is off the top of my head so if it doesn't work let me know.

    • @PiglioXDD
      @PiglioXDD Před 7 měsíci

      @@DashNothing Used the second option and worked perfectly, again thank you very much! Keep it up with the videos!

  • @BobNeverStop
    @BobNeverStop Před 2 měsíci

    Great tutorial, but can I use this in InteractionManager?
    func unregister_area(area):
    active_areas.erase(area)
    instead of this:
    func unregister_area(area):
    var index = active_areas.find(area)
    if index != -1:
    active_areas.remove_at(index)

    • @DashNothing
      @DashNothing  Před 2 měsíci

      Yes you can. At the time I didn't know about the erase function, but yeah it's cleaner.

  • @scotmcpherson
    @scotmcpherson Před 11 měsíci

    Keep it up ! Let’s godot !!!

  • @enderalex300
    @enderalex300 Před 6 měsíci +1

    Hey, great video, much appreciated! I have one issue though, it seems that I'm able to interact w/ an interactable object from any distance, and immediately when the two enter a scene together. It's confusing to me because I assume that you can't register an area as interactable until the player collides w/ the interaction_area's collisionShape. I'm not sure why it isn't acting like that.
    If I add two interactable objects to the scene, they do shift between distances, but I can interact with either of them from any distance as well. I don't know if that's relevant, but yeah. Again, thanks for the video!

    • @enderalex300
      @enderalex300 Před 6 měsíci +1

      Never mind, I realized it's because while my InteractionArea's collisionshape was masked to only detect the player, the actual object it was attached to was set on the default layer, which is player. It fired immediately on startup because it thought it was the player lmao.

    • @DashNothing
      @DashNothing  Před 6 měsíci +1

      @@enderalex300 Easy mistake to make. Glad you figured it out.

  • @HungaryHQ
    @HungaryHQ Před 3 měsíci

    worked! Thanks

  • @therealugly3846
    @therealugly3846 Před 9 měsíci +2

    Need help fixing my codes, in your InteractionManager, you made a function called _sort_by_distance_to_player, and had arguments area1, and area2, but it is giving me an error that says, "Invalid get index 'global_position' (on base: 'null instance'). Do you have an idea why so?

    • @DashNothing
      @DashNothing  Před 9 měsíci +1

      It could be that your InteractionManager can't find the player scene (first line where it gets first node in group "player"), in which case make sure player has his group set to "player" and that it's in the scene.
      The other problem could be with regjstering areas, so make sure each area calls register and unregister functions when the player enters/exits them. You shouldn't have any null values in InteractionManager's actjve_areas, so you can print() it and check and different times in code.
      Hope that helps!

    • @joshuahansberg3057
      @joshuahansberg3057 Před 3 měsíci

      @@DashNothing @therealugly3846 I have the same problem. but it is not happening all the time. When a mob dies and drops a ammo_crate this happens. could it be that when an scene ist instantiates the player does not get registered as area_entered? Did you ever solve your prolem @therealugly3846

  • @prof_nobody
    @prof_nobody Před 11 měsíci +1

    I was trying to figure something like this out so this was super helpful. One thing I am encountering is an invalid get index for global position in the sort by distance function. I am trying to figure out if this is something happening as I move just out of range of one item and it starts to trigger on another. I am pretty sure it is trying to unregister as it does this. I am using this for drops from monsters and it works pretty well except for this one thing.

    • @prof_nobody
      @prof_nobody Před 11 měsíci

      actually seems to be something with the two items being inside the same area....

    • @prof_nobody
      @prof_nobody Před 11 měsíci +1

      ah I figured it out... my group for player is Player and following I did player. So excellent tutorial. Much appreciated.

    • @DashNothing
      @DashNothing  Před 11 měsíci +2

      @@prof_nobody Awesome! Glad you got it working

  • @moonnight9474
    @moonnight9474 Před 11 měsíci +1

    good job

  • @SergioMatsumoto
    @SergioMatsumoto Před 5 měsíci

    very nice!

  • @mightymimoo454
    @mightymimoo454 Před měsícem

    Hi DashNothing!
    Thank you for the great video! It's super helpful. I have a question to you and to anyone in the chat really. I'm implementing the InteractionManager singleton and InteractionArea class into my current game, however I am getting a runtime error of: Invalid type in function 'register_area' in base 'Node2D (InteractionManager.gd)'. The Object-derived class of argument 1 (CharacterBody2D (Player.gd)) is not a subclass of the expected argument class.
    It seems that the instantiated version of InteractionManager within the InteractionArea class is not being recognized properly. Any ideas to why this happens?

    • @DashNothing
      @DashNothing  Před měsícem +1

      This seems like you're passing the player scene to the reguster_area function, when you should be passing in the interaction area scene. Because register_area is called from the interaction area script you have to pass in "self".

  • @fullmusic744
    @fullmusic744 Před 5 měsíci +1

    when i write
    func _ready():
    Interaction_area.interact = Callable(self, "_on_interact")
    in the npc that i want to add, it says that "invalid set index "interact" with vallue of type Callable"
    thats how i wrote the var interact:
    var interact: Callable = func():
    pass

    • @yxgen4
      @yxgen4 Před 5 měsíci

      are you using godot 4?

    • @fullmusic744
      @fullmusic744 Před 5 měsíci +2

      @@yxgen4 yeah, 4.2 i think

  • @WillVanDenBerghe
    @WillVanDenBerghe Před 9 měsíci +1

    Ok so I'm running into a problem trying to register the interaction area in the manager on body entered and exited (7:59). It's saying that InteractionManager is not declared in the current scope. Do I not need to import that somehow? Not sure how this works in godot, is that a singleton?

    • @DashNothing
      @DashNothing  Před 9 měsíci +3

      Yes, it's a singleton but you need to tell Godot to use it as such. Click on Projecr settings, then autoload tab and add interaction_manager.gd. Now it wiill be accessible from any script.
      This is covered in the video as well if you find yourself lost
      Hope that helps!

    • @WillVanDenBerghe
      @WillVanDenBerghe Před 9 měsíci +1

      @@DashNothing awesome man. Yes sorry looking back I realized I missed this in the video. Thank you so much for the reply!

  • @TinkEdwards
    @TinkEdwards Před 2 měsíci

    I used your tutorials for the dialog manager and interaction manager and they seem to work great. But when I try to incorporate my inventory into the mix, and I'm trying to add a yes/no prompt to pick up items, I cannot at all get it to work. Any tips? Also, is it possible to have my main character's dialogue to appear over his head and whatever object I'm interacting with has its dialogue closer to it? Like a conversation. Thank you for whatever help you can give!

  • @kiroky95
    @kiroky95 Před měsícem

    This was working fine until i overlapped objects with this and then it crashed.

    • @DashNothing
      @DashNothing  Před měsícem

      @@kiroky95 What's the error you get? It should work 100% fine with overlapped interaction areas, as shown in the video.

    • @kiroky95
      @kiroky95 Před měsícem

      @@DashNothing Invalid get index 'global_position' (on base:'null instance") on sort by distance to player area1 in InteractionManager script

  • @EMDthe1
    @EMDthe1 Před 27 dny

    It says that there is no label shown

  • @kamolr6539
    @kamolr6539 Před 7 měsíci +1

    Hello! i have a problem where it says "Invalid get index 'global_position' (on_base: null instance) upon entering to areas in the same time. in Addition labels are not shown whilst entering areas. Have any ideas why?

    • @DashNothing
      @DashNothing  Před 7 měsíci

      There's a number of things that could be wrong:
      - Your player variable in InteractionManager is null - this could be if the player isn't in the player group
      - You added the interaction area scene the wrong way - you have to add it by clicking on the "instantiate child scene" button (link icon) and NOT on the "add child node" button (plus icon)
      - The null instance is one of the interaction areas, which means they most likely don't register / unregister themselves properly
      Use the debug tool to find out exactly what variable is causing the issue and I'll be happy to help you further!

    • @kamolr6539
      @kamolr6539 Před 6 měsíci

      @@DashNothingI think I fixed the problem, player var was null even tho it’s in group so I made my own function which gets player pos to global vector and its given to area_to_player. But the label “[E] to interact “ is not showing (wasn’t before fix) any idea why?

    • @DashNothing
      @DashNothing  Před 6 měsíci

      @@kamolr6539 Do you update the player's position in the proccess function? If not, you should do that to always have the newest position available.

    • @kamolr6539
      @kamolr6539 Před 6 měsíci

      @@DashNothing function which changes global vector is inside player script and is called after move and slide function and play animation function

    • @DashNothing
      @DashNothing  Před 6 měsíci

      @@kamolr6539 Can you interact even though the label doesn't show up?

  • @Russian_engineer_bmstu

    I like this vid

  • @Captainkye
    @Captainkye Před 2 měsíci

    hey! this was an amazing tutorial!
    I have a question about the sprite frame changing at 10:00
    Instead of using a light i am using a campfire which as a animated sprite. for func _toggle_fire how would i change the animated sprite from a animated unlit campfire to a animated lit campfire?

    • @DashNothing
      @DashNothing  Před 2 měsíci

      You can have multiple animations per animated sprite. You can change which animation is playing programatically with sprite.animation = ...

  • @TheCatMurgatroyd
    @TheCatMurgatroyd Před 24 dny

    I have a few questions:
    Can this not be done with a tile from a tile set?
    Do i have to export every object I want the player to interact with as a separate image, then use it as an image file? (or what type of file, anyway?)
    I also find it weird that I need a separate window for every item?
    Can't I create every interactable object in my main scene from scratch?
    pls someone help 😩

  • @princecaspiangw796
    @princecaspiangw796 Před 21 dnem

    If I wanted to make an interaction that teleported the player, how would I go about that?

  • @itchy_nadz
    @itchy_nadz Před 8 měsíci

    "make sure you player is in the player group" Can you expand? @3:09 Great videos, btw.

    • @DashNothing
      @DashNothing  Před 8 měsíci +2

      If you click on the root node of your player scene by default you see the inspector on the right side of the editor. Click on the "node" tab next to the inspector tab and you will see the node's signals. Click on the "groups" tab next to the signals tab. There you can add the scene to groups by typing in the name of the group. In this case type in "player" and click add group.

  • @rn3rne
    @rn3rne Před 11 měsíci

    nvm, fixed it by myself, thank u for the video, if I finish my game, you should be in the credits ❤

  • @foxpeltt
    @foxpeltt Před 2 měsíci

    I keep getting the error "Invalid set index 'text' (on base: null instance) with value type of String." for my label. What do I do?

    • @DashNothing
      @DashNothing  Před 2 měsíci +1

      Make sure you got the @onready var label = $... line at the top of the interaction manager script. Also make sure that the name of the label node in the scene tree is the same as the name you put after the $ symbol.

  • @ivanchistyakovyt
    @ivanchistyakovyt Před 11 měsíci +1

    When my player collides with an object that I attached the interaction_area to, I get Invalid get index 'global_postiion' on base: Array[Node] in the custom sort function. The player group is player and everything else is just like in the video. What could be wrong?

    • @DashNothing
      @DashNothing  Před 11 měsíci

      Check if the word "global_position" is spelled correctly in the sorting function.

    • @ivanchistyakovyt
      @ivanchistyakovyt Před 11 měsíci

      func _sort_by_distance_to_player(area1, area2):
      var area1_to_player = player.global_position.distance_to(area1.global_position)
      var area2_to_player = player.global_position.distance_to(area2.global_position)
      return area1_to_player < area2_to_player@@DashNothing

    • @DashNothing
      @DashNothing  Před 11 měsíci

      @@ivanchistyakovyt hmm, it seems like the function is trying to get the global_position of a nonexistant node. Could it be that an interaction area registered itself on the manager, and then it was deleted from the scene before unregistering? Or something other than an interaction area registered itself?

    • @ivanchistyakovyt
      @ivanchistyakovyt Před 11 měsíci +1

      @@DashNothing Found mistake! Was @onready var player = get_tree().get_nodes_in_group("player") instead of @onready var player = get_tree().get_first_node_in_group("player"). Big thanks for the video and trying to help! Liked and recommended!

  • @bellehuberty9457
    @bellehuberty9457 Před 3 měsíci

    hello! i came from your textbox video. thank you so much for this high-quality content!
    i was wondering if you could help me - when using the interaction manager and dialogue managers together, how do we "tell" the interaction manager to display the textbox we set up in the dialogue manager? thank you!

    • @DashNothing
      @DashNothing  Před 3 měsíci

      Thanks for the kind words!
      You don't really tell the interaction manager what to do at all. The beauty of this is that each interaction area has its own oninteract callable that defines what happens.
      So when you're overriding the oninteract callable you can just call DialogManager.start_dialog(). I put an example of just that near the end of this video, when making an npc.

    • @bellehuberty9457
      @bellehuberty9457 Před 3 měsíci

      @@DashNothing Ahh ok, so to use the dialogue manager, we would go into the "triggerring" object's script and call the dialogue manager? Or would we call the dialogue manager in the interaction script?
      Thank you for your support I really appreciate it!

    • @DashNothing
      @DashNothing  Před 3 měsíci

      @@bellehuberty9457 You'd do ti from the triggering object's script. Check out how I made an NPC at the end of this video.

  • @bredcataw
    @bredcataw Před měsícem

    Good.

  • @DrowsieDumbo
    @DrowsieDumbo Před 5 měsíci

    I can tell I've got a long road ahead of learning.. the small oversights and assumed knowledge in this video leave me completely lost. This isn't quite as beginner friendly as I thought, I suppose I'll return in the future.

    • @DashNothing
      @DashNothing  Před 5 měsíci

      It's not meant to be for complete beginners, unfortunately. When we're talking about systems such as this there's an implied required understanding of software architecture and coding fundamentals. Of course, starting out you should tackle easier topics, such as the action rpg tutorial series by HeartBeast. I followed that one when I first started and I cannot recommend it enough.

  • @arisu8118
    @arisu8118 Před 11 měsíci +1

    Can i use this method to add a value to a variable in another scene, for example i want to add ammo to my weapon?, i tried to use and a made a global var but i dont know if it is the best way to do.

    • @DashNothing
      @DashNothing  Před 11 měsíci +3

      You can either have a global singleton that holds the ammo value and then add to it from your interact function and read from it in the player script. I assume this is what you did.
      Or you can have a reference to the player in the object that adds the ammo and add it directly to the player.
      I think the first approach might be better because there's less coupling. But it's fine either way.

    • @arisu8118
      @arisu8118 Před 11 měsíci +1

      @@DashNothing thanks

  • @lordbarron3352
    @lordbarron3352 Před 22 dny

    Wouldn't using a singleton for interactionmanager restrict the game to being singleplayer? Or are multiple players able to use it with no problem?

    • @DashNothing
      @DashNothing  Před 22 dny

      @@lordbarron3352 I've never made a multiplayer game, so I don't know. What do you suggest?

    • @lordbarron3352
      @lordbarron3352 Před 22 dny

      ​​@@DashNothingFor composition rather than inheritance, id have to think for a while. The way you structured it in the video works pretty similar to inheritance though. You essentially just decoupled the class to be overriden and set it as a singleton.
      For the inheritance route, you could have the player check for objects with an interactable component within an area, then call the objects override method.
      Currently though, i think I like your method better.

  • @SinatoyGaming
    @SinatoyGaming Před 3 měsíci

    hi that was a very great tutorial ! Everything worked almost perfectly until i tried to see the text bubble, but it didn't appear... The "press E to.." work just fine but for some reason not the text, so if anyone have info on that, i will gladly take advice

  • @doingitsidesways
    @doingitsidesways Před 8 měsíci +1

    Hi, i really love your tutorials but for some reason the interaction isn't triggered, the interactionmanager is in the autoload, the collision of the interaction area and the player are setup correctly, but it just dose nothing. I double checked the code with the video multiple times and didn't find an error.

    • @DashNothing
      @DashNothing  Před 8 měsíci +1

      Thank you!
      Does the text "[E] to interact" appear when the player is in range or does that not work either?

    • @doingitsidesways
      @doingitsidesways Před 8 měsíci

      @@DashNothing That dosnt work either.

    • @DashNothing
      @DashNothing  Před 8 měsíci

      @@doingitsidesways So it's either your active_areas is always empty shich means your interaction areas don't register themselves properly OR your can_interact starts at false. Can you print out those two into the output from InteractionManager's _unhandled_input() function when the player tries to interact?

    • @doingitsidesways
      @doingitsidesways Před 8 měsíci +2

      Hi thanks for the help, i figured it out after breaking my head over it, for some reason connecting the signals trough the editor didnt work, even tho it looked like it did, i connected it trough code:
      func _ready() -> void:
      body_entered.connect(_on_body_entered)
      body_exited.connect(_on_body_exited)
      and now it works as expected. Thank you for replying to me, i looking forward to more of your videos.

    • @brookbrown9202
      @brookbrown9202 Před 5 měsíci +1

      @@doingitsidesways holy shit thank you. i was about to rip my hair out lmao you're a godsend. amazing tutorial @DashNothing this streamlines so much for me!

  • @HammHammVT
    @HammHammVT Před 7 měsíci

    Hi again Dash!
    Quick question with your Interaction Manager.
    Could it be adjusted if we wanted to interact with objects that open UI? (inventory, crafting menus, etc.?)
    If so, where? In the "input" section?

    • @DashNothing
      @DashNothing  Před 7 měsíci +1

      Yes, you can do that easily. You would do it the same way you do other interactions - by assigning a function to interaction_area's interact callable. Only instead of let's say starting a dialog there, you could get a reference to a hidden UI element in the scene and set its visible = true.

    • @HammHammVT
      @HammHammVT Před 7 měsíci

      @@DashNothing I see - what Node would you recommend for a UI? I'm currently using a Control Node and it just doesn't seem to make UI appear, even when the function IS called.
      It works if I hardset a key to it like "i", but not with the interaction "e".

    • @DashNothing
      @DashNothing  Před 7 měsíci +1

      @@HammHammVT Any node that inherits from the Control node would work. You would probably use a PanelContainer for a background, and then place the text and buttons inside it.
      Then in the interact function you can write something like $PanelContainer.visible = true

    • @HammHammVT
      @HammHammVT Před 7 měsíci

      @@DashNothing
      DashNothing, Godot Sensei LOL
      I'll give it a try - wish me luck!

    • @HammHammVT
      @HammHammVT Před 7 měsíci

      @@DashNothing
      Hi Dash - no luck.
      Even with "visible = true", the UI doesn't want to appear.
      I can make it appear without the interaction object (Input.is_action..) but not with the object.
      My print statements tell me that the value has changed tho. Idk how to proceed from there.
      Any suggestions?

  • @DaveyGame
    @DaveyGame Před 3 měsíci

    Hey, All of this works but when i try do interaction_area and the stuff under on_body_entered/exited it says Identifier "InteractionManager" not Declared in the current scope.

  • @willd2609
    @willd2609 Před 2 měsíci

    amazing! can we please grab the source code for this project?!

  • @matezu
    @matezu Před měsícem

    I just wanted to know how to make the interaction text return as in the video because when I first interact with the NPC it doesn't appear again

    • @DashNothing
      @DashNothing  Před měsícem

      @@matezu It should be working like that with the code in the video. Maybe you didn't set can_interact back to true?

  • @XxXAllukardXxX
    @XxXAllukardXxX Před 7 měsíci

    For some reason I always have on_enter triggered once, when I enter actual area, I have 2.
    uPD. Seems to be fixed. I did not pay enough attention to collision layer and mask part.

  • @Yanko_-pe1kf
    @Yanko_-pe1kf Před 8 měsíci

    In the interaction manager I'm being told that in lines 13(active_areas.push_back(area)) and 22(if active_areas.size() > 0 && can_interact:) that there is an 'Invalid call. Nonexistent function 'size' and 'push_back' in base 'String'.'

    • @DashNothing
      @DashNothing  Před 8 měsíci +1

      active_areas is supposed to be an array, and it looks like you made it a string. When you define var active_areas at the top of the script make sure you add = [] to initialize it as an empty array.
      var active_areas = []

  • @MonkeyDRuffy-em1vn
    @MonkeyDRuffy-em1vn Před 3 měsíci

    Why did you/he decide to get the player node by using a group instead of doing it with "$" like done with var label?

    • @DashNothing
      @DashNothing  Před 3 měsíci +1

      With $ you can only get children of the node. Player is not a child of InteractionManager

  • @marcelodavila8569
    @marcelodavila8569 Před měsícem

    When I add the functions to my interactionArea I get this mistake, can anyone help me??
    Parse Error: Identifier "InteractionManager" not declared in the current scope.

    • @DashNothing
      @DashNothing  Před měsícem

      @@marcelodavila8569 You didn't autoload the interaction manager. Go to project settings, click the autoload tab, click the folder icon at the top, find InteractionManager.tscn, then click the add button on the right.

    • @marcelodavila8569
      @marcelodavila8569 Před měsícem

      @@DashNothing Thank you but now I have another problem where my sprite does not interact with anything even though I have it all set up

  • @jasonleeroberts
    @jasonleeroberts Před 2 měsíci

    Thank you so much for this tutorial! I tried following it, but also converting it to 3d. I followed all of the steps that you made, but I'm getting this error "Invalid set index 'global_position' (on base: 'Label') with value type of 'Vector3'" and it's pointing to a line that states:
    label.global_position = active_areas[0].global_position
    Any idea what could be happening here? I'm not skilled enough to understand this yet 😅

    • @DashNothing
      @DashNothing  Před 2 měsíci

      Label is a control node, meant to work in 2D space. Maybe you could try using the Label3D node which was meant to work in 3D space.

  • @aflyingcougar8290
    @aflyingcougar8290 Před 8 měsíci

    Great vid! I had to modify the "player" var to be set during the "_process()" function in the InteractionManager. For some reason whenever trying to set "player" like you showed in the video, it would try to get the node before it was defined, leading to null reference errors.
    My line was identical to yours (@onready var player = get_tree().get_first_node_in_group("player"), but it would be set to null because the player node did not exist when it was trying to set the variable. Not sure why my situation was different, but seems to work okay with my modification.

    • @DashNothing
      @DashNothing  Před 8 měsíci +1

      Maybe some other script creates the player at the start of the game? Unlikely, but I can't think of anything else.
      Godot creates nodes bottom up, so autoloaded nodes should be created last, unless I'm mistaken. By the time they're created, all other nodes should be available.
      If you didn't already, before setting it in _proccess() I would put an if to check if the player is already not null. Just so you don't set it over and over again.

    • @Lupin_VA
      @Lupin_VA Před 7 měsíci +1

      mines having the same issue can you possibly tell me4 how you called it cus for me var player = get_tree().get_first_node_in_group("Player") doesnt work

    • @aflyingcougar8290
      @aflyingcougar8290 Před 7 měsíci +2

      @@Lupin_VA, sure! Instead of declaring the player variable on line 4 (3:42 in video), i moved this line inside of the _process(delta) function. Here are the first lines of my _process(delta) function:
      func _process(delta):
      if activeAreas.size() > 0 && canInteract:
      if player == null:
      player = get_tree().get_first_node_in_group("player")
      ...
      Notice i also removed the @onready decorator. For me, this change makes sure the player is never null and also does not get called more times than necessary.

    • @donuttsprinkles
      @donuttsprinkles Před 7 měsíci

      @@aflyingcougar8290, thanks so much! i had this same problem

  • @6xten
    @6xten Před 9 měsíci

    Do I need to connect _body_entered and _exited and write out that bit of code every time I want to make an object interactible, or am I doing something wrong? It doesn't seem to want to inherit that.

    • @DashNothing
      @DashNothing  Před 9 měsíci

      No, the signals are connected in the interaction area script. All you have to do is add the interaction area to an object you want to interact with and override it's interact callable. The interaction area + InteractionManager will handle the rest for you!

  • @owps2121
    @owps2121 Před 6 měsíci +1

    Hello there! Thanks a lot for the tutorial! I've spent a couple of hours rewatching the videos and fixing some errors, BUT there's still one. Everything works fine, but the text box doesn't disappear after the dialog and keeps hanging... Seeking for help :) Thanks!

    • @DashNothing
      @DashNothing  Před 6 měsíci +1

      I assume you followed my dialog system tjtorial, in which case the problem must be in the dialog amanger script. It the _unhandled_input function theres a line textbox.queue_free() at 10:09 in that video. Does this not destroy your textbox? It should destroy it after every line and finally at the end.

    • @owps2121
      @owps2121 Před 6 měsíci +1

      It doesn't! Looked through the script again and can see no mistakes (but mb I'm blind). That part looks like this:
      func _unhandled_input(event):
      if (
      event.is_action_pressed("advance_dialog") &&
      is_dialog_active &&
      can_advance_line
      ):
      text_box.queue_free()

    • @owps2121
      @owps2121 Před 6 měsíci +1

      I GOT IT. I didn't assign the "advance_dialog" input... Now it works perfectly. Thank you! You're doing a great job and helped me a lot.@@DashNothing

    • @DashNothing
      @DashNothing  Před 6 měsíci +1

      @@owps2121 Yeah, that looks right. Can you check if it gets deleted after a line finishes, but before the whole dialog is over? You should never have more than one text box in the scene.
      You can check it by playing the game and clicking on the remote tab in the scene tree. There you can find the dialog manager and a single text box should be its child at most.

  • @AnnieClaudeT1
    @AnnieClaudeT1 Před 2 měsíci

    Hello, I am a bit confused what to do at 9:20 and in ''Cute and Simple dialog box'': It seems both script for NPC is different(10.45 other video)..So I am more confuse which NPC script to take in order to make the interaction and dialog work... Is it possible to share here what to write exactly? (Also, line 20 at 9:20 seems to be cut at the end, no idea what to write) (I am really a newbie in writing code)
    My other question is about the label: it doesn't show up above the NPC, I don't know why! I tried a few things as some peeps said below but no luck. I also have this message warning next to Label "Changing the Z index of a control only affects the drawing order, not the input even handling order"
    Thanks!

    • @DashNothing
      @DashNothing  Před 2 měsíci

      Use the NPc script from this video as a reference. I don't suggest copying the code that wasn't narrated in the video line by line - these sections just show you an example of how you can use the system.
      As for the label not showing up, I can't tell you why without seeing your code, but the warning you get about the z_index is not a problem and you can ignore that.

    • @AnnieClaudeT1
      @AnnieClaudeT1 Před 2 měsíci

      @@DashNothing Okay, I see thank you!
      As for the label, here's my script from InteractionManager:
      extends Node2D
      @onready var player = get_tree().get_first_node_in_group("player")
      @onready var label = $Label
      const base_text = "(E) to"
      var active_areas = []
      var can_interact = true
      func register_area(area: InteractionArea):
      active_areas.push_back(area)

      func unregister_area(area: InteractionArea):
      var index = active_areas.find(area)
      if index != -1:
      active_areas.remove_at(index)


      func _process(delta):
      if active_areas.size() > 0 && can_interact:
      active_areas.sort_custom(_sort_by_distance_to_player)
      label.text = base_text + active_areas[0].action_name
      label.global_position = active_areas[0].global_position
      label.global_position.y -= 36
      label.global_position.x = label.size.x / 2
      label.show()
      else:
      label.hide()

      func _sort_by_distance_to_player(area1, area2):
      var area1_to_player = player.global_position.distance_to(area1.global_position)
      var area2_to_player = player.global_position.distance_to(area2.global_position)
      return area1_to_player < area2_to_player

      func _input(event):
      if event.is_action_pressed("interact") && can_interact:
      if active_areas.size() > 0:
      can_interact = false
      label.hide()

      await active_areas[0].interact.call()

      can_interact = true

  • @looves132009
    @looves132009 Před 10 měsíci

    How would make it so that the label stop showing once input is pressed, but returns when you exit and reenter the interactable area?

    • @DashNothing
      @DashNothing  Před 10 měsíci +1

      In the interaction manager you would make a var show_label which you would set to false when an interaction happens.
      In the register area function you would set show_label to true.
      In the process function you would check if show_label is true before displaying the label.
      This is off the top of my head, but I'm pretty sure it would work.

  • @HammHammVT
    @HammHammVT Před 7 měsíci

    Great tutorial!
    At first I was having trouble with the text appearing/disappearing until I realized that the "active_areas.size() > x" counts any CollisionShape2D node in its range so I needed to change it from "0" to "1" (at least in my code). My player character's CollisionShape and the Interactable Object's CollisionShape.
    My only current issue is now my "E to Interact" key press works even OUTSIDE of the Interaction Area. Any advice for that?

    • @DashNothing
      @DashNothing  Před 7 měsíci +1

      Thank you!
      The interaction area colission mask should be set to player only (1:02). This way it will not detect any other object.
      Of course, with this you should change the 1 back to a 0.

    • @HammHammVT
      @HammHammVT Před 7 měsíci

      @@DashNothing ah, I'm new to Layers and Masks. Will take another look back.

  • @supergames6696
    @supergames6696 Před 6 měsíci

    I'm having trouble, it seems that my interaction area is not detecting my player. I don't know if it has to do something with the play group or the collision layer + mask on the interaction area? I've checked and the Collision layer on my player is the same as mask on the interection thing. Which is set to "1". Then I am not sure about the group thing you mentioned, because am I supposed to have the entire 2D node in it and player node also named player? Or is it only supposed to be the player node by it self and the naming of the player node does not matter?

    • @DashNothing
      @DashNothing  Před 6 měsíci

      Your collission layer/mask setup is correct. As for the group, the second option is right.
      - ONLY the player node should be in tbe "player" group
      - it doesn't matter what the player scene is called, as long as it's in the "player" group it will work
      Let me know if you need further help!

    • @supergames6696
      @supergames6696 Před 6 měsíci

      Yeah so, turns out that that wasn't the problem, I tried multiple debugging points whilst using print to determine what's being run. It turns out that _process in InteractionManager is always doing the label.hide() function, no matter if I enter a interaction area or not, it just won't add the area to the array. And as a matter of fact, it does not register the player entering it at all. Thank you for your help btw, I am a total newbie and I appriciate the help with your tutorials!@@DashNothing

    • @DashNothing
      @DashNothing  Před 6 měsíci

      @@supergames6696 Okay, so it seems the problem is with the interaction area. If collision mask is set to player's collision layer, also check these:
      - does the area have monitoring turned on? It should by default and it's needed to detect when objects enter
      - does the area have a collision shape child with a big enough area so that the player can enter it?
      And it's no problem, I'm happy to help. You are doing very well in debugging this issue, especially for a newbie.

  • @Revilo2242
    @Revilo2242 Před 4 měsíci

    hey ive copied the tutoriail and its working for the most part i just cant get the text to appear becuase i get a warning and a crash saying "Invalid get index 'Y' (on base: 'Vector2')" what have i done wrong and how do i fix it

  • @akon1189
    @akon1189 Před 10 měsíci

    There are a lot of codes and scripts missing in this video, like dialogue script , text box script and other

    • @DashNothing
      @DashNothing  Před 10 měsíci +1

      Yes, those are not relevant to the topic of the video. But if you want to check out how the dialog system is made, you can do so here: czcams.com/video/1DRy5An_6DU/video.htmlsi=UgbdeEQOgOv1UPwv

  • @Lumayoshi
    @Lumayoshi Před 4 měsíci

    Great video! Just for some reason, the system doesn't work for me, unless I manually connect the InteractionArea to itself every time I add it to a node. Maybe I did something wrong, but if it's a version issue, hopefully this also helps somebody out.

    • @DashNothing
      @DashNothing  Před 4 měsíci +1

      Maybe you're adding the node with the add node button (plus icon) and not with the instance scene button (link icon).

    • @Lumayoshi
      @Lumayoshi Před 4 měsíci

      @@DashNothing Oh wow, that is exactly what I did, I'm really learning a lot from this, thanks a lot! 😄

  • @xpotau
    @xpotau Před 10 měsíci

    Hey thanks for sharing this, very useful! I tried implementing this in c# last night and I struggle to get the callable propagation called. I define the callable in InteractionArea like this "public Callable interact;". Then on the object i want to interact with i assign the callable like this "interactionArea.interact = new Callable(this, nameof(OnInteract));". But the OnInteract is not triggered. I think it has to do with how the callable is defined in InteractionArea nut not initialized properly maybe, but not sure how to implement this overridable callable from GDScript to C#. Any Godot c# dev have an idea?