2016年9月10日 星期六

Unity內使用WebClient和Stream方式來下載遠端檔案

一般Unity下載遠端檔案,大家都是用WWW的方式來做;但是WWW的結果是將下載的檔案直接匯入到Unity內,沒有辦法放在外面,要放在外面還得自己事後存出去,像是文檔或圖片等,那如果下載的是AssetBundle怎麼辦?光想就覺得很麻煩......

當然Unity有WWW.LoadFromCacheOrDownload這樣的方式,但我想要的是更直接地把下載檔案放在外部,之後自己比對是否需要再次下載覆蓋或可直接本地端匯入,因此就來尋找了一般的下載方式。

找到的有WebClient和Stream兩種方式。WebClient很簡單,可說是一口氣就能搞定的輕鬆方式,但是如果是在Unity內用的話,當下載檔案的量大時,程式就會卡在那沒法做其它事了,所以我個人會比較傾向使用Stream的方式,只是程式碼就沒那麼簡便了。

--------------------------------------------------------------------------------------------------------

WebClient:
using UnityEngine;
using System.Collections;
using System.Net;

public class WebClientController : MonoBehaviour {

    void Start ()
    {
        WebClient webClient = new WebClient();

        try
        {
            webClient.DownloadFile( "http://localhost:8080/xxx.assetbundle", "D:/xxx.assetbundle" );
        }
        catch( Exception ex )
        {
            Debug.Log( ex );
        }
    }
}
雖然我想一併使用下載過程的檢視,但是這部分的效果就是出不來,只好先記錄程式碼,日後有空再來試。
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler( WebClient_DownloadProgressChanged );
webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler( WebClient_DownloadDataCompleted );

void WebClient_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e )
{
    Debug.Log( "下載" + e.ProgressPercentage + "%" );
}

void WebClient_DownloadDataCompleted (object sender, DownloadDataCompletedEventArgs e)
{
    Debug.Log( "下載完成" );
}
--------------------------------------------------------------------------------------------------------

Stream:
using UnityEngine;
using System.Collections;
using System.Net;

public class WebClientController : MonoBehaviour {

    HttpWebRequest httpWebRequest;
    HttpWebResponse httpResponse;
    System.IO.Stream dataStream;
    byte[] buffer = new byte[8192];
    int size = 0;
    float downloadMemory = 0;
    bool completeCheck = false;

    void Start ()
    {
        try
        {
            httpWebRequest = (HttpWebRequest)WebRequest.Create( "http://localhost:8080/xxx.assetbundle" );
            httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            dataStream = httpResponse.GetResponseStream();
            fileStream = new FileStream( "D:/xxx.assetbundle", FileMode.Create, FileAccess.Write );

            downloadMemory = 0;
        }
        catch( Exception e )
        {
            Debug.Log( e );
        }
    }

    void Update ()
    {
        if( completeCheck == false )
        {
            try
            {
                size = dataStream.Read( buffer, 0, buffer.Length );

                if( size > 0 )
                {
                    fileStream.Write( buffer, 0, size );
                    downloadMemory += size;
                    Debug.Log( "正下載 " + ( downloadMemory / 1048576 ).ToString( "f1" ) + "MB / " +
                                ((float)httpResponse.ContentLength / 1048576 ).ToString( "f1" ) + "MB == " +
                                (( downloadMemory / (float)httpResponse.ContentLength ) * 100 ).ToString( "f1" ) + "%" );
                }
                else
                {
                    fileStream.Close();
                    httpResponse.Close();
                    buffer = new byte[8192];

                    Debug.Log( "下載完成!" );

                    completeCheck = true;
                }
            }
            catch( Exception ex )
            {
                Debug.Log( ex );
            }
        }
    }
}
--------------------------------------------------------------------------------------------------------

1 則留言: