Unity网络请求方式UnityWebRequest

在unity2019中,“WWW"的资源加载方式过时了,新的方法为"UnityWebRequest”

UnityWebRequest 是什么

1.定义

官方文档里的说明:
UnityWebRequest 提供了一个模块化系统,用于构成 HTTP 请求和处理 HTTP 响应。UnityWebRequest 系统的主要目标是让 Unity 游戏与 Web 浏览器后端进行交互。该系统还支持高需求功能,例如分块 HTTP 请求、流式 POST/PUT 操作以及对 HTTP 标头和动词的完全控制。

在这里插入图片描述
在这里插入图片描述

2.常用操作:使用 HLAPI

本部分将详细介绍高级 API 中提供的选项以及目标用途。

2.1 从 HTTP 服务器检索文本或二进制数据 (GET)

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
 
public class MyBehaviour : MonoBehaviour {
    void Start() {
        StartCoroutine(GetText());
    } 
    IEnumerator GetText() {
        UnityWebRequest www = UnityWebRequest.Get("http://www.my-server.com");
        yield return www.SendWebRequest();
 
        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            // 将结果显示为文本
            Debug.Log(www.downloadHandler.text);
 
            // 或者以二进制数据格式检索结果
            byte[] results = www.downloadHandler.data;
        }
    }
}

2.2 从 HTTP 服务器检索纹理 (GET)

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
 
public class MyBehaviour : MonoBehaviour {
    void Start() {
        StartCoroutine(GetTexture());
    }
 
    IEnumerator GetTexture() {
        UnityWebRequest www = UnityWebRequestTexture.GetTexture("http://www.my-server.com/image.png");
        yield return www.SendWebRequest();

        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            Texture myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
        }
    }
}
或者也可以使用 helper getter 来实现 GetTexture:

    IEnumerator GetTexture() {
            UnityWebRequest www = UnityWebRequestTexture.GetTexture("http://www.my-server.com/image.png");
            yield return www.SendWebRequest();

            Texture myTexture = DownloadHandlerTexture.GetContent(www);
        }
从 HTTP 服务器检索文本或二进制数据 (GET)
从 HTTP 服务器下载 AssetBundle (GET)
版权所有 © 2020 Unity Technologies. Publication 2019.4教程社区答案知识库论坛Asset Store

2.3 从 HTTP 服务器下载 AssetBundle (GET)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
 
public class MyBehaviour : MonoBehaviour {
    void Start() {
        StartCoroutine(GetAssetBundle());
    }
 
    IEnumerator GetAssetBundle() {
        UnityWebRequest www = UnityWebRequest.GetAssetBundle("http://www.my-server.com/myData.unity3d");
        yield return www.SendWebRequest();
 
        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
        }
    }
}
从 HTTP 服务器检索纹理 (GET)
将表单发送到 HTTP 服务器 (POST)
版权所有 © 2020 Unity Technologies. Publication 2019.4教程社区答案知识库论坛Asset Store

2.4将表单发送到 HTTP 服务器 (POST)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;

public class MyBehavior : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Upload());
    }

    IEnumerator Upload()
    {
        List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
        formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));

        UnityWebRequest www = UnityWebRequest.Post("http://www.my-server.com/myform", formData);
        yield return www.SendWebRequest();

        if (www.isNetworkError || www.isHttpError)
        {
            Debug.Log(www.error);
        }
        else
        {
            Debug.Log("Form upload complete!");
        }
    }
}

2.5 将原始数据上传到 HTTP 服务器 (PUT)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
 
public class MyBehavior : MonoBehaviour {
    void Start() {
        StartCoroutine(Upload());
    }
 
    IEnumerator Upload() {
        byte[] myData = System.Text.Encoding.UTF8.GetBytes("This is some test data");
        UnityWebRequest www = UnityWebRequest.Put("http://www.my-server.com/upload", myData);
        yield return www.SendWebRequest();
 
        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            Debug.Log("Upload complete!");
        }
    }
}

3.高级操作:使用 LLAPI

3.1创建 UnityWebRequest

UnityWebRequest wr = new UnityWebRequest(); // 完全为空
UnityWebRequest wr2 = new UnityWebRequest("http://www.mysite.com"); // 设置目标 URL

// 必须提供以下两项才能让 Web 请求正常工作
wr.url = "http://www.mysite.com";
wr.method = UnityWebRequest.kHttpVerbGET;   // 可设置为任何自定义方法,提供了公共常量

wr.useHttpContinue = false;
wr.chunkedTransfer = false;
wr.redirectLimit = 0;  // 禁用重定向
wr.timeout = 60;       // 此设置不要太小,Web 请求需要一些时间

3.2 创建 UploadHandler

byte[] payload = new byte[1024];
// ...使用数据填充有效负载 ...

UnityWebRequest wr = new UnityWebRequest("http://www.mysite.com/data-upload");
UploadHandler uploader = new UploadHandlerRaw(payload);

// 发送标头:"Content-Type: custom/content-type";
uploader.contentType = "custom/content-type";

wr.uploadHandler = uploader;
创建 UnityWebRequest

3.3 创建 DownloadHandler

DownloadHandlers 有多种类型:
DownloadHandlerBuffer 用于简单的数据存储。

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

 
public class MyBehaviour : MonoBehaviour {
    void Start() {
        StartCoroutine(GetText());
    }
 
    IEnumerator GetText() {
        UnityWebRequest www = new UnityWebRequest("http://www.my-server.com");
        www.downloadHandler = new DownloadHandlerBuffer();
        yield return www.SendWebRequest();
 
        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            // 将结果显示为文本
            Debug.Log(www.downloadHandler.text);
 
            // 或者以二进制数据格式检索结果
            byte[] results = www.downloadHandler.data;
        }
    }
}

DownloadHandlerFile 用于下载文件并将文件保存到磁盘(内存占用少)。

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

public class FileDownloader : MonoBehaviour {

    void Start () {
        StartCoroutine(DownloadFile());
    }
    
    IEnumerator DownloadFile() {
        var uwr = new UnityWebRequest("https://unity3d.com/", UnityWebRequest.kHttpVerbGET);
        string path = Path.Combine(Application.persistentDataPath, "unity3d.html");
        uwr.downloadHandler = new DownloadHandlerFile(path);
        yield return uwr.SendWebRequest();
        if (uwr.isNetworkError || uwr.isHttpError)
            Debug.LogError(uwr.error);
        else
            Debug.Log("File successfully downloaded and saved to " + path);
    }
}

DownloadHandlerTexture 用于下载图像。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking; 
using System.Collections;

[RequireComponent(typeof(UnityEngine.UI.Image))]
public class ImageDownloader : MonoBehaviour {
    UnityEngine.UI.Image _img;
 
    void Start () {
        _img = GetComponent<UnityEngine.UI.Image>();
        Download("http://www.mysite.com/myimage.png");
    }
 
    public void Download(string url) {
        StartCoroutine(LoadFromWeb(url));
    }
 
    IEnumerator LoadFromWeb(string url)
    {
        UnityWebRequest wr = new UnityWebRequest(url);
        DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
        wr.downloadHandler = texDl;
        yield return wr.SendWebRequest();
        if(!(wr.isNetworkError || wr.isHttpError)) {
            Texture2D t = texDl.texture;
            Sprite s = Sprite.Create(t, new Rect(0, 0, t.width, t.height),
                                     Vector2.zero, 1f);
            _img.sprite = s;
        }
    }
}

DownloadHandlerAssetBundle 用于提取 AssetBundle。

using UnityEngine;
using UnityEngine.Networking; 
using System.Collections;
 
public class MyBehaviour : MonoBehaviour {
    void Start() {
        StartCoroutine(GetAssetBundle());
    }
 
    IEnumerator GetAssetBundle() {
        UnityWebRequest www = new UnityWebRequest("http://www.my-server.com");
        DownloadHandlerAssetBundle handler = new DownloadHandlerAssetBundle(www.url, uint.MaxValue);
        www.downloadHandler = handler;
        yield return www.SendWebRequest();
 
        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            // 提取 AssetBundle
            AssetBundle bundle = handler.assetBundle;
        }
    }
}

DownloadHandlerAudioClip 用于下载音频文件。

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

public class AudioDownloader : MonoBehaviour {

    void Start () {
        StartCoroutine(GetAudioClip());
    }

    IEnumerator GetAudioClip() {
        using (var uwr = UnityWebRequestMultimedia.GetAudioClip("http://myserver.com/mysound.ogg", AudioType.OGGVORBIS)) {
            yield return uwr.SendWebRequest();
            if (uwr.isNetworkError || uwr.isHttpError) {
                Debug.LogError(uwr.error);
                yield break;
            }

            AudioClip clip = DownloadHandlerAudioClip.GetContent(uwr);
            // 使用音频剪辑
        }
    }   
}

DownloadHandlerMovieTexture 用于下载视频文件。由于 MovieTexture 已被弃用,因此建议您使用 VideoPlayer 进行视频下载和电影播放。

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

public class MovieDownloader : MonoBehaviour {

    void Start () {
        StartCoroutine(GetAudioClip());
    }

    IEnumerator GetAudioClip() {
        using (var uwr = UnityWebRequestMultimedia.GetMovieTexture("http://myserver.com/mysound.ogg")) {
            yield return uwr.SendWebRequest();
            if (uwr.isNetworkError || uwr.isHttpError) {
                Debug.LogError(uwr.error);
                yield break;
            }

            MovieTexture movie = DownloadHandlerMovieTexture.GetContent(uwr);
            // 使用电影纹理
        }
    }   
}

DownloadHandlerScript 是一个特殊类。就其本身而言,不会执行任何操作。但是,此类可由用户定义的类继承。此类接收来自 UnityWebRequest 系统的回调,然后可以使用这些回调在数据从网络到达时执行完全自定义的数据处理。

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

public class LoggingDownloadHandler : DownloadHandlerScript {

    // 标准脚本化下载处理程序 - 在每个 ReceiveData 回调时分配内存
   
    public LoggingDownloadHandler(): base() {
    }

    // 预先分配的脚本化下载处理程序
    // 重用提供的字节数组来传递数据。
    //消除内存分配。
    
    public LoggingDownloadHandler(byte[] buffer): base(buffer) {
    }

    //对于 DownloadHandler 基类而言是必需的。在处理"bytes"属性时调用。
    
    protected override byte[] GetData() { return null; }

    //从网络收到数据后每帧调用一次。
    
    protected override bool ReceiveData(byte[] data, int dataLength) {
        if(data == null || data.Length < 1) {
            Debug.Log("LoggingDownloadHandler :: ReceiveData - received a null/empty buffer");
            return false;
        }

        Debug.Log(string.Format("LoggingDownloadHandler :: ReceiveData - received {0} bytes", dataLength));
        return true;
    }

    // 从服务器收到所有数据并通过 ReceiveData 传递后调用。
    
    protected override void CompleteContent() {
        Debug.Log("LoggingDownloadHandler :: CompleteContent - DOWNLOAD COMPLETE!");
    }

    // 从服务器收到 Content-Length 标头时调用。
    
    protected override void ReceiveContentLength(int contentLength) {
        Debug.Log(string.Format("LoggingDownloadHandler :: ReceiveContentLength - length {0}", contentLength));
    }
}

End.我用过的操作

使用方法如下:

1.加载图片资源

(API链接)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
 
public class MyBehaviour : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(GetText());
    }
 
    IEnumerator GetText()
    {
        using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture("http://www.my-server.com/myimage.png"))
        {
            yield return uwr.SendWebRequest();
 
            if (uwr.isNetworkError || uwr.isHttpError)
            {
                Debug.Log(uwr.error);
            }
            else
            {
                // Get downloaded asset bundle
                var texture = DownloadHandlerTexture.GetContent(uwr);
            }
        }
    }
}

(实际运用可参考下方链接:https://blog.csdn.net/weixin_45023328/article/details/106192943

2.加载音视频

(API链接)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
 
public class MyBehaviour : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(GetAudioClip());
    }
 
    IEnumerator GetAudioClip()
    {
        using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("http://www.my-server.com/audio.ogg", AudioType.OGGVORBIS))
        {
            yield return www.Send();
 
            if (www.isError)
            {
                Debug.Log(www.error);
            }
            else
            {
                AudioClip myClip = DownloadHandlerAudioClip.GetContent(www);
            }
        }
    }
}

3.加载AssetsBundle包

(API链接)

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
 
public class MyBehaviour : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(GetText());
    }
 
    IEnumerator GetText()
    {
        using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle("http://www.my-server.com/mybundle"))
        {
            yield return uwr.SendWebRequest();
 
            if (uwr.isNetworkError || uwr.isHttpError)
            {
                Debug.Log(uwr.error);
            }
            else
            {
                // Get downloaded asset bundle
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
            }
        }
    }
}

4.Get加载文本

 IEnumerator GetText(string url)
    {
        UnityWebRequest www = UnityWebRequest.Get(url);
        yield return www.SendWebRequest();
        if (www.isNetworkError || www.isHttpError)
        {
            Debug.Log(www.error);
        }
        else
        {
            // Show results as text
            Debug.Log(www.downloadHandler.text);
            // Or retrieve results as binary data
            byte[] results = www.downloadHandler.data;
        }
    }

5.执行Post操作时 ,将json作为参数传递

void Start()
    {
        //使用litJson创建json格式的参数数据
        JsonData data = new JsonData();
        data["与后端协商好的参数名"] = "你要写入的参数";
        byte[] postBytes = System.Text.Encoding.Default.GetBytes(data.ToJson());
 
        //使用原生UnityWebRequest(推荐)
        StartCoroutine(UnityWebRequestPost("你的url", postBytes));
 
        //使用UniRx
        ObservableWWW.Post("你的url", postBytes, new Dictionary<string, string>() { { "Content-Type", "application/json" } })
                     .Subscribe(result => Debug.Log(result));
    }
IEnumerator UnityWebRequestPost(string url, byte[] postBytes)
    {
        UnityWebRequest request = new UnityWebRequest(url, "POST");
 
        request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
        request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        yield return request.SendWebRequest();
        Debug.Log("Status Code: " + request.responseCode);
        if (request.isNetworkError || request.isHttpError)
        {
            Debug.LogError(request.error);
        }
        else
        {
            Debug.Log(request.downloadHandler.text);
        }
    }

6.执行Post操作时 在表单中添加数据

 IEnumerator UnityWebRequestPost(string url)
    {
        int refit_id = HttpRequesterGetQR.Instance.qrjson.data.refit_id;
        print(refit_id);
        WWWForm form = new WWWForm();
        form.AddField("refit_id", refit_id);
        UnityWebRequest request = UnityWebRequest.Post(url, form);
        request.SetRequestHeader("appId", HttpRequesterGetInfo.Instance.client_id);
        request.SetRequestHeader("appSecret", HttpRequesterGetInfo.Instance.appSecretappSecret);
        yield return request.SendWebRequest();
        if (request.isHttpError || request.isNetworkError)
        {
            Debug.LogError("失败:" + request.error);
        }
        else
        {
            string _resuslt = request.downloadHandler.text;
            Debug.Log("成功:" + _resuslt);           
        }

最后关于UnityWebRequest类的介绍可以参考这边文章:https://blog.csdn.net/qwe25878/article/details/85051911

参考文章:https://blog.csdn.net/qq_36848370/article/details/108606003

posted @ 2022-06-22 18:05  哒哒哒~~~  阅读(2339)  评论(0编辑  收藏  举报