2020-11-03 Unity 使用UnityWebRequest下载图片 音频 APk等功能实现

在工作中经常会需要下载网络图片,或者音频等功能,所以封装了这个下载脚本。
功能需求:为了高效率和节省流量,再本地有该文件时不再重复下载
可以回传下载进度,下载后的资源
调用方式简单

用来下载的脚本

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

/// 
/// 图片缓存
/// 
public class WebUtils : SingletonObject
{

    /// 
    /// 下载带泛型
    /// 
    public  void Load(string url , Action endAction=null, Action proAction=null) where T: UnityEngine.Object
    {
        if (!string.IsNullOrEmpty(url))
        {
            string path = PathTools.GetSavePath(url);
            if (!File.Exists(path))
            {
                StartCoroutine(DownLoadByUnityWebRequest(url, endAction, proAction));
            }
            else//已在本地缓存  
            {
                StartCoroutine(DownLoadByUnityWebRequest(path, endAction, proAction));
            }
        }
        else 
        {
            Debug.LogError("WebUtils error: url is null!");
        }
    }

    /// 
    /// UnityWebRequest下载
    /// 
    /// 
    /// 地址
    /// 下载类型
    /// 结束回调
    /// 进度回调
    /// 
    private IEnumerator DownLoadByUnityWebRequest(string url, Action callback = null,Action proAction=null) where T : UnityEngine.Object
    {
        UnityWebRequest uwr = new UnityWebRequest(url);

        if (typeof(T) == typeof(AudioClip)) 
        {
            string _suf = PathTools.GetSuffix(url);
            AudioType at = AudioType.MPEG;
            if (_suf.Contains("ogg"))
                at = AudioType.OGGVORBIS;
            DownloadHandlerAudioClip downloadAudioClip = new DownloadHandlerAudioClip(url, at);
            uwr.downloadHandler = downloadAudioClip;
        }

        if (typeof(T) == typeof(Sprite)|| typeof(T) == typeof(Texture2D))
        {
            DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
            uwr.downloadHandler = downloadTexture;
        }

        uwr.SendWebRequest();
        while (true)
        {
            if (uwr.isNetworkError || uwr.isHttpError)
                break;

            if (uwr.isDone || uwr.downloadProgress >= 1) 
            {
                proAction?.Invoke(1);
                break;
            }
            else
                proAction?.Invoke(uwr.downloadProgress);
        }

        yield return uwr;

        if (!uwr.isNetworkError && !uwr.isHttpError)
        {
            if (typeof(T) == typeof(AudioClip))
            {
                AudioClip audioClip = ((DownloadHandlerAudioClip)uwr.downloadHandler).audioClip;
                callback.Invoke((T)(UnityEngine.Object)audioClip);
            }

            if (typeof(T) == typeof(Sprite))
            {
                Texture2D texture = ((DownloadHandlerTexture)uwr.downloadHandler).texture;
                Sprite sp = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);
                callback?.Invoke((T)(UnityEngine.Object)sp);
            }

            if (typeof(T) == typeof(Texture2D))
            {
                Texture2D texture1 = ((DownloadHandlerTexture)uwr.downloadHandler).texture;
                callback?.Invoke((T)(UnityEngine.Object)texture1);
            }

            //保存到本地
            if (url.Substring(0, 4) == "http")
            {
                File.WriteAllBytes(PathTools.GetSavePath(url), uwr.downloadHandler.data);
            }
        }
        else 
        {
            Debug.LogError("DownLoadByUnityWebRequest error:"+ uwr.error +"  url:"+url);
        }
    }


    /// 
    /// 下载文件
    /// 
    public void LoadFile(string url,string _suffix="", Action endAction = null, Action proAction = null) 
    {
        if (!string.IsNullOrEmpty(url+_suffix))
        {
            string path = PathTools.GetSavePath(url+_suffix);
            if (!File.Exists(path))
            {
                StartCoroutine(DownLoadFileByUnityWebRequest(url, _suffix, endAction, proAction));
            }
            else//已在本地缓存  
            {
                StartCoroutine(DownLoadFileByUnityWebRequest(path, _suffix, endAction, proAction));
            }
        }
        else
        {
            Debug.LogError("WebUtils error: url is null!");
        }
    }

    private IEnumerator DownLoadFileByUnityWebRequest(string url, string _suffix = "", Action callback = null, Action proAction = null) 
    {
       UnityWebRequest uwr =  UnityWebRequest.Get(url);
        uwr.SendWebRequest();

        while (true)
        {
            if (uwr.isNetworkError || uwr.isHttpError)
                break;

            if (uwr.isDone || uwr.downloadProgress >= 1)
            {
                proAction?.Invoke(1);
                break;
            }
            else
                proAction?.Invoke(uwr.downloadProgress);
        }

        yield return uwr;

        if (uwr.isNetworkError || uwr.isHttpError)
        {
            Debug.LogError("DownLoadByUnityWebRequest error:" + uwr.error + "  url:" + url);
        }
        else 
        {
            callback?.Invoke(uwr.downloadHandler.text.ToString());
            //保存到本地
            if (url.Substring(0, 4) == "http")
            {
                File.WriteAllBytes(PathTools.GetSavePath(url + _suffix), uwr.downloadHandler.data);
            }
        }
    }

}


路径工具脚本

using System.IO;
using UnityEngine;

/// 
/// 路径工具
/// 
public class PathTools
{
    /// 
    /// StreamPath路径
    /// 
    public static string StreamPath
    {
        get
        {
            return Application.streamingAssetsPath + "/Cache";
        }
    }

    /// 
    /// 缓存路径
    /// 
    public static string persistentPath
    {
        get
        {
            return Application.persistentDataPath + "/WebCache";
        }
    }

    static  string[] sufTypes = { "png","jpg","apk","mp3","ogg","txt","json"}; 
    /// 
    /// 获取资源的保存路径
    /// 
    public static string GetSavePath(string url) 
    {
        string _suffix = GetSuffix(url);
        string _name = "{0}." + _suffix;
        string path = Path.Combine(persistentPath, _suffix);
        CreatePath(path);
        path = Path.Combine(path, string.Format(_name, GetFileName(url)/*url.GetHashCode()*/)); ;
        return path;
    }

    /// 
    /// 解析后缀名
    /// 
    public static string GetFileName(string url)
    {
        string[] subArr = url.Split('.');
        string totalStr = subArr[subArr.Length - 2];
        string [] subArr1 = totalStr.Split('/');
        return subArr1[subArr1.Length-1];
    }

    /// 
    /// 解析后缀名
    /// 
    public static string GetSuffix(string url) 
    {
        string[] subArr = url.Split('.');
        string _suffix  = subArr[subArr.Length - 1];

        for (int i = 0; i < sufTypes.Length; i++)
        {
            if (_suffix.Contains(sufTypes[i]))
            {
                _suffix = sufTypes[i];
                break;
            }
        }
        return _suffix;
    }

    /// 
    /// 获取资源的加载路径
    /// 
    public static string GetLoadPath(string url)
    {
        return "file:///" + GetSavePath(url);
    }

    /// 
    /// 创建路径
    /// 
    static void CreatePath(string path) 
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
    }

    /// 
    /// 获取资源保存路径,打包时保存路径
    /// 
    public static string GetAssetOutPath(int target)
    {
        string path = "";
        switch (target)
        {
            case 5://win
                path = StreamPath + "/Android/";
                break;
            case 9://ios
                path = StreamPath + "/IOS/";
                break;
            case 13://android
                path = StreamPath + "/Android/";
                break;
        }
        return path;
    }

    /// 
    /// 不同平台下StreamingAssets的路径
    /// 
    public static readonly string dataPath =
#if UNITY_ANDROID && !UNITY_EDITOR
        "jar:file://" + Application.dataPath + "!/assets/";
#elif UNITY_IOS && !UNITY_EDITOR
        "file://" + Application.dataPath + "/Raw/";
#elif UNITY_STANDALONE_WIN
        "file://" + Application.dataPath + "/StreamingAssets/";
#else
        "file://" + Application.dataPath + "/StreamingAssets/";
#endif


    /// 
    /// 平台名称,下载时只区分安卓和ios,pc使用安卓的资源
    /// 
    public static readonly string platName =
#if UNITY_IOS 
         "IOS";
#else
       "Android";
#endif
}



调用方式

   WebUtils.Ins.Load(imgurl, (sp) =>
        {

            image.sprite = sp;
            Debug.Log("下载结束");

        }, (pro) =>
        {

            Debug.Log("进度:" + pro);

        });


        WebUtils.Ins.Load(audurl, (cp) =>
        {

            GetComponent().clip = cp;
            GetComponent().Play();
            Debug.Log("下载结束");

        }, (pro) =>
        {

            Debug.Log("进度:" + pro);

        });


        WebUtils.Ins.LoadFile(apkurl, (str) => {

            Debug.Log("下载结束:"+str);

        }, (pro) => {

            Debug.Log("进度:" + pro);

        });

再封装一下

using UnityEngine;
using UnityEngine.UI;

/// 
/// 加载工具
/// 
public class LoadUtils
{

    /// 
    ///  通过图集设置图片
    /// 
    public static void SetChildImage(Image image, string url,string name)
    {
        Sprite[] sprs = Resources.LoadAll(url);

        if (sprs != null && sprs.Length > 0)
        {
            foreach (var item in sprs)
            {
                if (item.name == name)
                {
                    image.sprite = item;
                }
            }
        }
        else
        {
            Debug.LogError("SetChildImage url error:"+url);
        }
    }

    /// 
    /// 设置图片
    /// 
    ///  地址
    ///  图片 
    ///  Resource下路径  填空直接再Resource中加载 
    public static void SetImage(string url,Image image, string befor ="")
    {
        if (string.IsNullOrEmpty(url) || image == null)
        {
            return;
        }
        //网图
        if (url.Substring(0, 4) == "http")
        {
            WebUtils.Ins.Load(url, (sp) =>
            {
                image.sprite = sp;
            });
        }
        else //Resources加载
        {
            string[] strs = url.Split('.');
            if (strs.Length > 1) 
            {
                url = strs[0];
            }

            url = befor +"/"+ url;

            Sprite spri = ResourceLoader.Ins.Load(url);

            if (spri != null)
            {
                image.sprite = spri;
            }
            else
            {
                Debug.LogError("LoadUtils SetImage error: " + url);
            }
        }
    }

    /// 
    /// 设置音频
    /// 
    public static void SetAudio(string url, AudioSource audio, string befor = "")
    {
        if (string.IsNullOrEmpty(url) || audio == null)
        {
            return;
        }

        if (url.Substring(0, 4) == "http")
        {
            WebUtils.Ins.Load(url, (clip) =>
            {
                audio.clip = clip;
                audio.Play();
            });
        }
        else
        {
            string[] strs = url.Split('.');
            if (strs.Length > 1) 
            {
                url = strs[0];
            }

            url = befor + url;
            AudioClip clip = ResourceLoader.Ins.Load(url);
            audio.clip = clip;
            audio.Play();
        }
    }

}

调用

        LoadUtils.SetImage("icon_chongwu_moren@2x", image, "Texture");
        LoadUtils.SetAudio("2147463780", GetComponent());

你可能感兴趣的:(2020-11-03 Unity 使用UnityWebRequest下载图片 音频 APk等功能实现)