Great tutorial, I do have one problem and it is nothing that anyone else is going to care about, but I still feel it is worth noting. Instead of teaching people to use a built in Godot function to rotate and place the bullet spawners, I would have preferred the trigonometry done out in long form so that information would be applicable across any engine, regardless of API. A brief description of how to use sine and cosine to calculate points in a circle would have been slightly less consumable, but infinitely more informative. Keep up the great work, you earned a sub. It's also worth mentioning the benefit that object pooling may have on this sort of system vs. instantiation.
I just did it in Godot 4 - It worked great. Really happy with this tutorial. Just needed to change instance to instantiate when creating the bullet and I did my global vars a little different
@@massiveCheese I worked it out. Because I use a if Input its creating new spawn points every time in the same place so it spawns more and more bullets every time you shoot. This can be fixed by using a final for loop where you queue free the spawn points and re create them the next time you shoot.
@@TheTeyKiller It was a while back. I was thinking I must have done them differently because of changes between godot 3 and 4 but I'm not sure that's true. I have: @export var rotate_speed: int = 30 for example, instead of it being a const.
This is very nice ! I really loved the mathematical explanations as a lot of people just tend to skip them or simply explain them without any illustration. You on the other hand explained everything with grace. Looking forward to more tutorials from you..
Choosing the "No comment" instead of "Default" will create scripts with no comments and when creating new script, Godot will remember your previous choice. I am yet to see a video where it is used. Seeing everyone delete the comments after the creating scripts every time made me write this comment... Great video BTW.
6:44 Just a tip about adding stuff to the root. Whenever you instance object you should realistically be adding it to the last child of the root. Its fine for small projects but I found out the hard way working on a large project with loading screens and reparenting. i.e var root = get_tree().get_root() var current_scene = root.get_child(root.get_child_count()-1) current_scene.add_child(bullet)
@@DankMemes-xq2xm they stick around if you dont remove them when switching scenes. Most time stuff we add we usually remove before like bullets for example so we don't notice. get_tree(). get_root() is the top most node for the entire project not the current scene. I may be wrong though ill double check
@@Chevifier Ohh, now that I think about it I don't think I add to the root either, I just add stuff as a child directly below the scene, or in a ySort below the scene.
Hey there! Thank you for the video. I am making a bullet hell game rn. I want to point out that having a timer for each bullet might not be the optimal way. One central timer is in fact enough as long as you connect it to each bullet and run a count down function in each bullet. Another little trick to save you two lines of code is to put queue_free directly when connecting on_killTimer_timeout by going into the advanced options. :)
UuuhhhMmmaaazziiing! Exactly what I needed for a number of projects I want to do! I enjoyed your explanations and look forward to future videos. Are you signed up for the bullet hell jam?
Oh goodness this was the most relaxing tutorial ever, I could feel the stress melting away. :) I really like the pixel art on your logo, was that your own work?
Haha it's great that this video helped you relax, I suppose those patterns are almost a bit hypnotic 😂 And yup my logo is my own work, glad you like it!
@@bitbirdy Wow, that's really top draw work on the pixel art, hats off to you. Genuinely impressed. I do 3d so I can kinda go off a reference image in blender but with pixel art there's no getting around the need for talent (that's the step in the creative process I usually skip...) Well I look forward your next stress therapy video, oops, I mean godot tutorial. ;)
I haven't tested the performance, but one of the Godot developers tweeted that obejct pooling doesn't give much benefit in Godot, so constantly instantiating and deleting scenes should be fine twitter.com/reduzio/status/1073284242086551552 . If you find that it does affect performance, implementing a bullet pool is pretty easy too.
I also have a blog post about how to use multithreading to optimize many moving physics bodies which might be helpful! bitbirdy.dev/posts/godot-1000-bodies/
add_child and then queue_free() is totally ruin the engine to process the task. using pool system where load all the data then use em back is saving more energy. i dont say any of bad using this method but specially for you working on mobile. i think is, way better using ( object pooling system ) fuc# with exploration or experiment about knowing how do we spend the time to just see the optimization work well with kind of this code. but the fact dont do simple thing always save your engine workload! thank you anyway of the tutoral :D keep the good work!!
Thank you for the tutorial! This helped me so much. How does transform.x work when you use it in the Bullet.gd code? I get that position += speed * delta will move the object in the speed direction, but how does transform.x work to make it travel like relative to the angle?
transform.x is the "forward" direction of any node2d, so the bullet is basically going in whatever direction it's facing. At 6:58 I set the bullet's rotation which determines the bullet's forward direction.
It really depends on what kind of game you're making and how you want them to spawn. The official "Your first game" tutorai in the Godot Engine docs has a good example of spawning enemies randomly at the edges of the screen docs.godotengine.org/en/stable/getting_started/step_by_step/your_first_game.html
tried again, now the rotator doesn't follow the enemy when the enemy is instanced in the world, and the bullets won't move, either the people in this comment section are bots or this method is really old, anyway, wouldn't recommend to people
just go learn the basic for godot , then come back... it works because we know how to actually use the algorithm there's people here who uses completely diffrent engine and have it working. So scaled down your project save this video and comeback when u have the basic understanding of the engine. Goodluck
I LOVE IT WHEN PPL USE PAINT TO EXPLAIN STUFF! MADE MY DAY!
LOL good to know
WAZAZAZAZAZZAZA,AZAIAIAIAIAIAIAIAIIAAIAIAIAIAIAIAIAIIAIAIAIAIAIAIAIAAIIAIAIAIAIAIAIAIAIAIAI🚶♂️🚶🚶♀️🚶♂️🚶🚶♀️🚶♀️🚶♂️🚶🚶♂️🚶♀️🚶♂️🚶🚶🚶♂️🚶♀️🚶♂️🚶🚶♂️
Great tutorial, I do have one problem and it is nothing that anyone else is going to care about, but I still feel it is worth noting. Instead of teaching people to use a built in Godot function to rotate and place the bullet spawners, I would have preferred the trigonometry done out in long form so that information would be applicable across any engine, regardless of API. A brief description of how to use sine and cosine to calculate points in a circle would have been slightly less consumable, but infinitely more informative. Keep up the great work, you earned a sub. It's also worth mentioning the benefit that object pooling may have on this sort of system vs. instantiation.
I just did it in Godot 4 - It worked great. Really happy with this tutorial. Just needed to change instance to instantiate when creating the bullet and I did my global vars a little different
I did the same but I'm using it for a player attack and so it calls when you shoot but after a couple of shots it gets very laggy. I don't know why.
@@DoubleDotStudio Not sure what to try other starting the profiler in the debugging tools and see if you spot anything using up loads of time
@@massiveCheese I worked it out. Because I use a if Input its creating new spawn points every time in the same place so it spawns more and more bullets every time you shoot. This can be fixed by using a final for loop where you queue free the spawn points and re create them the next time you shoot.
how did you do the global vars differntly im currently stuck on the issue and cant figure it out.
@@TheTeyKiller It was a while back. I was thinking I must have done them differently because of changes between godot 3 and 4 but I'm not sure that's true. I have: @export var rotate_speed: int = 30 for example, instead of it being a const.
This is very nice ! I really loved the mathematical explanations as a lot of people just tend to skip them or simply explain them without any illustration. You on the other hand explained everything with grace. Looking forward to more tutorials from you..
awesome tutorial, now things are spinning and shooting, pretty flexible too
Really good tutorial, comprehensible, and just plain awsome.
Choosing the "No comment" instead of "Default" will create scripts with no comments and when creating new script, Godot will remember your previous choice. I am yet to see a video where it is used. Seeing everyone delete the comments after the creating scripts every time made me write this comment... Great video BTW.
Omg this is life changing. Thanks for that tip!!
to the point, easy to understand and nice sounding keyboard
i approve
Thanks really helpful tutorial. just to echo all the others who appreciated the maths explanation too.
Very excellent video! This helped greatly for a game I'm working on for a game jam.
I love seeing more tutorial makers.
Amazing explanation!
Now I think i can take part to the jam.
6:44 Just a tip about adding stuff to the root. Whenever you instance object you should realistically be adding it to the last child of the root. Its fine for small projects but I found out the hard way working on a large project with loading screens and reparenting.
i.e
var root = get_tree().get_root()
var current_scene = root.get_child(root.get_child_count()-1)
current_scene.add_child(bullet)
While running the game you can click the remote button in the scene tree view to see where youre adding the bullets in real time
@@Chevifier Thanks for the tip, I'll definitely keep that in mind!
What happens if you add stuff to the root?
@@DankMemes-xq2xm they stick around if you dont remove them when switching scenes. Most time stuff we add we usually remove before like bullets for example so we don't notice. get_tree(). get_root() is the top most node for the entire project not the current scene. I may be wrong though ill double check
@@Chevifier Ohh, now that I think about it I don't think I add to the root either, I just add stuff as a child directly below the scene, or in a ySort below the scene.
I've looked at a lot of these kinds of tutorials and I feel qualified to say that this is very well done
Awesome tutorial You my friend got yourself a new subscriber!!
Thank you very much, your explanation was very understandable, I was able to use this algorithm in another game engine as well
This tutorial is so damn good. For once, It actually feels like I'm getting somewhere with making a game.
Thank you so much doing LD48 - This really helped
i've been looking for a tutorial like this for a while, thanks a lot
Top top toppppp quality. Great job Robyn!
Such a fantastic showcase. Hats off.
GREAT TUTORIAL GOT YOURSELF A NEW SUB!
Great tutorial! I do have one issue however, even though I have spawn_point_count set to 8, it’s only spawning one bullet at a time
Hey there! Thank you for the video. I am making a bullet hell game rn. I want to point out that having a timer for each bullet might not be the optimal way. One central timer is in fact enough as long as you connect it to each bullet and run a count down function in each bullet. Another little trick to save you two lines of code is to put queue_free directly when connecting on_killTimer_timeout by going into the advanced options. :)
Nicely done :)
Thanks! :) It works also in 3D and within UE5 ;)
UuuhhhMmmaaazziiing! Exactly what I needed for a number of projects I want to do! I enjoyed your explanations and look forward to future videos. Are you signed up for the bullet hell jam?
Thanks! I'm not participating in the bullet hell jam unfortunately. I have no time for game jams these days :(
What a neat tutorial! Excited for future videos ^^
Love it keep making tutorials!
Great tutorial, thanks!
this helped me a lot! thank you!
Love the tutorial sooo good!
That is some clean code!
Oh goodness this was the most relaxing tutorial ever, I could feel the stress melting away. :) I really like the pixel art on your logo, was that your own work?
Haha it's great that this video helped you relax, I suppose those patterns are almost a bit hypnotic 😂 And yup my logo is my own work, glad you like it!
@@bitbirdy Wow, that's really top draw work on the pixel art, hats off to you. Genuinely impressed. I do 3d so I can kinda go off a reference image in blender but with pixel art there's no getting around the need for talent (that's the step in the creative process I usually skip...)
Well I look forward your next stress therapy video, oops, I mean godot tutorial. ;)
Nice, I'll have to use this when I inevitably make a shmup game.
Yea go for it!
cool tutorial, i cant help but ask what keyboard did you use at the time you posted this video? i like the sound.
Super useful thank you!
So clever, thank you
Thanks just what i needed :)
Good job!
Thank you very much , you are so talented;)
Thx a lot
could you pls make this video for Godot 4? Thank you!
omg i love you thanks so much
Thank's guy
This is so cool! I'm trying to implement something similar. Have you run into performance issues instantiating and deleting so many new bullet scenes?
I haven't tested the performance, but one of the Godot developers tweeted that obejct pooling doesn't give much benefit in Godot, so constantly instantiating and deleting scenes should be fine twitter.com/reduzio/status/1073284242086551552 . If you find that it does affect performance, implementing a bullet pool is pretty easy too.
I also have a blog post about how to use multithreading to optimize many moving physics bodies which might be helpful! bitbirdy.dev/posts/godot-1000-bodies/
add_child and then queue_free() is totally ruin the engine to process the task. using pool system where load all the data then use em back is saving more energy.
i dont say any of bad using this method but specially for you working on mobile. i think is, way better using ( object pooling system ) fuc# with exploration or experiment about knowing how do we spend the time to just see the optimization work well with kind of this code. but the fact dont do simple thing always save your engine workload! thank you anyway of the tutoral :D keep the good work!!
I transformed this into 3d. It was so cool
That's awesome!
Thank you for the tutorial! This helped me so much. How does transform.x work when you use it in the Bullet.gd code? I get that position += speed * delta will move the object in the speed direction, but how does transform.x work to make it travel like relative to the angle?
transform.x is the "forward" direction of any node2d, so the bullet is basically going in whatever direction it's facing. At 6:58 I set the bullet's rotation which determines the bullet's forward direction.
Wow thanks you
hey i have the same exact code as you and for some reason my bullets dont appear can you help me?
Have you made sure to assign a texture to the Bullet's sprite? If you've already done that, DM on Twitter, maybe we can figure it out!
great tutorial! ive got everything working except that the rotator isnt rotating? any thoughts?
*edit*
figured it out :)
i have the same problem how did you solve it
Having the same issue how did you fix it?
@@Jabaz_ did u fixed it?
Epic :>
Well done video... BUT the only pattern it generates is (I don't know what's the correct name, but some kind of) "rotator".
Let me know you have any other ideas for other types of attack patterns! I might make it into a tutorial later on
Actually you can create different types of patterns by playing around with radius and stuff.
I also have Game dev channel like your
Time to create touhou project fan game lol
unfortunately it did now worked, I copied everything to a T and now matter what, the bullets wont spawn, a shame really
good tutorial, is there a way to make this in game maker studio 2?
and how can you make an enemy spawner?
It really depends on what kind of game you're making and how you want them to spawn. The official "Your first game" tutorai in the Godot Engine docs has a good example of spawning enemies randomly at the edges of the screen docs.godotengine.org/en/stable/getting_started/step_by_step/your_first_game.html
@@bitbirdy thanks a lot i'm going to check that
tried again, now the rotator doesn't follow the enemy when the enemy is instanced in the world, and the bullets won't move, either the people in this comment section are bots or this method is really old, anyway, wouldn't recommend to people
just go learn the basic for godot , then come back... it works because we know how to actually use the algorithm there's people here who uses completely diffrent engine and have it working. So scaled down your project save this video and comeback when u have the basic understanding of the engine. Goodluck
Thank you for script 😢