Obtain data from UnityWebRequest while still downloading?

后端 未结 1 1939
离开以前
离开以前 2021-01-29 09:12

I have this code that makes a REST call:

public IEnumerator GetCooroutine(string route)
{
    string finalURL = URL + route;
    UnityWebRequest www = UnityWebRe         


        
1条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-29 09:29

    It is possible to do it with UnityWebRequest but you have to perform extra work. The secret is to use DownloadHandlerScript with UnityWebRequest.

    Create a separate class and make it derive from DownloadHandlerScript instead of MonoBehaviour. In the example below, I will call it CustomWebRequest. Override the bool ReceiveData(byte[] data, int dataLength), void CompleteContent() and the void ReceiveContentLength(int contentLength) functions inside it.

    Here is an example of the CustomWebRequest class:

    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));
        }
    }
    

    And to use it to start the download, just create new instance of UnityWebRequest and use CustomWebRequest as the downloadHandler before calling the SendWebRequest function. No coroutine required for this and you don't even have to yield anything. This is how to do it:

    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();
    }
    

    That's it.

    • When Unity first makes the request, ReceiveContentLength(int contentLength) is called. You can use the contentLength parameter to determine the total number of bytes you will receive from that request.

    • The ReceiveData function is called each time new data is received and from that function, you can access that current data from the byteFromServer parameter and the length of it from the dataLength parameter.

    • When Unity is done receiving data, the CompleteContent function is called.

    0 讨论(0)
提交回复
热议问题