在某种情况下,在网络上下载图片和音频的时候,由于网络等原因加载图片或者音频会很慢,就需要将图片或者音频缓存到本地。这样在读取本地图片和音频会很快。在网上也搜索了一些方法主要原理就是查找本地是否有这个文件,然后决定是去网上下载,还是本地加载。这里主要用到的方法就是读写本地文件和网上下载文件。下面是代码。文章源自大腿Plus-https://www.shijunzh.com/archives/795
using UnityEngine; using System.Collections; using System.IO; using System; using UnityEngine.Events; using UnityEngine.Networking; /// <summary> /// 图片缓存 /// </summary> namespace Tools.Cache { public class CacheManager : MonoBehaviour { private static CacheManager cache = null; private string cachePath = ""; private static UnityAction<Texture2D> textureCacheEvent; private static UnityAction<Sprite> spriteCacheEvent; private static UnityAction<AudioClip> clipCacheEvent; void Awake() { cachePath = //Application.persistentDataPath; #if UNITY_EDITOR || UNITY_STANDALONE_WIN Application.dataPath + "/StreamingAssets/Cache"; #elif UNITY_IPHONE || UNITY_ANDROID Application.persistentDataPath + "/Cache"; #else string.Empty; #endif } public static CacheManager GetCache() { if (cache == null) { GameObject go = new GameObject("CacheManager"); cache = go.AddComponent<CacheManager>(); } return cache; } public void DownLoad(string url, string identifyId, UnityAction<Texture2D> callback) { textureCacheEvent = callback; StartCoroutine(Load(url, identifyId)); } public void DownLoad(string url, string identifyId, UnityAction<Sprite> callback) { spriteCacheEvent = callback; StartCoroutine(Load(url, identifyId)); } public void DownLoad(string url, string identifyId, UnityAction<AudioClip> callback) { clipCacheEvent = callback; StartCoroutine(Load(url, identifyId)); } /// <summary> /// 判断是否本地有缓存 /// </summary> /// <param name="url"></param> /// <returns></returns> private IEnumerator Load(string url, string identifyId) { if (!string.IsNullOrEmpty(url)) { string _suffix = url.Split('.')[url.Split('.').Length - 1]; string _name = "{0}." + _suffix; if (!File.Exists(Path.Combine(Path.Combine(cachePath, _suffix), string.Format(_name, identifyId)))) { //网络上下载 yield return DownLoadByUnityWebRequest((new Uri(url)).AbsoluteUri, (data) =>; { //保存至缓存路径 if (!Directory.Exists(Path.Combine(cachePath, _suffix))) { Directory.CreateDirectory(Path.Combine(cachePath, _suffix));//创建新路径 } File.WriteAllBytes(Path.Combine(Path.Combine(cachePath, _suffix), string.Format(_name, identifyId)), data); }); } else { //已在本地缓存 string filePath = "file:///" + Path.Combine(Path.Combine(cachePath, _suffix), string.Format(_name, identifyId)); yield return DownLoadByUnityWebRequest(filePath); } } } /// <summary> /// UnityWebRequest /// </summary> /// <param name="url"></param> /// <param name="callback"></param> /// <returns></returns> private IEnumerator DownLoadByUnityWebRequest(string url, Action<byte[]> callback = null) { UnityWebRequest uwr = new UnityWebRequest(url); if (textureCacheEvent != null) { DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true); uwr.downloadHandler = downloadTexture; yield return uwr.SendWebRequest(); Texture2D texture = null; if (!uwr.isNetworkError) { texture = downloadTexture.texture; } textureCacheEvent.Invoke(texture); } if (spriteCacheEvent != null) { DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true); uwr.downloadHandler = downloadTexture; yield return uwr.SendWebRequest(); Texture2D texture = null; if (!uwr.isNetworkError) { texture = downloadTexture.texture; } Sprite sp = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f); spriteCacheEvent.Invoke(sp); } if (clipCacheEvent != null) { DownloadHandlerAudioClip downloadAudioClip = new DownloadHandlerAudioClip(url, AudioType.WAV); uwr.downloadHandler = downloadAudioClip; yield return uwr.SendWebRequest(); AudioClip audioClip = null; if (!uwr.isNetworkError) { audioClip = downloadAudioClip.audioClip; } clipCacheEvent.Invoke(audioClip); } if (callback != null) { callback.Invoke(uwr.downloadHandler.data); } } /// <summary> /// WWW /// </summary> /// <param name="url"></param> /// <param name="callback"></param> /// <returns></returns> private IEnumerator DownLoadByWWW(string url, Action<byte[]> callback = null) { WWW www = new WWW(url); yield return www; if (textureCacheEvent != null) { textureCacheEvent.Invoke(www.texture); } if (spriteCacheEvent != null) { Sprite sp = Sprite.Create(www.texture, new Rect(0, 0, www.texture.width, www.texture.height), Vector2.one * 0.5f); spriteCacheEvent.Invoke(sp); } if (clipCacheEvent != null) { clipCacheEvent.Invoke(www.GetAudioClip()); } if (callback != null) { callback.Invoke(www.bytes); } } } }
上面的代码,不用拖到任何物体上就能使用。只要拖到项目的任意目录就能直接使用。下面是使用方法。文章源自大腿Plus-https://www.shijunzh.com/archives/795
using UnityEngine; using Tools.Cache; public class Test : MonoBehaviour { public RawImage image; // Use this for initialization void Start() { string url = "http://www.shijunzh.com/wp-content/uploads/2017/06/cropped-icon.png"; string name = "123"; CacheImage.GetCache().DownLoad(url, name, CacheEvent); } void CacheEvent(Texture2D t) { image.texture = t; } }
其中,在DownLoad方法里第一个参数是图片的url地址,第二个参数是保存到本地的图片名称。也是用这个名称去判断本地有没有这个图片的,所以这个参数最好具有唯一性的。第三个参数是一个委托方法,用来接收加载的图片的。文章源自大腿Plus-https://www.shijunzh.com/archives/795
上面的脚本改了第三版了,新增了UnityWebRequest网络请求下载方法。也保留了WWW的方法。根据官方最新的测试版,可能要彻底弃用WWW,所以就自行取舍吧。文章源自大腿Plus-https://www.shijunzh.com/archives/795
评论