Table of Contents

异步脚本

高级 程序员

异步脚本只异步执行一次。它们可用于初始化场景及其内容,或每帧执行游戏逻辑。

public class Example : AsyncScript
{
    public override Task Execute()
    {
        // 执行异步代码
    }
    
    public override void Cancel()
    {
        // 脚本卸载时执行的操作
    }
}

何时使用

异步脚本用于实现需要等待某些操作的游戏逻辑。

如果你不需要等待任何任务,建议改为使用启动脚本或同步脚本。

什么是异步代码?

C# 中的异步编程指的是编写可以并行运行的代码。

例如:假设我们有一个保存游戏状态的方法,它需要 10 秒才能执行完毕。我们不必暂停一切直到它运行结束,而是可以异步运行它,这意味着在玩家进度保存期间,游戏可以继续运行。

异步方法是一个返回 Task 的普通方法,该 Task 随后可以被等待。在它运行期间,其他非异步代码和异步代码都获准运行。

protected override async Task Execute()
{
    // 等待 1 秒,而不会冻结游戏
    await Task.Delay(1000);
}

每帧执行代码

为了像同步脚本一样每帧持续执行逻辑,你可以在循环中使用 Script.NextFrame()。

public class Example : AsyncScript
{
    public override async Task Execute()
    {
        // 初始化代码写在这里
        
        // 只要脚本处于活动状态,这个循环就会持续运行
        while (Game.IsRunning)
        {
            // 每帧执行的代码写在这里
            
            await Script.NextFrame();
        }
    }
}

并行执行任务

有时在同一脚本中并行执行两个异步任务很有用。这可以通过 Script.AddTask() 实现。

public class Example : AsyncScript
{
    public override async Task Execute()
    {
        Script.AddTask(ParallelTask);
        
        // 与 ParallelTask 同时执行代码
    }
    
    private async Task ParallelTask()
    {        
        // 与 Execute 同时执行代码
    }
}
Warning

避免使用 Task.Run 来执行并行任务,因为它会在线程池而不是主线程上执行你的代码。这会让与引擎的交互变得不安全,并可能导致意外行为。

可重写的方法

异步脚本具有 2 个可重写的方法,用于执行游戏逻辑。

Note

这些方法只会在运行时被调用 - 它们永远不会在 Game Studio 中被调用。

Execute()

Execute 方法在脚本被添加到游戏时被调用。例如:

  • 当脚本所在的场景被加载时
  • 当包含该脚本的新实体被添加到场景时
  • 当脚本被添加到已存在的实体时

如果脚本附加到的实体先从场景中移除、随后又被添加回来,该方法可能会执行多次。

Cancel()

Cancel 方法在脚本从游戏中移除时被调用。包括:

  • 当脚本所在的场景被卸载时
  • 当脚本附加到的实体从其场景中移除时
  • 当脚本从场景实体上移除时
  • 当游戏关闭时

如果脚本附加到的实体先被重新添加、随后又从场景中移除,该方法可能会执行多次。

教程

更多示例请查看异步脚本教程。