关于c#:在仍然下载的同时从UnityWebRequest获取数据?

Obtain data from UnityWebRequest while still downloading?

我有这段代码可以进行REST调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
public IEnumerator GetCooroutine(string route)
{
    string finalURL = URL + route;
    UnityWebRequest www = UnityWebRequest.Get(finalURL);
    yield return www.SendWebRequest();

    if (www.isNetworkError || www.isHttpError) {
        Debug.Log(www.error);
    }
    else {
        Debug.Log("GET succesfull. Response:" + www.downloadHandler.text);
    }
}

我需要在请求接收时访问数据或请求主体,并将其用于其他用途。 我不想等到完成接收它们之后再访问它们。

如果使用yield,则代码将等到send完成执行,而我不希望这样做。


可以使用UnityWebRequest进行此操作,但是您必须执行额外的工作。秘诀是将DownloadHandlerScriptUnityWebRequest一起使用。

创建一个单独的类,并使其从DownloadHandlerScript而不是MonoBehaviour派生。在下面的示例中,我将其称为CustomWebRequest。覆盖其中的bool ReceiveData(byte[] data, int dataLength)void CompleteContent()void ReceiveContentLength(int contentLength)函数。

这是CustomWebRequest类的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class CustomWebRequest : DownloadHandlerScript
{
    // Standard scripted download handler - will allocate memory on each ReceiveData callback
    public CustomWebRequest()
        : base()
    {
    }

    // Pre-allocated scripted download handler
    // Will reuse the supplied byte array to deliver data.
    // Eliminates memory allocation.
    public CustomWebRequest(byte[] buffer)
        : base(buffer)
    {
    }

    // Required by DownloadHandler base class. Called when you address the 'bytes' property.
    protected override byte[] GetData() { return null; }

    // Called once per frame when data has been received from the network.
    protected override bool ReceiveData(byte[] byteFromServer, int dataLength)
    {
        if (byteFromServer == null || byteFromServer.Length < 1)
        {
            Debug.Log("CustomWebRequest :: ReceiveData - received a null/empty buffer");
            return false;
        }

        //Do something with or Process byteFromServer here


        return true;
    }

    // Called when all data has been received from the server and delivered via ReceiveData
    protected override void CompleteContent()
    {
        Debug.Log("CustomWebRequest :: CompleteContent - DOWNLOAD COMPLETE!");
    }

    // Called when a Content-Length header is received from the server.
    protected override void ReceiveContentLength(int contentLength)
    {
        Debug.Log(string.Format("CustomWebRequest :: ReceiveContentLength - length {0}", contentLength));
    }
}

要使用它开始下载,只需创建UnityWebRequest的新实例,并在调用SendWebRequest函数之前将CustomWebRequest用作downloadHandler。不需要协程,您甚至不需要产生任何东西。这是怎么做的:

1
2
3
4
5
6
7
8
9
10
11
UnityWebRequest webRequest;
//Pre-allocate memory so that this is not done each time data is received
byte[] bytes = new byte[2000];

void Start()
{
    string url ="http://yourUrl/mjpg/video.mjpg";
    webRequest = new UnityWebRequest(url);
    webRequest.downloadHandler = new CustomWebRequest(bytes);
    webRequest.SendWebRequest();
}

而已。

  • Unity首次发出请求时,将调用ReceiveContentLength(int
    contentLength)
    。您可以使用contentLength参数来确定将从该请求接收的字节总数。

  • 每次接收到新数据时都会调用ReceiveData函数
    并从该功能中,您可以从
    byteFromServer参数及其从dataLength开始的长度
    参数。

  • Unity接收完数据后,CompleteContent函数为
    叫。