在Unity中使用异步等待(async await)

3

有人能说一下如何使这样的结构起作用吗?目前返回UnityExtension。 或者建议如何将非MonoBehaviour代码的一部分轻松地移动到单独的线程中。

UnityException:get_canAccess只能从主线程调用。在加载场景时,构造函数和字段初始化器将从加载线程执行。不要在构造函数或字段初始化器中使用此函数,而是将初始化代码移动到Awake或Start函数中。

    private async void Awake()
    {
        Mesh protoMesh = gameObject.GetComponent<MeshFilter>().mesh;
        SelfMesh = await InitMeshAsync(protoMesh);
    }

    protected async Task<CustomMesh> InitMeshAsync(Mesh protoMesh)
    {
        return await Task.Run(() => new CustomMesh(protoMesh.vertices, protoMesh.triangles));
    }
1个回答

1

从异常信息来看,CustomMesh正在使用无法在单独线程中运行的代码。protoMesh.vertices, protoMesh.triangles需要在启动新线程之前获取。

private async void Awake()
{
    Mesh protoMesh = gameObject.GetComponent<MeshFilter>().mesh;
    SelfMesh = await InitMeshAsync(protoMesh);
}

protected async Task<CustomMesh> InitMeshAsync(Mesh protoMesh)
{
    var vertices = protoMesh.vertices;
    var triangles = protoMesh.triangles;
    return await Task.Run(() => new CustomMesh(vertices, triangles));
}

关于哪些内容可以从单独的线程运行,哪些不能,这是一个棘手的问题,你需要不断地查看给定字段/方法的实现方式,但一个好的经验法则是在启动另一个线程之前,始终复制基本类型(如intstringfloat[])的请求字段。

如果您访问GitHub,您会发现vertices使用了GetAllocArrayFromChannel,该方法使用了GetAllocArrayFromChannelImpl,而后者是无法从单独的线程中使用的本地方法。


不确定这是否是问题所在。我还需要删除类Color内部的初始化。 - Zik Lebovsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接