在某种情况下,在网络上下载图片和音频的时候,由于网络等原因加载图片或者音频会很慢,就需要将图片或者音频缓存到本地。这样在读取本地图片和音频会很快。在网上也搜索了一些方法主要原理就是查找本地是否有这个文件,然后决定是去网上下载,还是本地加载。这里主要用到的方法就是读写本地文件和网上下载文件。下面是代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
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.zhaoshijun.com/archives/795
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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.zhaoshijun.com/archives/795
上面的脚本改了第三版了,新增了UnityWebRequest网络请求下载方法。也保留了WWW的方法。根据官方最新的测试版,可能要彻底弃用WWW,所以就自行取舍吧。文章源自大腿Plus-https://www.zhaoshijun.com/archives/795 文章源自大腿Plus-https://www.zhaoshijun.com/archives/795
我的微信
微信扫一扫

shijun_z
我的QQ
QQ扫一扫

846207670
评论