2020-11-03 Unity 使用UnityWebRequest下載圖片 音頻 APk等功能實現(xiàn)

在工作中經(jīng)常會需要下載網(wǎng)絡圖片硅则,或者音頻等功能霞篡,所以封裝了這個下載腳本。
功能需求:為了高效率和節(jié)省流量嚎幸,再本地有該文件時不再重復下載
可以回傳下載進度,下載后的資源
調用方式簡單

用來下載的腳本

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

/// <summary>
/// 圖片緩存
/// </summary>
public class WebUtils : SingletonObject<WebUtils>
{

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

    /// <summary>
    /// UnityWebRequest下載
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="url">地址</param>
    /// <param name="type">下載類型</param>
    /// <param name="callback">結束回調</param>
    /// <param name="proAction">進度回調</param>
    /// <returns></returns>
    private IEnumerator DownLoadByUnityWebRequest<T>(string url, Action<T> callback = null,Action<float> 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);
        }
    }


    /// <summary>
    /// 下載文件
    /// </summary>
    public void LoadFile(string url,string _suffix="", Action<string> endAction = null, Action<float> 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<string> callback = null, Action<float> 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;

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

    /// <summary>
    /// 緩存路徑
    /// </summary>
    public static string persistentPath
    {
        get
        {
            return Application.persistentDataPath + "/WebCache";
        }
    }

    static  string[] sufTypes = { "png","jpg","apk","mp3","ogg","txt","json"}; 
    /// <summary>
    /// 獲取資源的保存路徑
    /// </summary>
    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;
    }

    /// <summary>
    /// 解析后綴名
    /// </summary>
    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];
    }

    /// <summary>
    /// 解析后綴名
    /// </summary>
    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;
    }

    /// <summary>
    /// 獲取資源的加載路徑
    /// </summary>
    public static string GetLoadPath(string url)
    {
        return "file:///" + GetSavePath(url);
    }

    /// <summary>
    /// 創(chuàng)建路徑
    /// </summary>
    static void CreatePath(string path) 
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
    }

    /// <summary>
    /// 獲取資源保存路徑寄猩,打包時保存路徑
    /// </summary>
    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;
    }

    /// <summary>
    /// 不同平臺下StreamingAssets的路徑
    /// </summary>
    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


    /// <summary>
    /// 平臺名稱嫉晶,下載時只區(qū)分安卓和ios,pc使用安卓的資源
    /// </summary>
    public static readonly string platName =
#if UNITY_IOS 
         "IOS";
#else
       "Android";
#endif
}



調用方式

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

            image.sprite = sp;
            Debug.Log("下載結束");

        }, (pro) =>
        {

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

        });


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

            GetComponent<AudioSource>().clip = cp;
            GetComponent<AudioSource>().Play();
            Debug.Log("下載結束");

        }, (pro) =>
        {

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

        });


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

            Debug.Log("下載結束:"+str);

        }, (pro) => {

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

        });

再封裝一下

using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 加載工具
/// </summary>
public class LoadUtils
{

    /// <summary>
    ///  通過圖集設置圖片
    /// </summary>
    public static void SetChildImage(Image image, string url,string name)
    {
        Sprite[] sprs = Resources.LoadAll<Sprite>(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);
        }
    }

    /// <summary>
    /// 設置圖片
    /// </summary>
    /// <param name="url"> 地址</param>
    /// <param name="image"> 圖片 </param>
    /// <param name="befor"> Resource下路徑  填空直接再Resource中加載 </param>
    public static void SetImage(string url,Image image, string befor ="")
    {
        if (string.IsNullOrEmpty(url) || image == null)
        {
            return;
        }
        //網(wǎng)圖
        if (url.Substring(0, 4) == "http")
        {
            WebUtils.Ins.Load<Sprite>(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<Sprite>(url);

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

    /// <summary>
    /// 設置音頻
    /// </summary>
    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<AudioClip>(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<AudioClip>(url);
            audio.clip = clip;
            audio.Play();
        }
    }

}

調用

        LoadUtils.SetImage("icon_chongwu_moren@2x", image, "Texture");
        LoadUtils.SetAudio("2147463780", GetComponent<AudioSource>());
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市车遂,隨后出現(xiàn)的幾起案子封断,更是在濱河造成了極大的恐慌,老刑警劉巖舶担,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坡疼,死亡現(xiàn)場離奇詭異,居然都是意外死亡衣陶,警方通過查閱死者的電腦和手機柄瑰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剪况,“玉大人教沾,你說我怎么就攤上這事∫攵希” “怎么了授翻?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長孙咪。 經(jīng)常有香客問我堪唐,道長,這世上最難降的妖魔是什么翎蹈? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任淮菠,我火速辦了婚禮,結果婚禮上荤堪,老公的妹妹穿的比我還像新娘合陵。我一直安慰自己,他們只是感情好澄阳,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布拥知。 她就那樣靜靜地躺著,像睡著了一般碎赢。 火紅的嫁衣襯著肌膚如雪举庶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天揩抡,我揣著相機與錄音户侥,去河邊找鬼。 笑死峦嗤,一個胖子當著我的面吹牛蕊唐,可吹牛的內容都是我干的。 我是一名探鬼主播烁设,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼替梨,長吁一口氣:“原來是場噩夢啊……” “哼钓试!你這毒婦竟也來了?” 一聲冷哼從身側響起副瀑,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤弓熏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后糠睡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽鞠,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年狈孔,在試婚紗的時候發(fā)現(xiàn)自己被綠了信认。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡均抽,死狀恐怖嫁赏,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情油挥,我是刑警寧澤潦蝇,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站深寥,受9級特大地震影響攘乒,放射性物質發(fā)生泄漏。R本人自食惡果不足惜翩迈,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一持灰、第九天 我趴在偏房一處隱蔽的房頂上張望盔夜。 院中可真熱鬧负饲,春花似錦、人聲如沸喂链。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椭微。三九已至洞坑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝇率,已是汗流浹背迟杂。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留本慕,地道東北人排拷。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像锅尘,于是被迫代替她去往敵國和親监氢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359