详解UnityWebRequest类

什么是UnityWebRequest类

UnityWebRequest 是 Unity 引擎中用于处理网络请求的一个强大类,它可以让你在 Unity 项目里方便地与网络资源进行交互,像发送 HTTP 请求、下载文件等操作都能实现。下面会详细介绍 UnityWebRequest 的相关内容。

UnityWebRequest中的常用操作

//1.使用Get获取文本或二进制数据

//2.使用Get获取纹理数据

//3.使用Get获取AB包数据

//4.使用Post请求发送数据

//5.使用Put请求上传数据

Get操作

cs 复制代码
       #region 知识点三 Get获取操作
        //1.获取文本或2进制
        StartCoroutine(DownLoadText());
        //2.获取纹理
        StartCoroutine(DownLoadImage());
        //3.获取AB包
        StartCoroutine(DownLoadAB());
        #endregion 
    }
    IEnumerator DownLoadText()
    {
        UnityWebRequest req = UnityWebRequest.Get("http://172.41.2.6/HTTP_Server/");
        //就会等待服务器端响应后 断开连接后 再继续执行后面的内容
        yield return req.SendWebRequest();
        //如果处理成功,结果就是成功枚举
        if(req.result ==UnityWebRequest.Result.Success)
        {
            //文本 字符串
            print(req.downloadHandler.text);
            //字节数组
            byte[] bytes = req.downloadHandler.data;
        }
        else
        {
            print("获取失败:" + req.result + req.error + req.responseCode);
        }
    }
    IEnumerator DownLoadImage()
    {
        UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/测试图片.png");
        yield return req.SendWebRequest();
        if(req.result ==UnityWebRequest.Result.Success )
        {
            //(req.downloadHandler as DownloadHandlerTexture).texture;
            //DownloadHandlerTexture.GetContent(req);
            //image.texture =(req.downloadHandler as DownloadHandlerTexture).texture;
            image.texture = DownloadHandlerTexture.GetContent(req);
        }
        else
        {
            print("获取失败" + req.error + req.result + req.responseCode);
        }
    }
    IEnumerator DownLoadAB()
    {
        UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("http://172.41.2.6/HTTP_Server/lua");
        //yield return req.SendWebRequest();
        req.SendWebRequest();
        while(!req .isDone )
        {
            print(req.downloadProgress);
            print(req.downloadedBytes);
            yield return null;
        }
        if(req .result ==UnityWebRequest.Result.Success )
        {
            //AssetBundle ab=(req.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
            AssetBundle ab = DownloadHandlerAssetBundle.GetContent(req);
        }
        else
            print("获取失败" + req.error + req.result + req.responseCode);
    }

Post和Put操作

上传数据相关类

cs 复制代码
       #region 知识点一 上传相关数据类
        //父接口
        //IMultipartFromSection
        //数据相关类都继承该接口
        //我们可以用父类装子类
        List<IMultipartFormSection> dataList = new List<IMultipartFormSection>();
        //子类数据
        //MutipartFromDataSection
        //1.二进制字节数组
        dataList.Add(new MultipartFormDataSection(Encoding.UTF8.GetBytes("23399ffs")));
        //2.字符串
        dataList.Add(new MultipartFormDataSection("sjfjgnafd"));
        //3.参数名、参数值(字节数组、字符串)、编码类型、资源类型(常用)
        dataList.Add(new MultipartFormDataSection("Name", "DamnF", Encoding.UTF8, "application/..."));
        dataList.Add(new MultipartFormDataSection("msg", new byte[1024], "appl...."));

        //MultipartFromFileSection
        //1.字节数组
        dataList.Add(new MultipartFormFileSection(File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")));
        //2.文件名、字节数组(常用)
        dataList.Add(new MultipartFormFileSection("上传的文件.png", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")));
        //3.字符串数据、文件名(常用)
        dataList.Add(new MultipartFormFileSection("2r0402099", "text.txt"));
        //4.字符串数据、编码格式、文件名(常用)
        dataList.Add(new MultipartFormFileSection("299ffjej3", Encoding.UTF8, "test.txt"));
        //5.表单名、字节数组、文件名、文件类型
        dataList.Add(new MultipartFormFileSection("file", new byte[1024], "test.txt", ""));
        //6.表单名、字符串数据、编码格式、文件名
        dataList.Add(new MultipartFormFileSection("file", "dggt4hdsgg", Encoding .UTF8, ""));
        #endregion

Post和Put

cs 复制代码
       #region 知识点二 Post发送相关
        StartCoroutine(UpLoad());
        #endregion
        #region 知识点三 Put上传相关
        //注意:Put请求类型不是所有的web服务器都认,必须要服务器处理该请求才能有响应

        #endregion 
    }
    IEnumerator UpLoad()
    {
        //准备上传的数据
        List<IMultipartFormSection> dataList = new List<IMultipartFormSection>();
        //键值对相关的 信息 字段数据
        dataList.Add(new MultipartFormDataSection("Name", "DamnF"));
        //PlayerMsg msg = new PlayerMsg();
        //dataList.Add(new MultipartFormDataSection("Msg", msg.Writing()));
        //添加一些上传文件
        //传2进制文件
        dataList.Add(new MultipartFormFileSection("TestTest124.png", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png")));
        //传文本文件
        dataList.Add(new MultipartFormFileSection("12444515", "Test123.txt"));
        UnityWebRequest req = UnityWebRequest.Post("http://172.41.2.6/HTTP_Server/",dataList);
        req.SendWebRequest();
        while (!req.isDone)
        {
            print(req.uploadProgress);
            print(req.uploadedBytes);
            yield return null;
        }
        print(req.uploadProgress);
        print(req.uploadedBytes);

        if (req.result == UnityWebRequest.Result.Success)
        {
            print("上传成功");
            //req.downloadHandler.data;
        }
        else
            print("上传失败" + req.error + req.responseCode + req.result);
    }

    IEnumerator UpLoadPut()
    {
        UnityWebRequest req= UnityWebRequest.Put("http://172.41.2.6/HTTP_Server/", File.ReadAllBytes(Application.streamingAssetsPath + "/test.png"));
        yield return req.SendWebRequest();
        if(req.result ==UnityWebRequest.Result.Success )
        {
            print("上传put成功");
        }
        else
        {

        }
    }

UnityWebRequest中的高级操作

cs 复制代码
       #region 知识点一 UnityWebRequest高级操作指什么
        //高级操作是指让你按照规则来实现更多的数据获取、上传的功能
        #endregion
        #region 知识点二 UnityWebRequest中更多的内容
        //目前已学的内容
        //UnityWebRequest req = UnityWebRequest.Get("");
        //UnityWebRequest req = UnityWebRequestTexture.GetTexture("");
        //UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("");
        //UnityWebRequest req = UnityWebRequest.Put();
        //UnityWebRequest req = UnityWebRequest.Post();

        //req.isDone
        //req.downloadProgress
        //req.downloadProgress 
        //req.uploadedBytes
        //req.uploadProgress
        //req.SendWebRequest();

        //更多内容
        //1.构造函数
        UnityWebRequest req = new UnityWebRequest();
        //2.请求地址
        req.url = "服务器地址";
        //3.请求类型
        req.method = UnityWebRequest.kHttpVerbGET;
        //4.进度
        //req.downloadProgress
        //req.uploadProgress 
        //5.超时设置
        //req.timeout=2000;
        //6.上传、下载的字节数
        //req.uploadedBytes 
        //req.downloadedBytes 
        //7.重定向次数 设置为0表示不进行重定向 可以设置次数
        req.redirectLimit = 10;

        //8.状态码 结果 错误内容
        //req.result;
        //req.error;
        //req.responseCode;

        //9.下载、上传处理对象
        //req.downloadHandler;
        //req.uploadHandler;
        #endregion 
        #region 知识点三 自定义获取数据DownloadHandler相关类
        //关键类:
        //1.DownloadHandlerBuffer 用于简单的数据存储,得到对应的2进制数据
        //2.DownloadHandlerFile 用于下载文件并将文件保存到磁盘(内存占用少)
        //3.DownloasHandlerTexture 用于下载图像
        //4.DownloadHandlerAssetBundle 用于提取AssetBundle
        //5.DownloadHandlerAudioClip 用于下载音频文件

        //以上的类,其实是Unity帮我们实现好的,用于解析下载下来的数据的类
        //使用对应的类处理下载数据 它们就会在内部将下载好的数据处理为对应类型,方便我们使用
        //DownloadHandlerScript 是一个特殊的类 就本身而言 不会执行任何操作
        //但是此类可由用户定义的类继承。此类接收来自UnityWebRequest系统的回调
        //然后可以使用这些回调在数据从网络到达时执行完全自定义的数据处理
        StartCoroutine(DownLoadTex());
        StartCoroutine(DownLoadAB());
        StartCoroutine(DownLoadAudioClip());
        #endregion

    }
    IEnumerator DownLoadTex()
    {
        UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/测试图片.png"
                                                 , UnityWebRequest.kHttpVerbGET);
        //req.method = UnityWebRequest.kHttpVerbGET;
        //1.DownloadHandlerBuffer
        DownloadHandlerBuffer bufferHandler = new DownloadHandlerBuffer();
        req.downloadHandler = bufferHandler;
        //2.DownloadHandlerFile
        req.downloadHandler = new DownloadHandlerFile(Application.persistentDataPath + "/downloadfile.png");
        //3.DownloadHandlerTexture
        DownloadHandlerTexture handlerTexture = new DownloadHandlerTexture();
        req.downloadHandler = handlerTexture;
        yield return req.SendWebRequest();
        if(req.result ==UnityWebRequest.Result.Success )
        {
            //获取字节数组
            //bufferHandler.data
        }
        else
        {
            print("获取数据失败" + req.result + req.error + req.responseCode);
        }
    }

    IEnumerator DownLoadAB()
    {
        UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/lua", UnityWebRequest.kHttpVerbGET);
        //第二个参数,需要已知校检码 才能进行比较 检查完整性 如果不知道的话 只能传0 不进行完整性检查
        //所以一般 只有进行AB包热更新时 服务器发送了 对应的 文件列表中 包含了 验证码才能进行检查
        DownloadHandlerAssetBundle downloadHandlerAB = new DownloadHandlerAssetBundle(req.url, 0);
        req.downloadHandler = downloadHandlerAB;
        yield return req.SendWebRequest();
        if (req.result == UnityWebRequest.Result.Success)
        {
            AssetBundle ab = downloadHandlerAB.assetBundle;
            print(ab.name);
        }
        else
        {
            print("获取数据失败" + req.result + req.error + req.responseCode);
        }
    }
    IEnumerator DownLoadAudioClip()
    {
        UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("http://172.41.2.6/HTTP_Server/音效文件.mp3",
                                                                      AudioType.MPEG);
        yield return req.SendWebRequest();

        if (req.result == UnityWebRequest.Result.Success)
        {
            AudioClip a= DownloadHandlerAudioClip .GetContent(req);
        }
        else
        {
            print("获取数据失败" + req.result + req.error + req.responseCode);
        }
    }

    IEnumerator DownLoadCustomHandler()
    {
        UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/测试图片.png", UnityWebRequest.kHttpVerbGET);
        req.downloadHandler = new CustomDownLoadFileHandler(Application.persistentDataPath + "/CustomHandler.png");
        yield return req.SendWebRequest();
        if (req.result == UnityWebRequest.Result.Success)
        {
            print("存储本地成功");
        }
        else
        {
            print("获取数据失败" + req.result + req.error + req.responseCode);
        }
    }

自定义获取数据处理

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class DownLoadHanderMsg :DownloadHandlerScript
{
    private BaseMsg msg;
    private int index = 0;
    private byte[] cacheBytes;
    public DownLoadHanderMsg ():base()
    {

    }
    public T GetMsg<T>()where T:BaseMsg
    {
        return msg as T;
    }
    protected override byte[] GetData()
    {
        return base.GetData();
    }
    protected override void ReceiveContentLengthHeader(ulong contentLength)
    {
        base.ReceiveContentLengthHeader(contentLength);
    }
    protected override bool ReceiveData(byte[] data, int dataLength)
    {
        data.CopyTo(cacheBytes, dataLength);
        index += dataLength;
        return true;
    }
    protected override void CompleteContent()
    {
        index = 0;
        int msgID = BitConverter.ToInt32(cacheBytes,index);
        index += 4;
        int msgLength = BitConverter.ToInt32(cacheBytes, index);
        index += 4;
        switch (msgID)
        {
            case 1001:
                msg = new PlayerMsg();
                msg.Reading(cacheBytes, index);
                break;
        }
        if (msg == null)
        {
            Debug.Log("对应ID" + msgID + "没有处理");
        }
        else
            Debug.Log("消息处理完毕");
    }
}
cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Lesson34_E : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }
    IEnumerator GetMsg()
    {
        UnityWebRequest req = new UnityWebRequest("Web服务器地址", UnityWebRequest.kHttpVerbPOST);
        DownLoadHanderMsg  handlerMsg= new DownLoadHanderMsg();
        req.downloadHandler = handlerMsg;
        yield return req.SendWebRequest();
        if(req.result ==UnityWebRequest.Result.Success )
        {
            PlayerMsg msg = handlerMsg.GetMsg<PlayerMsg>();
            //使用消息对象,来进行逻辑处理
        }
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

UnityWebRequest高级操作--上传数据

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class Lesson35 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region UnityWebRequest高级操作--上传数据
        //1.UploadHandlerRaw--用于上传字节数组
        //2.UploadHandlerFile--用于上传文件

        //其中重要的变量是
        //contentType 内容类型,如果不设置,模式是application/octet-stream 2进制流的形式

        //以上部分作为了解,实际开发并不常用
        #endregion
    }
    IEnumerator UpLoad()
    {
        UnityWebRequest req = new UnityWebRequest("http://172.41.2.6/HTTP_Server/", UnityWebRequest.kHttpVerbPOST);
        //1.UploadHandlerRaw--用于上传字节数组
        //byte[] bytes = Encoding.UTF8.GetBytes("23fe33h3h3h");
        //req.uploadHandler = new UploadHandlerRaw(bytes);
        req.uploadHandler.contentType = "类型/细分类型";

        //2.UploadHandlerFile--用于上传文件
        req.uploadHandler = new UploadHandlerFile(Application.streamingAssetsPath + "/test.png");

        yield return req.SendWebRequest();
        print(req.result);
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

将UnityWebRequest中的操作封装到WWWMgr模块中

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;

public class WWWMgr : MonoBehaviour
{
    private static WWWMgr instance = new WWWMgr();
    public static WWWMgr Instance => instance;

    private string HTTP_SERVER_PATH = "http://172.41.2.6/HTTP_Server/";
    private void Awake()
    {
        instance = this;
        DontDestroyOnLoad(this.gameObject);
    }
    public void LoadRes<T>(string path, UnityAction<T> action) where T : class
    {
        StartCoroutine(LoadResAsync<T>(path, action));
    }
    private IEnumerator LoadResAsync<T>(string path, UnityAction<T> action) where T : class
    {
        WWW www = new WWW(path);
        yield return www;
        if (www.error == null)
        {
            //根据T泛型的类型 决定使用哪种类型的资源 传递给外部
            if (typeof(T) == typeof(AssetBundle))
            {
                action?.Invoke(www.assetBundle as T);
            }
            else if (typeof(T) == typeof(Texture))
            {
                action?.Invoke(www.texture as T);
            }
            else if (typeof(T) == typeof(AudioClip))
            {
                action?.Invoke(www.GetAudioClip() as T);
            }
            else if (typeof(T) == typeof(string))
            {
                action?.Invoke(www.text as T);
            }
            else if (typeof(T) == typeof(byte[]))
            {
                action?.Invoke(www.bytes as T);
            }
        }
        else
        {
            Debug.LogError("加载资源出错了" + www.error);
        }

    }
    
    public void UnityWebRequestLoad<T>(string path,UnityAction <T>action,string localPath="",AudioType type=AudioType.MPEG )where T:class 
    {
        StartCoroutine(UnityWebRequestLoadAsync<T>(path, action, localPath, type));
    }
    private IEnumerator UnityWebRequestLoadAsync<T>(string path, UnityAction<T> action, string localPath = "", AudioType type = AudioType.MPEG) where T:class 
    {
        UnityWebRequest req = new UnityWebRequest(path, UnityWebRequest.kHttpVerbGET);
        if (typeof(T) == typeof(byte[]))
            req.downloadHandler = new DownloadHandlerBuffer();
        else if (typeof(T) == typeof(Texture))
            req.downloadHandler = new DownloadHandlerTexture();
        else if (typeof(T) == typeof(AssetBundle))
            req.downloadHandler = new DownloadHandlerAssetBundle(req.url, 0);
        else if (typeof(T) == typeof(object))
            req.downloadHandler = new DownloadHandlerFile(localPath);
        else if (typeof(T) == typeof(AudioClip))
            req = UnityWebRequestMultimedia.GetAudioClip(path, type);
        else //如果出现没有的类型 就不用继续执行
        {
            Debug.LogWarning("未知类型" + typeof(T));
            yield break;
        }
        yield return req.SendWebRequest();
        if(req.result ==UnityWebRequest.Result.Success )
        {
            if (typeof(T) == typeof(byte[]))
                action?.Invoke(req.downloadHandler.data as T);
            else if (typeof(T) == typeof(Texture))
                //action?.Invoke((req.downloadHandler as DownloadHandlerTexture).texture as T);
                action?.Invoke(DownloadHandlerTexture.GetContent(req) as T);
            else if (typeof(T) == typeof(AssetBundle))
                action?.Invoke((req.downloadHandler as DownloadHandlerAssetBundle).assetBundle as T);
            else if (typeof(T) == typeof(object))
                action?.Invoke(null);
            else if (typeof(T) == typeof(AudioClip))
                action?.Invoke(DownloadHandlerAudioClip.GetContent(req) as T);
        }
        else
        {
            Debug.LogWarning("获取数据失败" + req.result + req.error + req.responseCode);
        }
    }
    public void SendMsg<T>(BaseMsg msg,UnityAction<T>action)where T:BaseMsg 
    {
        StartCoroutine(SendMsgAsync<T>(msg, action));
    }
    private IEnumerator SendMsgAsync<T>(BaseMsg msg,UnityAction <T>action)where T:BaseMsg 
    {
        //消息发送
        WWWForm data = new WWWForm();
        //准备要发送的消息数据
        data.AddBinaryData("Msg", msg.Writing());
        WWW www = new WWW(HTTP_SERVER_PATH, data);
        //我们也可以直接传递 2进制字节数组 只要和后端制定好规则 怎么传都是可以的
        //WWW www = new WWW(HTTP_SERVER_PATH, msg.Writing());
        //异步等待 发送结束 才会继续执行后面的代码
        yield return www;
        //发送完毕后 收到响应
        //认为后端发回来的内容也是一个继承自BaseMsg类的字节数组对象
        if(www.error ==null)
        {
            //先解析 ID和消息长度
            int index = 0;
            int msgID = BitConverter.ToInt32(www.bytes, index);
            index += 4;
            int msgLength = BitConverter.ToInt32(www.bytes, index);
            index += 4;
            //反序列化 BaseMsg
            BaseMsg baseMsg = null;
            switch (msgID)
            {
                case 1001:
                    baseMsg = new PlayerMsg();
                    baseMsg.Reading(www.bytes, index);
                    break;
            }
            if (baseMsg != null)
                action?.Invoke(baseMsg as T);
            else
                Debug.LogError("发消息出现问题" + www.error);
        }
    }

    public void UpLoadFile(string fileName,string localName,UnityAction<UnityWebRequest .Result> action)
    {
        StartCoroutine(UpLoadFileAsync(fileName, localName, action));
    }
    private IEnumerator UpLoadFileAsync(string fileName,string localName,UnityAction<UnityWebRequest .Result> action)
    {
        List<IMultipartFormSection> dataList = new List<IMultipartFormSection>();
        dataList.Add(new MultipartFormDataSection(fileName, File.ReadAllBytes(localName)));
        UnityWebRequest req = UnityWebRequest.Post(HTTP_SERVER_PATH, dataList);
        yield return req.SendWebRequest();
        action?.Invoke(req.result);
        if (req.result != UnityWebRequest.Result.Success)
        {
            print("上传失败" + req.error + req.responseCode + req.result);
        }
    }
          
}
相关推荐
WXDcsdn19 分钟前
华为VRF技术基于三层交换机的应用实例
服务器·网络·华为
oMMh1 小时前
使用C# ASP.NET创建一个可以由服务端推送信息至客户端的WEB应用(1)
前端·c#·asp.net
冰茶_1 小时前
WPF之Button控件详解
大数据·学习·microsoft·c#·wpf
且听风吟ayan2 小时前
leetcode day37 474
leetcode·c#
会讲英语的码农2 小时前
[计算机网络]物理层
网络·计算机网络
christine-rr2 小时前
【25软考网工】第四章无线通信网(1)移动通信与4G/5G技术、CDMA计算
网络·5g·网络工程师·软考·考试
caimouse2 小时前
C#里创建一个TCP客户端连接类
java·网络·tcp/ip
大飞pkz3 小时前
【Unity】MVC的简单分享以及一个在UI中使用的例子
unity·c#·mvc·框架·ui框架·商业级ui框架
Tatalaluola3 小时前
unity在编辑器模式调试音频卡顿电流声
unity·游戏引擎