I'm working on a game using the Godot game engine with Mono/C#. I'm trying to achieve the following:
- Display a message on screen
- Wait for a mouse button click/screen tap
- Display another message
- Wait for click
- ...
Therefore I have a Say() method:
async Task Say(string msg)
{
SetStatusText(msg);
_tcs = new TaskCompletionSource<Vector2>();
await _tcs.Task;
SetStatusText(string.Empty);
}
What I'm expecting is this to work:
async Task Foo()
{
// Displays "First".
await Say("First");
// "Second" should be shown after a click.
await Say("Second");
// "Third" should be shown after another click.
await Say("Third");
}
What actually happens is:
- "First" is shown
- "Second" is shown after a click.
- "Third" never shows up, even after a click.
I tracked it down to _tcs being null (or in an invalid state, if I don't set it to null) in my mouse button click code:
public void OnMouseButtonClicked(Vector2 mousePos)
{
if(_tcs != null)
{
_tcs.SetResult(mousePos);
_tcs = null;
return;
}
// Other code, executed if not using _tcs.
}
The mouse button click code sets the result of _tcs and this works fine for the first await, but then it fails, although I'm creating a new instance of TaskCompletionSource with every call of Say().
Godot problem or has my C# async knowledge become so rusty that I'm missing something here? It almost feels as if _tcs is being captured and reused.