加载和读取外部图片资源"/>
Unity异步加载和读取外部图片资源
后台线程读取本地或者云端png\jpg图片。
背景:做VR开发中,最经常用到的一个功能就是加载外部的全景图,并且在头盔里显示。但是一张4K的全景图动辄10M左右的大小,而且需要占用24M(4K 的jpg格式,一个像素24bit-RGB)内存。如果在主线程里做加载,会明显感觉到卡顿,而在VR模式下用户对卡顿 的感知会被放大。幸运的时Unity的新版本中为我们提供了在辅助线程(worker thread)完成这个文件加载和图片解析的过程。
使用WWW类或者IO的方式确实可以做到文件加载在后台线程完成,但是当把加载到的数据解析到Texture 类里时,在早先的版本里,只能在主线程做,而且unity会一次分配满足这个图片的内存,并且读取所有像素。这样的行为导致,这个操作是非常耗时的。当然对于小的图片,这样做依然是没有问题的。
Texture2D tex;tex = new Texture2D(4, 4, TextureFormat.DXT1, false);using (WWW www = new WWW(url)){yield return www;www.LoadImageIntoTexture(tex);GetComponent<Renderer>().material.mainTexture = tex;// 或者是下面这样// GetComponent<Renderer>().material.mainTexture =www.texture;}
上述方式非常简单而且可靠,对于一些小的图片加载也完全没有问题,而且兼容几乎所有的unity版本。假设使用这种方式的话,有一些问题需要注意
- 加载的图片长和宽尽量是2的n次方,否则会比期望的浪费更多的内存空间,并且加载速度会更慢
- 如果加载出来的图片不再需要了,需要手动Destroy,即使没有引用unity也不会自动GC 回收掉
- 如果不需要透明通道,尽量使用jpg格式的图片,而不要使用png,这样可以节省1/4的内存(RGB24->RGBA32)
说完传统的方式加载,我们介绍下Unity新支持的异步加载图片功能,这个在文档里隐藏较深,很多人可能不会发现。
IEnumerator GetTexture() {//这里的地址可以填本地文件地址 file://[文件路径]using(UnityWebRequest www = UnityWebRequest.GetTexture(".png")) {yield return www.Send();if(www.isError) {Debug.Log(www.error);}else {/*这里把贴图转换的过程放到了后台线程来完成,并且相比于直接脚本加载图片做了优化,减少了内存分配*/Texture myTexture = DownloadHandlerTexture.GetContent(www);}}}
UnityWebRequest这个类在Unity2018.2.12 里被替换成了UnityWebRequestTexture,但是使用方法是完全一样的。
Unity2018文档地址.UnityWebRequestTexture.GetTexture.html.
更多推荐
Unity异步加载和读取外部图片资源
发布评论