Unity + NGUI create the asynchronous loading of network images and local cache tool class (2), unityngui
Next, the main methods in our tool class are as follows:
Public void SetAsyncImage (string url, UITexture texture)
Follow the image loading steps described above
Public void SetAsyncImage (string url, UITexture texture) {// before you start downloading the image, set the main image of UITexture to occupy the bitmap texture. mainTexture = placeholder; // determines whether the image is loaded for the first time if (! File. exists (path + url. getHashCode () {// If the cache file StartCoroutine (DownloadImage (url, texture) does not exist before;} else {StartCoroutine (LoadLocalImage (url, texture ));}}
The following code checks whether a cached file uses a url. getHashCode () method, because our image file name uses the hash code of the original URL for direct storage as the file name, the probability of duplicate names can be ignored, but also shorten the length of the file name to improve efficiency, this practice is based on the open-source iOS framework EGOImageView.
If the image is loaded for the first time and the file corresponding to this URL does not exist, we will download the image from the original URL and assign it to the control.
If this file already exists in the cache folder, read and load the file directly.
Thanks to the preparations above, our tool class is already a single example class of MonoBehaviour, so you can use the asynchronous function StartCorutine () of unity ()
Next, complete the DownloadImage (string url, UITexture texture) method)
IEnumerator DownloadImage (string url, UITexture texture) {Debug. log ("downloading new image:" + path + url. getHashCode (); WWW www = new WWW (url); yield return www; Texture2D image = www. texture; // Save the image to the cache path byte [] pngData = image. encodeToPNG (); File. writeAllBytes (path + url. getHashCode (), pngData); texture. mainTexture = image ;}
This method is simple. Then, you can read the existing image method LoadLocalImage (string url, UITexture texture) from the cache folder)
Note that the Resources. Load () method cannot be used here, because our images are not stored inProject catalogI carefully checked the relevant information and found that the more appropriate method should be to use the unity WWW class to load the file url, that is, add file in front of the file path: /// make it a File url and read it using the www class. However, this process is local or faster.
IEnumerator LoadLocalImage (string url, UITexture texture) {string filePath = "file: //" + path + url. getHashCode (); Debug. log ("getting local image:" + filePath); WWW www = new WWW (filePath); yield return www; // directly map texture. mainTexture = www. texture ;}
Our tool class has been written.
Add a node with UITexture component to a Panel, call our tool method, and test the running result:
First run:
Open the folder where this file is located (I am using a windows system, different system paths)
,
This image has been attached to our image control and saved to the local path. That is to say, after we run it again, we will not enter the first case of if. We will turn off the program and run it again:
As we thought, this is actually not a network request, it means that my cache is useful, and the image will come out, not like waiting for a while.
Next, we delete the cache file and execute it again. The first method will be called ~
This tool class is done here first, and then the image switching effect has been waiting for HUD in the loading process and will be studied later. Complete code:
Using UnityEngine; using System. collections; using System. IO; public class AsyncImageDownload: MonoBehaviour {public Texture placeholder; public static AsyncImageDownload Instance = null; private string path = Application. persistentDataPath + "/ImageCache/"; // construct the singleton public static AsyncImageDownload CreateSingleton () {if (! Directory. exists (Application. persistentDataPath + "/ImageCache/") {Directory. createDirectory (Application. persistentDataPath + "/ImageCache/");} GameObject obj = new GameObject (); obj. addComponent <AsyncImageDownload> (); AsyncImageDownload loader = obj. getComponent <AsyncImageDownload> (); Instance = loader; loader. placeholder = Resources. load ("placeholder") as Texture; return loader;} public void SetAsyncImage (str Ing url, UITexture texture) {// before you start downloading the image, set the main image of UITexture to occupy the bitmap texture. mainTexture = placeholder; // determine whether the image is loaded for the first time if (! File. exists (path + url. getHashCode () {// If the cache file StartCoroutine (DownloadImage (url, texture) does not exist before;} else {StartCoroutine (LoadLocalImage (url, texture ));}} IEnumerator DownloadImage (string url, UITexture texture) {Debug. log ("downloading new image:" + path + url. getHashCode (); WWW www = new WWW (url); yield return www; Texture2D image = www. texture; // Save the image to the cache path byte [] pngData = image. encodeToPNG (); File. writeAllBytes (path + url. getHashCode (), pngData); texture. mainTexture = image;} IEnumerator LoadLocalImage (string url, UITexture texture) {string filePath = "file: //" + path + url. getHashCode (); Debug. log ("getting local image:" + filePath); WWW www = new WWW (filePath); yield return www; // directly map texture. mainTexture = www. texture ;}}