menu_bookDocumentation
Async Components: Coroutine-Style Async Tasks on the Main Thread
Async tasks in s&box run on the main thread by default, operating like coroutines. They are the recommended replacement for coroutines in s&box.
Basic Async
CSHARP
async Task PrintSomething( float waitSeconds, string message )
{
await Task.DelaySeconds( waitSeconds );
Log.Info( message );
}Frame-by-Frame Lerping
Use Task.Frame() to wait one frame, enabling smooth animations:
CSHARP
async Task LerpSize( float seconds, Vector3 to, Easing.Function easer )
{
TimeSince timeSince = 0;
Vector3 from = WorldScale;
while ( timeSince < seconds )
{
var size = Vector3.Lerp( from, to, easer( timeSince / seconds ) );
WorldScale = size;
await Task.Frame();
}
}
await LerpSize( 3.0f, Vector3.One * 3.3f, Easing.BounceOut );Multiple Concurrent Tasks
CSHARP
async Task DoMultipleThings()
{
Task taskOne = PrintSomething( 2.0f, "One" );
Task taskTwo = PrintSomething( 3.0f, "Two" );
await Task.WhenAll( taskOne, taskTwo );
}Calling Async from Synchronous Code
CSHARP
protected override void OnEnabled()
{
_ = DoMultipleThings(); // fire and forget
GetKanyeQuote().ContinueWith( task => Log.Info( task.Result ) ); // with callback
}Lifecycle Safety
When a GameObject is destroyed or disabled while awaiting, the async method may still run. When awaiting via Component.Task, tasks are automatically cancelled if the GameObject becomes invalid. For custom implementations, use CancellationToken and check validity after awaits.
Avoid letting tasks stack up — handle cases where the user triggers an action multiple times during a wait.
Was this helpful?