For anyone wondering, I tried this with the corresponding 3D nodes (because I wanted a basic interaction system in my 3D game) and it worked too!! Thank you so much for this tutorial!!
This is amazing! There is a surprising lack of good 2D interaction tutorials on TH-cam, so I had a hard time finding one that worked. Thank you so much for this tutorial! 😄
This was the best interaction tutorial by far. Followed a few others and some didn't explain every step, and some didn't seem to work very good. This one worked superb!
Great tutorial to make the interaction part of a game to work. Fast and efficient, and nicely implemented into previous coding that you might have for movement and others. Still tinkering now about how to make dialogue layouts to appear instead of printing the text, but this is an amazing start that helped me boost interactivity in less than 10 minutes of working with it. Thanks a lot for your time and experience!
cool video, It helps a lot. As a player, it is super annoying when several interactive objects are close together and you fail to interact with the specific one you want. A simple solution would be to send the interaction at the end of all_interactions when you interact, so you can loop around all interactions available at a point. a UI clicable list of interactions that appears when you maintain space bar would be better but much more work.
Thank you sooooo much for this tutorial! I spent a good chunk of my day trying and failing to get a dialogue box working, but stumbled across this and managed to get it working flawlessly very quickly, even if just to print text out into my console. Everything is so very well explained, I definitely feel like I learned a lot about Godot scripting from this video. Cheers!
One nice feature is to add a cycle based on mouse wheel for going between the interactions, so you can select which one you want. Just replace the 0 index with a var which you increase or decrease on mouse wheel inputs, just make sure to accommodate for edge cases.
I like this system. It's pretty clean! And on top of that, I learnt a couple of things in GDScript and Godot I hadn't yet searched for (like exposing variables in the engine ui to modify them in 2D view, or the entire layer/monitoring/monitorable system...) I think the only thing I'm going to change is to get all the interaction code out of the player_character script and just reference it, 'cause I don't like having one script doing everything. Thank you very much for that tutorial.
Thanks for the feedback! :) Yeah there are definitely some in-efficient parts to this system, but I think the base for actually detecting the interactables is pretty solid. But yes, it is good practice to move the interaction event scripts outside of the player script, I just haven't gotten around to remaking this system yet :)
Wonderful tutorial! Easy to follow, well documented! Quick question: If I wanted the Interact Value to be a function from a scene/script, i.e. a Control Node for something like a Cooking/Crafting page, how should I go about that?
Thank you! Well honestly I've been wanting to redo this video, since the method shown is actually pretty inefficient, but basically you'll want to move all the logic to each interactions own script (instead of putting it all in the player script). I know there are a lot of other good tutorials for doing this, so I would check out a more modular system; or if you want I could help you if ya ping me in the discord server 👍
Thank you for your work! But please, make your code more readable on FullHD monitors. Editor -> Editor Settings -> Interface Editor -> Code Font Size pls set font larger to 20 or 22 just for video watching purposes
Yes, sorry about this! I normally zoom the code for tutorials, but forgot to do it this time since I revert back while editing my own stuff. I'll try to remember this in the future, thanks for the input :)
This was honestly really helpful! I may be dumb for trying to make a 2d game within the time span of a college winter break, but I really want to make a finished game and see how it does. You probably mentioned this and I over looked it but is there a way to change the size of the collisionshape for different interactables? I ask because I may use this for the entrance of a dungeon but also may want it to be used on items that can be picked up.
For anyone interested I thought this would be a neat feature to include as well. This is how I went about it. Added a new export in addition to the label, type, value etc. to the Interactable script for the radius of the interaction zone, as well as a reference to the CollisionShape2D like so @export var interact_label = "none" @export var interact_type = "none" @export var interact_value = "none" ## Export for custom interaction zone radius @export var interact_radius = 50 ## Reference to the attached CollisionShape2D node @onready var collision_box = $CollisionShape2D Then in the ready function I modified the radius of the collision box to the provided value of the radius func _ready(): collision_box.shape.radius = interact_radius This should allow you to easily configure and tweak the radius while providing whatever default value makes the most sense.
hey Queble, great tutorial! One question though, how would I use this to change a scene on interaction? My code currently is func execute_interaction(): if all_interactions: var cur_interaction = all_interactions[0] match cur_interaction.interact_type: "print_text" : print(cur_interaction.interact_value) "signal" : emit_signal(cur_interaction.interact_value) "travel" : get_tree().change_scene_to_file((cur_interaction.interact_value).tscn) but the "travel" part isn't travelling. I've tried a few different ways to write this, but i'm fairly new to Godot (and programming in general) so I can't quite tell what I'm doing wrong. I'm fairly certain I could just use a signal that when detected could change scenes, but I don't really wanna do that. Thanks in advance!
figured it out after i got more experience in godot. for anyone wondering, you can do this: "travel" : get_tree().change_scene_to_file(str(cur_interaction.interact_value)) just make sure you have the name of the scene you want to change to in the interact value.
@@Sorry-Sir_butNah it emits the signal in the interaction value, but only if you've got it connected to the player i think. it works for me, since i use a lot of signals to do stuff 'cause im bad, but there are most likely more efficient ways to do a lot of the stuff i use signals for.
@@ClarenceGooseman I’m trying to make a system where I can pick something up I’m just now sure how I would go about connecting it to the interaction area if have to keep typing it inside the player script. It seems like it’ll just take to much space if I added 50 different items.
yes I will absolutely subscribe. Thank you for helping me get past this hurdle so I can finally go to bed 😭 EDIT: Actually I need some help wrapping my brain around this. Could someone help me figure out how, with this setup, I'd trigger an event in an NPC's script with this? I know I'm like just on the edge of the knowledge I'd need to figure this out, but I'm still too new to have that intuition 😅
Just a heads up for anyone who ran into this issue as well. I was getting this error: Node not found: "Interaction Components/InteractLabel" (relative to "/root/Main/player") when using $"Interaction Components/InteractLabel" Turns out (at least with Godot 4.2) that I needed to remove the space between Interaction Components in my path reference. $InteractionComponents/InteractLabel works both with and without being encased in double quotes.
I really enjoy your tutorials...simply your tone of voice is reassuring for newcomers like myself That said, I have what I assume is a self-inflicted issue. I get an error on the following code: func update_interactions(): if all_interactions: interactLabel.text = all_interactions[0].interact_label else: interactLabel.text = "" error reads: invalid set index 'text' (on base: "string") with value of type "string"
Thank you so much for the video! Just wondering how I could implement animations with this system, for instance interacting with a door and playing its open animation. I'm very new to Godot so any help would be great :)
Hey! Quick question: How would I go about to add collision between the player and the interactArea? I tried adding masks to both of them but that isnt working.
Very cool! Is there a way to save both the Interactable class and the InteractionArea nodes to be used in other projects? Sort of like a template or something. (I'm very new to Godot, so unfamiliar with any cross-project workflows)
Yes, you could potentially just save the scenes, and use them between projects, but you may want to optimize it for this a bit better by connecting the signals through code, and removing the interaction component from the player script.
Would you possibly be able to do a tutorial on being able to have a companion follow the player? I haven't been able to find anything on the topic anywhere
Oh ok nice! Is the companion a real world object, or just like an overlay? I was gonna mess around with something like that today, but instead use a pathfinding script, and then just offset it to the player
@@queblegamedevelopment4143 I found something on making it in the world scene, but i have plans to be able to interact with the companion as well, would having it just a AnimatedSprite2D mess with that being a feature?
Glad to hear! Looking back at my code, it looks like there's and update_interactions function that will set the text to a blank string if there isn't an interaction in the array. If you call that after removing the interaction, it should update :)
Thank you so much for the reply! :) So in the update_interactions function how would that look like? I would call the update_interactions after the text is set to blank? @@queblegamedevelopment4143
I get an error that seems to come from what's in line 12 in your player script at 9:42, it's searching through the world scene for some reason and nothing i've tried so far has been able to shed light on the issue. I'm new to game development so i don't even know how to start figuring this out. for whatever reason it can't find the label node in Interaction Components, but i've done everything just as shown and it's just... not working. and this is also causing the debug game to crash, which i also don't understand.
Watching the video and reading a few comments, to keep the spirit of your system but make it more modular couldn't you simply swap the monitoring/monitorable and then put all the code inside the interactable node? Not sure how much resources are taken up by nodes monitoring, obviously a few would not matter but what about once you start getting into more and more, like in the hundreds.
Yes, I've actually been working on an updated system for this (since it's obviously not modular), but in the mean time I've been helping people optimize it better in the discord server. Hoping to get an updated video out soon :)
I tried this with 3D (as what I'm trying to do is in 3D), and got it all to work except for the actual text popping up. What I'm aiming for is for it to display that text (example is the "Yay it worked" value) in the game itself. Basically, nothing happened when I pressed the interaction key in the debugging attempt. Text appeared when I got close to it (as intended), but the interaction key just doesn't work; nothing happens when I press it. There are no errors popping up in the script, so I don't even know how or where to make a change so that the interaction key will actually work. Can anyone help me?
@@queblegamedevelopment4143 I had this issue but solved it by removing the match function and just writing print(cur_interaction.interact_value) Is this going to effect anything later if I try to implement the code into something? As far as I can see I'm already gaining access to all the data I need through the interaction, but I'm a newb and I don't know what match is used for. It's worth mentioning I'm in Godot 4.1.1
@queblegamedevelopment4143 I figured it out, I was using a body signal instead of an area signal. My bad. I'm trying to use it to set up signs in my game, but I can't just attach the scene to a new scene so I'm trying to work around that, but thx for the tutorial. I would have not made it this far without it
You can replace the print() code with a desired event. If you want it to trigger a dialogue system for example, you could call a method on a dialogue component you create separately
@@queblegamedevelopment4143 i dont understand. how can i have diffrent types of interactions then. do i have to do everything again? i want to have objs i can "pick-up" to get points. but i also want a door at the end that you have to interact with to end the lvl.
Looking for a chill game dev community?
Join our Discord server here: discord.gg/J7mqN4sV :)
For those as myself who might wonder, you can see colision shapes if you turn on the menu options : Debug -> Visible colision shapes
For anyone wondering, I tried this with the corresponding 3D nodes (because I wanted a basic interaction system in my 3D game) and it worked too!!
Thank you so much for this tutorial!!
appreciate this comment a lot :) was looking exactly for this info
This is amazing! There is a surprising lack of good 2D interaction tutorials on TH-cam, so I had a hard time finding one that worked.
Thank you so much for this tutorial! 😄
This was the best interaction tutorial by far.
Followed a few others and some didn't explain every step, and some didn't seem to work very good.
This one worked superb!
Great tutorial to make the interaction part of a game to work. Fast and efficient, and nicely implemented into previous coding that you might have for movement and others. Still tinkering now about how to make dialogue layouts to appear instead of printing the text, but this is an amazing start that helped me boost interactivity in less than 10 minutes of working with it. Thanks a lot for your time and experience!
cool video, It helps a lot. As a player, it is super annoying when several interactive objects are close together and you fail to interact with the specific one you want. A simple solution would be to send the interaction at the end of all_interactions when you interact, so you can loop around all interactions available at a point. a UI clicable list of interactions that appears when you maintain space bar would be better but much more work.
Thank you sooooo much for this tutorial! I spent a good chunk of my day trying and failing to get a dialogue box working, but stumbled across this and managed to get it working flawlessly very quickly, even if just to print text out into my console. Everything is so very well explained, I definitely feel like I learned a lot about Godot scripting from this video. Cheers!
Glad it helped!
Amazing tutorial. Dozens of others failed to do this same concept as clearly, quickly and cohesively as you. Good job!
One nice feature is to add a cycle based on mouse wheel for going between the interactions, so you can select which one you want. Just replace the 0 index with a var which you increase or decrease on mouse wheel inputs, just make sure to accommodate for edge cases.
Holy crap I think this is exactly what I need! Thanks for the video!!
I like this system. It's pretty clean! And on top of that, I learnt a couple of things in GDScript and Godot I hadn't yet searched for (like exposing variables in the engine ui to modify them in 2D view, or the entire layer/monitoring/monitorable system...)
I think the only thing I'm going to change is to get all the interaction code out of the player_character script and just reference it, 'cause I don't like having one script doing everything.
Thank you very much for that tutorial.
Thanks for the feedback! :)
Yeah there are definitely some in-efficient parts to this system, but I think the base for actually detecting the interactables is pretty solid.
But yes, it is good practice to move the interaction event scripts outside of the player script, I just haven't gotten around to remaking this system yet :)
@@queblegamedevelopment4143 I think you have some great tutorials on your channel. Some of the most helpful and concise I've found.
this worked great for me, thank you for the easy to follow tutorial!
Wonderful tutorial! Easy to follow, well documented!
Quick question:
If I wanted the Interact Value to be a function from a scene/script, i.e. a Control Node for something like a Cooking/Crafting page, how should I go about that?
Thank you!
Well honestly I've been wanting to redo this video, since the method shown is actually pretty inefficient, but basically you'll want to move all the logic to each interactions own script (instead of putting it all in the player script).
I know there are a lot of other good tutorials for doing this, so I would check out a more modular system; or if you want I could help you if ya ping me in the discord server 👍
Thank you for your work! But please, make your code more readable on FullHD monitors.
Editor -> Editor Settings -> Interface Editor -> Code Font Size pls set font larger to 20 or 22 just for video watching purposes
Yes, sorry about this!
I normally zoom the code for tutorials, but forgot to do it this time since I revert back while editing my own stuff.
I'll try to remember this in the future, thanks for the input :)
This was honestly really helpful! I may be dumb for trying to make a 2d game within the time span of a college winter break, but I really want to make a finished game and see how it does. You probably mentioned this and I over looked it but is there a way to change the size of the collisionshape for different interactables? I ask because I may use this for the entrance of a dungeon but also may want it to be used on items that can be picked up.
For anyone interested I thought this would be a neat feature to include as well. This is how I went about it.
Added a new export in addition to the label, type, value etc. to the Interactable script for the radius of the interaction zone, as well as a reference to the CollisionShape2D like so
@export var interact_label = "none"
@export var interact_type = "none"
@export var interact_value = "none"
## Export for custom interaction zone radius
@export var interact_radius = 50
## Reference to the attached CollisionShape2D node
@onready var collision_box = $CollisionShape2D
Then in the ready function I modified the radius of the collision box to the provided value of the radius
func _ready():
collision_box.shape.radius = interact_radius
This should allow you to easily configure and tweak the radius while providing whatever default value makes the most sense.
Finally got my dialog box and side images to show up.
Great tutorial, and explained in detailed. Subbed!
hey Queble, great tutorial! One question though, how would I use this to change a scene on interaction? My code currently is
func execute_interaction():
if all_interactions:
var cur_interaction = all_interactions[0]
match cur_interaction.interact_type:
"print_text" : print(cur_interaction.interact_value)
"signal" : emit_signal(cur_interaction.interact_value)
"travel" : get_tree().change_scene_to_file((cur_interaction.interact_value).tscn)
but the "travel" part isn't travelling. I've tried a few different ways to write this, but i'm fairly new to Godot (and programming in general) so I can't quite tell what I'm doing wrong. I'm fairly certain I could just use a signal that when detected could change scenes, but I don't really wanna do that. Thanks in advance!
figured it out after i got more experience in godot. for anyone wondering, you can do this:
"travel" : get_tree().change_scene_to_file(str(cur_interaction.interact_value))
just make sure you have the name of the scene you want to change to in the interact value.
@@ClarenceGooseman chad
@@ClarenceGoosemanwhat’s the signal do for you?
@@Sorry-Sir_butNah it emits the signal in the interaction value, but only if you've got it connected to the player i think. it works for me, since i use a lot of signals to do stuff 'cause im bad, but there are most likely more efficient ways to do a lot of the stuff i use signals for.
@@ClarenceGooseman I’m trying to make a system where I can pick something up I’m just now sure how I would go about connecting it to the interaction area if have to keep typing it inside the player script. It seems like it’ll just take to much space if I added 50 different items.
yes I will absolutely subscribe. Thank you for helping me get past this hurdle so I can finally go to bed 😭
EDIT: Actually I need some help wrapping my brain around this. Could someone help me figure out how, with this setup, I'd trigger an event in an NPC's script with this? I know I'm like just on the edge of the knowledge I'd need to figure this out, but I'm still too new to have that intuition 😅
THIS HELPED A LOT OMGGG THANKYOUUU!!!!!
Just a heads up for anyone who ran into this issue as well. I was getting this error:
Node not found: "Interaction Components/InteractLabel" (relative to "/root/Main/player") when using $"Interaction Components/InteractLabel"
Turns out (at least with Godot 4.2) that I needed to remove the space between Interaction Components in my path reference.
$InteractionComponents/InteractLabel works both with and without being encased in double quotes.
I really enjoy your tutorials...simply your tone of voice is reassuring for newcomers like myself
That said, I have what I assume is a self-inflicted issue. I get an error on the following code:
func update_interactions():
if all_interactions:
interactLabel.text = all_interactions[0].interact_label
else:
interactLabel.text = ""
error reads: invalid set index 'text' (on base: "string") with value of type "string"
Thank you so much for the video! Just wondering how I could implement animations with this system, for instance interacting with a door and playing its open animation. I'm very new to Godot so any help would be great :)
Great tutorial. Thanks.
Thanks man, that was super helpful
Great job! Very helpful! Could you do a version for 3d?
PARABENS PELO TRABALHO NOTA 100000000000A/10
Hey! Quick question: How would I go about to add collision between the player and the interactArea? I tried adding masks to both of them but that isnt working.
Very cool! Is there a way to save both the Interactable class and the InteractionArea nodes to be used in other projects?
Sort of like a template or something. (I'm very new to Godot, so unfamiliar with any cross-project workflows)
Yes, you could potentially just save the scenes, and use them between projects, but you may want to optimize it for this a bit better by connecting the signals through code, and removing the interaction component from the player script.
@@queblegamedevelopment4143 Nice, thank you so much for the help :)
Thanks for the video, learnt some useful info
Would you ever consider doing a 3D version?
Would this work similar in 3D, but with an Area3d node instead?
Yes, it should work correctly if you switch all the 2D components to 3D
hey, by 10:45 when i run the scene it shows : invalid get index 'interact_label' (on base: 'int'). How can I fix it?
i follow exact step-by-step instructions but my text is not updated :(
please help
Would you possibly be able to do a tutorial on being able to have a companion follow the player? I haven't been able to find anything on the topic anywhere
Sure, I'll add it to the list! (although it might be a bit until I get to it :/ )
@@queblegamedevelopment4143 I figured it out via lerp, now just figuring out how to get the animations to work lmao
Oh ok nice! Is the companion a real world object, or just like an overlay? I was gonna mess around with something like that today, but instead use a pathfinding script, and then just offset it to the player
@@queblegamedevelopment4143 I found something on making it in the world scene, but i have plans to be able to interact with the companion as well, would having it just a AnimatedSprite2D mess with that being a feature?
This video saved my game!! It's so helpful. But Is there a way that when picking up an item and you interact with it, the words go away?
Glad to hear!
Looking back at my code, it looks like there's and update_interactions function that will set the text to a blank string if there isn't an interaction in the array.
If you call that after removing the interaction, it should update :)
Thank you so much for the reply! :) So in the update_interactions function how would that look like? I would call the update_interactions after the text is set to blank? @@queblegamedevelopment4143
This is a good tutorial, but I would highly suggest you add in the title that this is Godot 4.
Thanks a lot :) It's very helpful to me.
sweet tutorial, thanks! now if only i could figure out how to delete the object which I interacted with afterwards..
cur_interaction.queue_free()
I get an error that seems to come from what's in line 12 in your player script at 9:42, it's searching through the world scene for some reason and nothing i've tried so far has been able to shed light on the issue. I'm new to game development so i don't even know how to start figuring this out. for whatever reason it can't find the label node in Interaction Components, but i've done everything just as shown and it's just... not working. and this is also causing the debug game to crash, which i also don't understand.
Hmm ok, you could join the discord server and I'll try to help ya out :)
Watching the video and reading a few comments, to keep the spirit of your system but make it more modular couldn't you simply swap the monitoring/monitorable and then put all the code inside the interactable node? Not sure how much resources are taken up by nodes monitoring, obviously a few would not matter but what about once you start getting into more and more, like in the hundreds.
Yes, I've actually been working on an updated system for this (since it's obviously not modular), but in the mean time I've been helping people optimize it better in the discord server.
Hoping to get an updated video out soon :)
Damn, I wish I had this back in Senior Seminar a few years back. My interaction code for chests and signs on my tilemap was janky.
I tried this with 3D (as what I'm trying to do is in 3D), and got it all to work except for the actual text popping up. What I'm aiming for is for it to display that text (example is the "Yay it worked" value) in the game itself.
Basically, nothing happened when I pressed the interaction key in the debugging attempt. Text appeared when I got close to it (as intended), but the interaction key just doesn't work; nothing happens when I press it. There are no errors popping up in the script, so I don't even know how or where to make a change so that the interaction key will actually work.
Can anyone help me?
Hey why don't you join the discord? I'll try to help out as soon as I'm by my PC :)
@@queblegamedevelopment4143 I had this issue but solved it by removing the match function and just writing print(cur_interaction.interact_value)
Is this going to effect anything later if I try to implement the code into something?
As far as I can see I'm already gaining access to all the data I need through the interaction, but I'm a newb and I don't know what match is used for.
It's worth mentioning I'm in Godot 4.1.1
when i set up a new instance of the interact area, no text appears and i cant interact with it :(
Hmm I forgot how this system works since it was so long ago... Would you mind joining the discord server and I can help you out? :)
@queblegamedevelopment4143 I figured it out, I was using a body signal instead of an area signal. My bad. I'm trying to use it to set up signs in my game, but I can't just attach the scene to a new scene so I'm trying to work around that, but thx for the tutorial. I would have not made it this far without it
Was beating my head on this - helped me a ton. Keep making boring videos, my dude.
interactions... like collisions?
YES!!
no no i think it's like collisions with state machine combo @@teabow. man i still can't figure out how to make a boid.
Only bit I don't get is how to make it appear in game instead of printed in debugger
You can replace the print() code with a desired event.
If you want it to trigger a dialogue system for example, you could call a method on a dialogue component you create separately
@@queblegamedevelopment4143 cheers mate. Very good vid btw
@@queblegamedevelopment4143 i dont understand. how can i have diffrent types of interactions then. do i have to do everything again? i want to have objs i can "pick-up" to get points. but i also want a door at the end that you have to interact with to end the lvl.
export doesn't work, I hate this stupid thing
Hmm, would you send the line of code that isn't working?
I'll see if I can fix it