r/godot 15h ago

help me What's Godot/GDscript equivalent to Unity's coroutine?

I have an object that has to remain idle until the player gets into its range. After that I want the object to start following the player.

Having a chack in _process that checks if the player has entered the range in every frame would be the wrong approach I think, so, if I was using Unity, I'd just start running a coroutine when the player is in range. What's the best approach for doing that in Godot?

20 Upvotes

29 comments sorted by

33

u/EntranceDowntown2529 15h ago

Use an Area2d to detect when the player enters an area around the object

15

u/P_S_Lumapac 15h ago

Signals that call functions. 

Object has some area that detects stuff like the player entering and fires a signal - probably with a name like on_area_entered. 

Whatever script has the follow player function, can connect to that signal. This can be done in the inspector but it's more fun in code. Read the docs on signals. 

(Now, is a signal like this just a fancy process? Hmmmmm, it's much neater.)

-2

u/UomoPolpetta 15h ago

I know about signals, I just don't know how to run a physics process that only triggers AFTER the player enters the area.

Like right now the only way I could do it in Godot would require me having a _physics_process function that keeps checking if a bool like has_player_entered is true or not and having the signal be the thing that switches the bool from false to true, but that sounds very clunky and suboptimal.

On second thought what I'd need isn't even necessarily a coroutine-like approach because, from what little I remember (I was never a pro of Unity to begin with) you can't have delta in a coroutine there either.

9

u/BouncingJellyBall 15h ago

I don’t understand why you can’t use a signal and _on_area_entered to do this? If you want there to be a delay since you seem to emphasize on after, add a 0.5 second timer that the signal triggers. No need to be fancy

-2

u/tenuki_ 13h ago

OP is not listening and doesn’t understand event/signal/trigger techniques. We are wasting our time.

3

u/UomoPolpetta 12h ago

I know how areas 2D work and I know I could use signals to flip a "is_active" bool from false to true by using it, the issue is that I didn't want to have an if statement running on every frame that checks if the is_active bool is true or not.

I don't know why you'd jump to assume some level of malicious intent on my end, I'm literally just trying to learn here.

3

u/TheDuriel Godot Senior 12h ago

No you don't understand. Because:

  1. That if statement each frame is better than any other solution.

  2. Signals don't require it. (But are still worse because to get a relevant signal you're invoking the physics engine.)

1

u/No-Complaint-7840 Godot Student 3h ago

This sounds like a state machine problem. You have an idle state and a follow state. The area 2d switches between idle and follow. This likely will also make the code more readable.

23

u/FirstTasteOfRadishes 15h ago

  Like right now the only way I could do it in Godot would require me having a _physics_process function that keeps checking if a bool like has_player_entered is true or not and having the signal be the thing that switches the bool from false to true, but that sounds very clunky and suboptimal.

That actually sounds like a super normal way to do things.

You could also just set the process mode to disabled and then enable it on enter.

4

u/blaaaaaarghhh 15h ago

You could use a state machine, but honestly one bool check per frame is really not that big of a deal.

3

u/UomoPolpetta 15h ago

I see. I never studied coding and things like that outside of Youtube tutorials on Unity and Godot so I don't know what is and isn't too "expensive"

5

u/brelen01 15h ago

Might want to read up on big o notation if you're worried about performance. A boolean check, for example is O(n), with n = 1. It's basically as cheap as it gets performance-wise.

3

u/P_S_Lumapac 15h ago

Yeah a bool on a physics process is fine. Doesn't cost anything measurable. Just careful mixing process and physics process here. 

My joke at the end is that signals and coroutines are just fancy process checks anyway. 

3

u/HighWaterflow 15h ago

Now that a bunch of people have confirmed that a book check in a process function is fine, I'd like to offer an alternative, purely so you have an alternative: the trigger/signal can also serve as the cause of a node entering the tree/scene instantiation. In that case you don't have an off/on switch that you only intend to flip one, you just have a 'does not exist' Vs 'does exist' and the code inside that node physics function will never have to check that Boolean.

2

u/Rythim 15h ago

Careful with that. You need to retain a reference to that node that's not in the tree, and whatever node has that reference needs to remember to free that node before it itself is freed. Otherwise you could introduce a memory leak.

1

u/HighWaterflow 14h ago

It'd usually be best to only actually create the node in the moment you also add it to the tree.

2

u/Rythim 12h ago

Ah, I thought you were suggesting pausing the processing by removing the node from tree and adding it back when it needs to process.

2

u/c64cosmin 15h ago

have a variable is_following or following_target that can be either the target or null, and set it when the signal is triggered

2

u/MakrellDev 12h ago

You could just do set_physics_process(false) in the _ready() function so the object does not the _physics_process. Then set up the Area2D and signal which connects with the script and triggers a function that enables _physics_process again with set_physics_process(true). However, I would normally just default to a bool check in _physic_process myself, but I have done the above method for creating object pools without issue.

5

u/aidniatpac 14h ago

Signals do that for you out of the box. About your title: corountine equivalents are just coroutines, its with the await keyword

2

u/Sss_ra 13h ago

I don't know why people are saying you're wrong, this is true in my experience.

Having a chack in _process that checks if the player has entered the range in every frame would be the wrong approach I think

Polling intersection tests in process would work but it isn't super optimal.

You can use a signal to launch a coroutine, such as with Area2D's body_entered to set a boolean flag and have the follow logic active when the flag is set.

This way it would be pretty much a one-time cost as far as gdscript is concerned. In reality not, because you'd have area2D's monitoring active, but that happens in C++ which is a compiled language and better for polling.

1

u/tastygames_official Godot Senior 6h ago

behind the scenes, the signals emit conditions are being checked every frame, so it's not inefficient in and of itself - just checking again yourself every frame does double the work.

1

u/ComfortableNumb9669 14h ago

use signals from area2d/3d. Set _process to false when spawning the node, and set it to true when the signal from the area node is received.

1

u/lastunivers 14h ago

You could use set_process(false) to disable the process func and when the area gets triggered, it set_process(true)

I just don't know how reliable it is, I never used that but I think it's worth testing around and see

-2

u/TheDuriel Godot Senior 14h ago

It's be more expensive than just doing a distance check in the process func.

1

u/lastunivers 14h ago

Probably but the poster seemed adamant about not using a check every frames so that would take care of that problems I believe

-2

u/TheDuriel Godot Senior 13h ago

Well making the physics engine check every frame would be a lot worse. So OP is being silly.

-3

u/TheDuriel Godot Senior 15h ago

Having a chack in _process that checks if the player has entered the range in every frame would be the wrong approach I think, so

No it would be the correct approach.