Using `await` in C#?
Asked Answered
E

7

0

Hi everyone,

I'm trying to figure out how to use await in C#. For example, I would like to run simple tween, wait for it to finish, and then run some more code. I've been experementing with something like this, but have had no luck so far:

var tween = CreateTween();
tween.TweenProperty(panel, "modulate:a", 0, 1).SetTrans(Tween.TransitionType.Sine);
await ToSignal(tween, "finished");
GD.Print("Tween Finished");

I'm getting this error which I don't fully understand, but presumably it's because ToSignal(tween, "finished") is not returning a Task?:

CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

I've based my use of ToSignal on this doc:

https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_differences.html#doc-c-sharp-differences-await

Please let me know if you have any suggestions!

Thanks,
d13

Elke answered 16/12, 2023 at 13:10 Comment(0)
S
0

What method is this in? You need to change its signature to async as the error state. For example:

private async void Something() 
{
    /* await here */
}

(As shown in the MS docs linked from godot)

Superordinate answered 16/12, 2023 at 14:31 Comment(0)
E
0

Superordinate
Amazing, that worked! Thanks so much 🙂

Here's a complete example, which tweens the alpha of a sprite:

async void DoSomething()
{
	var tween = CreateTween();
	tween.TweenProperty(thingToTween, "modulate:a", 0, 1).SetTrans(Tween.TransitionType.Sine);
	await ToSignal(tween, “finished");
	GD.Print("Tween finished.");
}

And a timer that waits for 1.5 seconds...

async void DoSomething()
{
        GD.Print("Hello...");
	await ToSignal(GetTree().CreateTimer(1.5), "timeout");
        GD.Print("...World!");
}
Elke answered 16/12, 2023 at 15:26 Comment(0)
G
0

Elke Sarnoff
im trying in Godot 4.2 in C# with tween like you wrote, but the program doenst wait til signal. but no errors.
please, have you tested in Godot 4.2, too?

Gnomon answered 27/12, 2023 at 17:49 Comment(0)
S
0

Gnomon this really depends on the method return; an async void can’t be awaited so will continue (and the print will still display). This is generally fine for an event handler in a GUI but perhaps less so in godot. Ideally, the return would be async Task but this doesn’t bubble out to godot’s engine methods.

If you want to wait (and I assume this means preventing something else happening), likely that you need some state or a flag to prevent things happening until after the signal has fired. The code is correct as you mentioned but it won’t halt processing.

What are you trying to do?

Superordinate answered 28/12, 2023 at 11:21 Comment(0)
G
1

Superordinate
thx for the answer. i tried to follow a path with an animatedsprite2D. inside the async-functions the program waits, if i use the function multiple, program doesnt wait. the solution for me was to code all inside.

Gnomon answered 28/12, 2023 at 13:34 Comment(0)
E
0

Gnomon Yes, this works fine for me in 4.2. Could you post the code you're using?

Elke answered 29/12, 2023 at 10:41 Comment(0)
G
0

Elke
test for moving a sprite in steps:

`

public async void testtween()
{
    testsprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");

    Tween tween = CreateTween();
    tween.TweenProperty(testsprite, "position", new Vector2(300, 300), 1.0f);
    await ToSignal(tween, "finished");
    GD.Print("finished tween one\n");
    tween.Kill();

    tween = CreateTween();
    tween.TweenProperty(testsprite, "position", new Vector2(0, 0), 1.0f);
    await ToSignal(tween, "finished");
    GD.Print("finished tween two\n");
    tween.Kill();
}`
Gnomon answered 29/12, 2023 at 11:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.