OP:
如何异步创建纹理?
简短回答
你不能,“使用C# API创建纹理(如new Texture2D
)必须始终在主线程上调用”。
详细回答
.NET 4.x 带来了通过 async/await
实现的异步 I/O 和异步计算支持。它们通常没有任何使用障碍,但在 Unity 3D 中存在一些问题,尤其是在计算方面。
您下面的代码是一个I/O绑定的示例,并且是异步 I/O 的一个例子,Unity不应该有任何问题。 会造成问题的部分将是纹理的创建。请继续阅读。
WebResponse atlasTextureResponse = await atlasTextureRequest.GetResponseAsync();
byte[] atlasTextureData = await EntityDatabase.ReadStreamAsync(
atlasTextureResponse.GetResponseStream(),
(int)atlasTextureResponse.ContentLength
);
在Unity中创建纹理是一个计算密集型的操作,它是计算操作的一个示例。要在后台执行计算操作,通常需要执行以下操作:
var stuff =
await Task.Run (() => ConstructSomethingThatTakesALongTimeSynchonosouly ();
虽然这样也可以,但我们想要创建一个Texture2D
,因此我们可以尝试做如下操作:
public class LoadTextureAsyncExample : MonoBehaviour
{
private async void Start()
{
var textureBytes = await DownloadTextureAsync();
_texture = await Task.Run(() => CreateTexture2D(textureBytes));
}
private async Task<byte[]> DownloadTextureAsync()
{
}
private Texture2D CreateTexture2D(byte[] textureBytes)
{
var texture = new Texture2D(1, 1);
texture.LoadRawTextureData(textureBytes);
return texture;
}
现在,虽然CreateTexture2D
将在线程池线程中运行并且不会阻塞主线程,但由于它在与主线程不同的线程中运行,代码在创建Texture2D
时会失败。
C#创建的纹理必须在主线程中创建。您可以尝试设置Texture.allowThreadedTextureCreation = true
,但这也不起作用。Unity在下面最好地解释了这一点。
Unity(我强调):
Texture.allowThreadedTextureCreation
描述
允许Unity内部在任何线程上执行纹理创建(而不是专用渲染线程)。
注意:C# API用于纹理创建(例如new Texture2D)必须始终在主线程上调用。该设置不改变此要求。