美文网首页
2020-11-03 Unity 使用UnityWebReque

2020-11-03 Unity 使用UnityWebReque

作者: VECTOR_Y | 来源:发表于2020-11-03 11:09 被阅读0次

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

    用来下载的脚本

    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>
        /// 创建路径
        /// </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>
        /// 平台名称,下载时只区分安卓和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;
            }
            //网图
            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>());
    

    相关文章

      网友评论

          本文标题:2020-11-03 Unity 使用UnityWebReque

          本文链接:https://www.haomeiwen.com/subject/kbsbvktx.html