从服务器加载时在Unity中使Texture2D可读

3

我正在使用DownloadHandlerTexture.GetContent来获取我的纹理:

www = UnityWebRequest.GetTexture("http://www.example.com/loadTex/?tag=" + tag);
www.SetRequestHeader("Accept", "image/*");
async = www.Send();
while (!async.isDone)
    yield return null;

if (www.isError) {
    Debug.Log(www.error);
} else {
    yield return null;
    tex = DownloadHandlerTexture.GetContent(www);
}

加载后,我想将其缓存到文件中,因此我执行以下操作:
byte[] pic = tex.EncodeToPNG();
File.WriteAllBytes(Application.persistentDataPath + "/art/" + tag + ".png", pic);

此时我会收到异常:
UnityException: Texture '' is not readable, the texture memory can not be accessed from 
scripts. You can make the texture readable in the Texture Import Settings.

我认为我需要以某种方式使它易读。我搜索了一下,但我得到的唯一答案是如何通过编辑器使其易读。

2个回答

4

我想提醒大家,UnityWebRequest.GetTexture可以使用两个参数:url和一个用来使纹理可读或不可读的布尔变量 :)

https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.GetTexture.html

因此,在使用DownloadHandlerTexture.GetContent获取请求结果中的纹理之前,只需要调用UnityWebRequest.GetTexture(url, false)即可使下载的纹理变为可读。

PS: 在Unity 5.6之前,请注意,非可读性的布尔变量是相反的。他们应该从5.6开始修复(根据发行说明)。

使您的纹理可读:

  • 在5.6之前: UnityWebRequest.GetTexture(url, true)
  • 在5.6之后: UnityWebRequest.GetTexture(url, false)

2

您可以存储来自UnityWebRequest的数据。您当前所做的有点无用,因为您将结果转换为纹理,然后再将纹理转回字节数组。

byte[] bytes = www.uploadHandler.data;
File.WriteAllBytes(Application.persistentDataPath + "/art" + tag, data);

我猜这样就可以了。不需要使用.png扩展名,因为你存储的是原始字节数组。然后你将获得该数组并从中创建纹理:

byte [] bytes = File.ReadAllBytes(Application.persistentDataPath + "/art" + tag); 
Texture2D texture = new Texture2D(4,4,TextureFormat.RGBA32, false);
texture.LoadImage(bytes);

我正在加载纹理以在模型中使用。但是,当程序结束时,我尝试将其缓存到文件中。我使用 DownloadHandlerTexture.GetContent 的原因是它针对内存进行了优化。 - serge
不要在最后缓存,而是在获取时进行缓存。 这非常相同。 - Everts
听起来很合理,我回家后会尝试并尽快报告。另外,从字节加载纹理是否比使用DownloadHandlerTexture.GetContent效率低? - serge
这是来自手册的内容:“要从远程服务器检索纹理文件,您可以使用UnityWebRequest.Texture。该方法与UnityWebRequest.GET非常相似,但经过优化以有效地下载和存储纹理。” - serge
好的,但你误解了我的意思。我是说,你可以像现在这样使用纹理,但同时也要按照我展示的方式存储纹理。你所展示的方法更快,我明白,但下一轮使用缓存版本时,这个方法就不再适用了。因此,当你下载时,请使用快速版本并存储uploadHandler.data。接下来,获取缓存数据并使用较慢的版本,这将比重新下载更快。 - Everts

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