赞
踩
using System; using System.Collections; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; public class UnityWebRequestDemo : MonoBehaviour { /* * 一.概述 * UnityWebRequest支持与上传,下载及断点续传功能。 * UnityWebRequest由三个元素组成: * 1. UploadHandler 处理数据将数据上传到服务器的对象 * 2. DownloadHandler 从服务器下载数据的对象 * 3. UnityWebRequest 负责与Http进行通信并管理上面两个对象 * * 常用的方法: * SendWebRequest():开始与远程服务器通信。在调用此方法之后,有必要的话UnityWebRequest将执行DNS解析,将HTTP请求发送到目标URL的远程服务器并处理服务器的响应 * Get(url): 创建一个HTTP为传入URL的UnityWebRequest对象 * Post(url): 向Web服务器发送表单信息 * Put(url): 将数据上传到Web服务器 * Abort(): 直接结束联网 * Head(): 创建一个为传输Http头请求的UnityWebRequest对象 * GetResponseHeader(): 返回一个字典,内容为在最新的HTTP响应中收到的所有响应头 */ /* * 二.构造函数 * public UnityWebRequest(); * public UnityWebRequest(Uri uri); * public UnityWebRequest(Uri uri,string method); * public UnityWebRequest(Uri uri,string method,Networking.DownloadHandler downloadHandler,Networking.UploadHandler uploadHandler); * 参数含义: * method:相当于方法,只有GET、POST、PUT、HEAD四种,默认为GET,一旦调用SendWebRequest(),就无法更改 * downloadHandler:下载数据的委托方法 * uploadHandler:上传数据的委托方法 */ private void Start() { // Get(); // Post(); // Put(); // Head(); // GetResponseHeader(); // DownLoadFile(); // BreakpointDownload(); } #region GET /* * Get方法,创建一个 UnityWebReqest对象,参数传入URL。 */ void Get() { StartCoroutine(SendRequest_Get()); } IEnumerator SendRequest_Get() { UnityWebRequest unityWebRequest = UnityWebRequest.Get("http://www.baidu.com"); //创建UnityWebRequest对象 yield return unityWebRequest.SendWebRequest(); //等待返回请求的信息 if (unityWebRequest.result == UnityWebRequest.Result.ProtocolError || unityWebRequest.result == UnityWebRequest.Result.ConnectionError) //如果其 请求失败,或是 网络错误 { Debug.Log(unityWebRequest.error); //打印错误原因 } else //请求成功 { Debug.Log("Get:请求成功"); //如果访问的链接有返回文本结果,比如json文本,则通过text获取 string result = unityWebRequest.downloadHandler.text; Debug.Log(result); //如果访问的是资源链接,比如图片,则通过data拿到图片二进制流 //byte[] data = uwr.downloadHandler.data; } } #endregion #region POST /* * Post方法将一个表上传到远程的服务器,一般来说我们登陆某个网站的时候会用到这个方法,我们的账号密码会以一个表单的形式传过去。 */ void Post() { StartCoroutine(SendRequest_Post()); } IEnumerator SendRequest_Post() { WWWForm form = new WWWForm(); //键值对 form.AddField("key", "value"); form.AddField("name", "Chinar"); //请求链接,并将form对象发送到远程服务器 UnityWebRequest webRequest = UnityWebRequest.Post("http://www.baidu.com", form); yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.ProtocolError || webRequest.result == UnityWebRequest.Result.ConnectionError) //如果其 请求失败,或是 网络错误 { Debug.Log(webRequest.error); } else { Debug.Log("发送成功"); } } #endregion #region PUT /* * Put方法将数据发送到远程的服务器。 */ void Put() { StartCoroutine(SendRequest_Put()); } IEnumerator SendRequest_Put() { byte[] myData = System.Text.Encoding.UTF8.GetBytes("Chinar的测试数据"); using (UnityWebRequest webRequest = UnityWebRequest.Put("http://www.baidu.com", myData)) { yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.ProtocolError || webRequest.result == UnityWebRequest.Result.ConnectionError) //如果其 请求失败,或是 网络错误 { Debug.Log(webRequest.error); } else { Debug.Log("上传成功!"); } } } #endregion #region HEAD void Head() { StartCoroutine(SendRequest_Head()); } IEnumerator SendRequest_Head() { UnityWebRequest webRequest = UnityWebRequest.Head("http://www.chinar.xin/chinarweb/WebRequest/Get/00-效果.mp4"); //创建UnityWebRequest对象 yield return webRequest.SendWebRequest(); //等待返回请求的信息 if (webRequest.result == UnityWebRequest.Result.ProtocolError || webRequest.result == UnityWebRequest.Result.ConnectionError) //如果其 请求失败,或是 网络错误 { Debug.Log(webRequest.error); //打印错误原因 } else //请求成功 { Debug.Log("Head:请求成功"); } } #endregion #region Abort /* * Abort方法会尽快结束联网,可以随时调用此方法。 *如果 UnityWebRequest尚未完成,那么 UnityWebRequest将尽快停止上传或下载数据。 中止的 UnityWebRequests被认为遇到了系统错误 。 *isNetworkError或isHttpError属性将返回true,error属性将为“User Aborted”。 */ #endregion #region GetResponseHeader /* * GetResponseHeader方法可以用来获取请求文件的长度 传入参数 "Content-Length"字符串,表示获取文件内容长度。 */ void GetResponseHeader() { StartCoroutine(SendRequest_GetResponseHeader()); } IEnumerator SendRequest_GetResponseHeader() { UnityWebRequest webRequest = UnityWebRequest.Head( "http://www.chinar.xin/chinarweb/WebRequest/Get/00-效果.mp4"); //创建UnityWebRequest对象 yield return webRequest.SendWebRequest(); //等待返回请求的信息 if (webRequest.result == UnityWebRequest.Result.ProtocolError || webRequest.result == UnityWebRequest.Result.ConnectionError) //如果其 请求失败,或是 网络错误 { Debug.Log(webRequest.error); //打印错误原因 } else //请求成功 { long totalLength = long.Parse(webRequest.GetResponseHeader("Content-Length")); //首先拿到文件的全部长度 Debug.Log("totalLength"); //打印文件长度 } } #endregion /* * -------------------------------------------常用属性------------------------------------------- * 属性 类型 含义 * timeout int 等待时间(秒)超过此数值是 UnityWebReqest的尝试连接将终止 * UnityWebRequest.Result.ProtocolError bool HTTP响应出现出现错误 * UnityWebRequest.Result.ConnectionError bool 系统出现错误 * error string 描述 UnityWebRequest对象在处理HTTP请求或响应时遇到的任何系统错误 * downloadProgress float 表示从服务器下载数据的进度 * uploadProgress float 表示从服务器上传数据的进度 * isDone bool 是否完成与远程服务器的通信 */ #region DownloadFill public Slider ProgressBar; //进度条 public Text SliderValue; //滑动条值 public Button startBtn; //开始按钮 void DownLoadFile() { //初始化进度条和文本框 ProgressBar.value = 0; SliderValue.text = "0.0%"; startBtn.onClick.AddListener(OnClickStartDownload); } /// <summary> /// 回调函数:开始下载 /// </summary> public void OnClickStartDownload() { StartCoroutine(DownloadFile()); } /// <summary> /// 协程:下载文件 /// </summary> IEnumerator DownloadFile() { UnityWebRequest uwr = UnityWebRequest.Get( "file:///C:/Users/Administrator/Music/VipSongsDownload/全昭弥 (전소미) - What You Waiting For.mflac"); //创建UnityWebRequest对象,将Url传入 uwr.SendWebRequest(); //开始请求 if (uwr.isNetworkError || uwr.isHttpError) //如果出错 { Debug.Log(uwr.error); //输出 错误信息 } else { while (!uwr.isDone) //只要下载没有完成,一直执行此循环 { ProgressBar.value = uwr.downloadProgress; //展示下载进度 SliderValue.text = Math.Floor(uwr.downloadProgress * 100) + "%"; yield return 0; } if (uwr.isDone) //如果下载完成了 { print("完成"); ProgressBar.value = 1; //改变Slider的值 SliderValue.text = 100 + "%"; } byte[] results = uwr.downloadHandler.data; // 注意真机上要用Application.persistentDataPath CreateFile(Application.streamingAssetsPath + "/MP4/test.mp4", results, uwr.downloadHandler.data.Length); //事先要在StreamingAssets创建一个MP4文件夹 AssetDatabase.Refresh(); //Asset资源刷新 } } /// <summary> /// 这是一个创建文件的方法 /// </summary> /// <param name="path">保存文件的路径</param> /// <param name="bytes">文件的字节数组</param> /// <param name="length">数据长度</param> void CreateFile(string path, byte[] bytes, int length) { Stream swream; FileInfo file = new FileInfo(path); if (!file.Exists) { swream = file.Create(); } else { return; } swream.Write(bytes, 0, length); swream.Close(); swream.Dispose(); } #endregion #region BreakpointDownload 断点续传 private bool _isStop; //是否暂停 public Slider _ProgressBar; //进度条 public Text _SliderValue; //滑动条值 public Button _startBtn; //开始按钮 public Button pauseBtn; //暂停按钮 private string Url = "file:///C:/Users/Administrator/Music/VipSongsDownload/全昭弥 (전소미) - What You Waiting For.mflac"; void BreakpointDownload() { //初始化进度条和文本框 _ProgressBar.value = 0; _SliderValue.text = "0.0%"; startBtn.onClick.AddListener(SatrtDownload); pauseBtn.onClick.AddListener(OnClickStop); } /// <summary> /// 回调函数:开始下载 /// </summary> public void SatrtDownload() { // 注意真机上要用Application.persistentDataPath StartCoroutine(DownloadFile(Url, Application.streamingAssetsPath + "/MP4/test.mp4", CallBack)); } /// <summary> /// 协程:下载文件 /// </summary> /// <param name="url">请求的Web地址</param> /// <param name="filePath">文件保存路径</param> /// <param name="callBack">下载完成的回调函数</param> /// <returns></returns> IEnumerator DownloadFile(string url, string filePath, Action callBack) { UnityWebRequest huwr = UnityWebRequest.Head(url); //Head方法可以获取到文件的全部长度 yield return huwr.SendWebRequest(); if (huwr.isNetworkError || huwr.isHttpError) //如果出错 { Debug.Log(huwr.error); //输出 错误信息 } else { long totalLength = long.Parse(huwr.GetResponseHeader("Content-Length")); //首先拿到文件的全部长度 string dirPath = Path.GetDirectoryName(filePath); if (!Directory.Exists(dirPath)) //判断路径是否存在 { Directory.CreateDirectory(dirPath); } //创建一个文件流,指定路径为filePath,模式为打开或创建,访问为写入 using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write)) { long nowFileLength = fs.Length; //当前文件长度 Debug.Log(fs.Length); if (nowFileLength < totalLength) { Debug.Log("还没下载完成"); fs.Seek(nowFileLength, SeekOrigin.Begin); //从头开始索引,长度为当前文件长度 UnityWebRequest uwr = UnityWebRequest.Get(url); //创建UnityWebRequest对象,将Url传入 uwr.SetRequestHeader("Range", "bytes=" + nowFileLength + "-" + totalLength); uwr.SendWebRequest(); //开始请求 if (uwr.isNetworkError || uwr.isHttpError) //如果出错 { Debug.Log(uwr.error); //输出 错误信息 } else { long index = 0; //从该索引处继续下载 while (nowFileLength < totalLength) //只要下载没有完成,一直执行此循环 { if (_isStop) break; yield return null; byte[] data = uwr.downloadHandler.data; if (data != null) { long length = data.Length - index; fs.Write(data, (int) index, (int) length); //写入文件 index += length; nowFileLength += length; ProgressBar.value = (float) nowFileLength / totalLength; SliderValue.text = Math.Floor((float) nowFileLength / totalLength * 100) + "%"; if (nowFileLength >= totalLength) //如果下载完成了 { ProgressBar.value = 1; //改变Slider的值 SliderValue.text = 100 + "%"; callBack?.Invoke(); break; } } } } } } } } /// <summary> /// 下载完成后的回调函数 /// </summary> void CallBack() { Debug.Log("下载完成"); } /// <summary> /// 暂停下载 /// </summary> public void OnClickStop() { if (_isStop) { pauseBtn.GetComponentInChildren<Text>().text = "暂停下载"; Debug.Log("继续下载"); _isStop = !_isStop; OnClickStartDownload(); } else { pauseBtn.GetComponentInChildren<Text>().text = "继续下载"; Debug.Log("暂停下载"); _isStop = !_isStop; } } #endregion }
参考了 林新发 的文章,把内容都写入代码中方便查看和加深印象。
原文链接:https://linxinfa.blog.csdn.net/article/details/94436027
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。