Unity3d网络加载方法:DownloadHandlerTexture

A DownloadHandler subclass specialized for downloading images for use as Texture objects.

DownloadHandlerTexture stores received data in a pre-allocated Unity Texture object. It is optimized for downloading images from Web servers, and performs image decompression and decoding on a worker thread.

For use cases where you wish to download an image via HTTP and use it as a Texture within Unity, usage of this class is strongly recommended.

一个专门用于下载图像以用作纹理对象的DownloadHandler子类。

DownloadHandlerTexture将接收到的数据存储在预先分配的Unity纹理对象中。它针对从Web服务器下载图像进行了优化,并在工作线程上执行图像解压缩和解码

对于希望通过HTTP下载图像并将其用作Unity中的纹理的用例,强烈建议使用此类

https://docs.unity3d.com/ScriptReference/Networking.DownloadHandlerTexture-ctor.html

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class Example : MonoBehaviour
{
    IEnumerator Start()
    {
        using (var uwr = new UnityWebRequest("https://website.com/image.jpg", UnityWebRequest.kHttpVerbGET))
        {
            uwr.downloadHandler = new DownloadHandlerTexture();
            yield return uwr.SendWebRequest();
            GetComponent<Renderer>().material.mainTexture = DownloadHandlerTexture.GetContent(uwr);
        }
    }
}

在某种情况下,在网络上下载图片和音频的时候,由于网络等原因加载图片或者音频会很慢,就需要将图片或者音频缓存到本地。这样在读取本地图片和音频会很快。在网上也搜索了一些方法主要原理就是查找本地是否有这个文件,然后决定是去网上下载,还是本地加载。这里主要用到的方法就是读写本地文件和网上下载文件。下面是代码。

CacheImage.cs

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);
            }
        }
    }
}

上面的代码,不用拖到任何物体上就能使用。只要拖到项目的任意目录就能直接使用。下面是使用方法。

using UnityEngine;
using Tools.Cache;
 
public class Test : MonoBehaviour
{
    public RawImage image;
    // Use this for initialization
    void Start()
    {
        string url = "https://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地址,第二个参数是保存到本地的图片名称。也是用这个名称去判断本地有没有这个图片的,所以这个参数最好具有唯一性的。第三个参数是一个委托方法,用来接收加载的图片的。

上面的脚本改了第三版了,新增了UnityWebRequest网络请求下载方法。也保留了WWW的方法。根据官方最新的测试版,可能要彻底弃用WWW,所以就自行取舍吧。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值