协程 运行 时不播放动画

Animation doesn't play while coroutine is running

当我的场景开始时,我启动了一个协程来生成一个显示给用户的谜题。有时,这一代可能需要几秒钟,但通常很快。因为用户也可以从场景中刷新拼图,所以我不想来回跳到一个单独的加载场景,而是在协程 运行 时只显示一个简单的动画。我在同一个精灵上测试了两个动画:精灵的动画师和更新时的简单旋转。但是,正如标题所说,这两个都不是 运行,而协程是 运行。我可以看到该动画有效,因为协程完成后,两个动画都会开始(请参阅下面注释掉的 SetActive(false))。我怎样才能让这个动画工作?

结构是这样的:

-游戏场景

--Canvas

---PuzzleControl 游戏Object(带有 PuzzleControl 脚本)

----动画游戏Object(带有Sprite Renderer和Animator组件)

---LoadingScreen Game Object(带有 LoadingAnimation 脚本)

public class PuzzleControl : MonoBehaviour
{
    private PuzzleBuilder builder;
    void Start()
    {
        builder = this.gameObject.AddComponent<PuzzleBuilder>();
        LoadingScreen.SetActive(true);
        StartCoroutine(builder.Refresh());
    }

    public void RebuildPuzzle()
    {
        LoadingScreen.SetActive(true);
        StartCoroutine(builder.Refresh());
    }

    public void BuildComplete()
    {
        // This will be called by our builder -- currently turned off
        //LoadingScreen.SetActive(false);
    }
}


public class LoadingAnimation : MonoBehaviour
{
    public GameObject animation;
    private float rotateSpeed = 200f;

    // Update is called once per frame
    void Update()
    {
        animation.GetComponent<Transform>().Rotate(new Vector3(0f,0f, rotateSpeed * Time.deltaTime));
    }
}

这是一个常见的误解,协程实际上并不 运行 在一个单独的线程上,所以如果你有很多计算要做,你需要将它移到任务中并 运行 它在线程池上,否则 Unity 在执行此工作时仍会冻结。协程仅 return 控制 cpu 当它们屈服时,每个帧统一将重新进入它停止的协程,这给出了代码的错觉 运行ning 同时 when实际上,它只是使用 yield 关键字被切成块。

将事物移动到线程中的一个限制是,作为一般规则,您实际上不能接触任何属于 Unity 引擎的部分,因此您需要收集所需的数据,然后将其发送给线程进行计算,然后在完成后将更改应用于场景。

这里有一个简单的例子,说明如何将长 运行ning 计算发送到一个单独的线程(或至少将其并行化,因为 C# 会将其发送到线程池以处理分配):

using System.Threading.Tasks;

void Start()
{   
    // send it 
    var taskHandle = Task<MapBuildData>.Run(DoLongBuildCalculation).ContinueWith(OnBuildComplete);
}

MapBuildData DoLongBuildCalculation()
{
    // do long calculation.
    return result;
}

void OnBuildComplete(Task<MapBuildData> buildTask)
{
    if(buildTask.IsFaulted || buildTask.IsCanceled)
    {
        // handle it.
    }

    // do something in with buildTask.Result
} 

编辑:为澄清起见,您不应在 DoLongBuildCalculation() 内部与 Unity 对象交互。