Calling set_process(true) in my script doesn't restart _process() being called

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jedesjardins

I’m trying to code a Textbox in my game. The textbox plays out it’s text over time, character by character. When it’s finished showing it’s text it calls set_process(false) to stop it’s processing.

Now I want the textbox to show different text, so I reset it’s state, set_process(true) and… nothing happens. For some reason _process isn’t called again. There is no errors/debug messages and I don’t know why processing doesn’t resume.

The code in question:

# first file, an Area2D that triggers the textbox when
# the player walks into it
extends Area2D

func _ready():
    var err = connect("body_entered", self, "start_script")
    if err != OK:
        print(err)

func start_script(_body):
    var textbox_scene = load("res://scenes/entities/textbox/textbox.tscn")
    var textbox = textbox_scene.instance()
    textbox.top_line_text = "Hello?"

    add_child(textbox)

    yield(textbox, "text_shown")

    print("This is reached")

    # this resets the state, sets the two lines of text
    # and calls set_process(true)
    textbox.show_text("Why is this never shown?", "")

    print("This is also reached")

    yield(textbox, "text_shown")

    print("This is not reached")

    textbox.queue_free()

and

# textbox.gd
func show_text(top: String, bottom: String):
    ...
    set_process(true)
    print("Set Process should be true")

func _process(delta):
    print("Processing")
    ...

This all outputs the text:

Processing
... # processing is printed multiple times
Processing
This is reached
Set Process should be true
This is also reached
# this is where I expect more processing to be printed, but it
# never is. indicating to me _process is never called again

I think the problem isn’t in the code you shared. Something else might be happening. It could be that the line doing set_process(false) (which you didn’t post) is being executed after you set the next text to execute, due to the order things actually happen when emitting the text_shown signal.

I made a test project doing something similar and it worked fine.

Zylann | 2020-03-09 19:04

I’m not sure what else could be happening. It’s a pretty simple project at the moment. The only thing I can imagine is that start_script is a coroutine, but I don’t know why that would mess with it at all.

jedesjardins | 2020-03-09 19:10

Here is an example of what I mean:
In the test project I just made, my process function in the text box looks like this:

func _process(delta):
	if _char_index <= len(_text):
		text = _text.left(_char_index)
		_char_index += 1
	else:
		set_process(false)
		emit_signal("text_shown")

This one works. But if I invert the order of emit_signal:

		emit_signal("text_shown")
		set_process(false)

This no longer works and the text box never plays the second text. And that happens because show_text() (which is supposed to bring back process to true) is called from inside the emit_signal, and when the signal has been handled, it resumes to the next line, which is… set_process(false). So it never plays the text.

You may check your project if you haven’t done the same mistake. You may otherwise share more of it.

Zylann | 2020-03-09 19:14

Well shoot, that was it. I didn’t realize the code that yields to the signal is called synchronously after the signal is emitted.
Thank you!
(I don’t know if you get positive karma or anything for having the answer. If you submit an official answer I will mark it as such, however)

jedesjardins | 2020-03-09 19:17

Added as answer :wink:

Zylann | 2020-03-09 19:24

:bust_in_silhouette: Reply From: Zylann

Shot in the dark turned out to hit :slight_smile:

I think you have a problem in your text box _process function.
In the test project I just made, my process function in the text box looks like this:

func _process(delta):
	if _char_index <= len(_text):
		text = _text.left(_char_index)
		_char_index += 1
	else:
		set_process(false)
		emit_signal("text_shown")

This one works. But if I invert the order of emit_signal:

		emit_signal("text_shown")
		set_process(false)

This no longer works and the text box never plays the second text. And that happens because show_text() (which is supposed to bring back process to true) is called from inside the emit_signal, and when the signal has been handled, it resumes to the next line, which is… set_process(false). So it never plays the text.

I get the same problem:

func _ready():
	set_process(false)
func _enter_tree():
	SigHub.catch_dlgUpdate.connect(AnimVisemes)
func _process(delta):
	print("Process")
func AnimVisemes(dlg: DlgDat):
	print("Setting to true")
	set_process(true)
  1. with only process function “Process” output

  2. with all only “Setting to true” is output

The signal function is working because “Setting to true” is working. If the process was started via the set_process(true) call then “Process” would print, it does not.

I don’t think they care, it’s been 6 years…

Don’t necro threads, it’s bad form.

Cheers !

2 Likes

If you believe this is a bug, the proper place to report that is here: GitHub - godotengine/godot: Godot Engine – Multi-platform 2D and 3D game engine · GitHub

If you solved it, then this would have been an appropriate response. Keep in mind that Godot releases a new version every three months, so a 6 year old post is many versions ago. So if you have a problem, asking a question on a thread that old is not really helpful.

This forum is very helpful to people who are polite, bother to read the forum guidelines, and don’t treat those of us who volunteer our time for free as if we are subhuman or LLMs just there to answer their questions. You being ignorant of the guidelines that keep this place civil is not an excuse for being uncivil.

Forums like this are going away because people now ask their questions to LLMs, and new people showing up are incredibly rude and dismissive of our time. Which makes us not want to respond anymore. When these forums disappear, the LLMs will have nothing to scrape, and they will no longer be able to answer questions.

We are happy to engage with you if you are polite. If you think that being polite is “pointless crap”, well then this is not the place for you.

3 Likes

Not quite buster, the post was in the forum’s archive.

You should have started a new thread with the question, copy pasting the original, then answering with your solution and marking it as such would have been useful to others, seeing at it would be clearly labelled as such.

The OP is probably long gone and thus marking this as a solution relies on overworked forum mods (who are volunteers and whose time is at least worth as much as yours)

Plus if it’s a bug, see @dragonforge-dev post.

But no, you know better, don’t care about social graces. No wonder the Internet is a cesspool nowadays

1 Like