2016年9月10日 星期六

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

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

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

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

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

WebClient:
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Net;
  4.  
  5. public class WebClientController : MonoBehaviour {
  6.  
  7.     void Start ()
  8.     {
  9.         WebClient webClient = new WebClient();
  10.  
  11.         try
  12.         {
  13.             webClient.DownloadFile( "http://localhost:8080/xxx.assetbundle", "D:/xxx.assetbundle" );
  14.         }
  15.         catch( Exception ex )
  16.         {
  17.             Debug.Log( ex );
  18.         }
  19.     }
  20. }
雖然我想一併使用下載過程的檢視,但是這部分的效果就是出不來,只好先記錄程式碼,日後有空再來試。
  1. webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler( WebClient_DownloadProgressChanged );
  2. webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler( WebClient_DownloadDataCompleted );
  3.  
  4. void WebClient_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e )
  5. {
  6.     Debug.Log( "下載" + e.ProgressPercentage + "%" );
  7. }
  8.  
  9. void WebClient_DownloadDataCompleted (object sender, DownloadDataCompletedEventArgs e)
  10. {
  11.     Debug.Log( "下載完成" );
  12. }
--------------------------------------------------------------------------------------------------------

Stream:
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Net;
  4.  
  5. public class WebClientController : MonoBehaviour {
  6.  
  7.     HttpWebRequest httpWebRequest;
  8.     HttpWebResponse httpResponse;
  9.     System.IO.Stream dataStream;
  10.     byte[] buffer = new byte[8192];
  11.     int size = 0;
  12.     float downloadMemory = 0;
  13.     bool completeCheck = false;
  14.  
  15.     void Start ()
  16.     {
  17.         try
  18.         {
  19.             httpWebRequest = (HttpWebRequest)WebRequest.Create( "http://localhost:8080/xxx.assetbundle" );
  20.             httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
  21.             dataStream = httpResponse.GetResponseStream();
  22.             fileStream = new FileStream( "D:/xxx.assetbundle", FileMode.Create, FileAccess.Write );
  23.  
  24.             downloadMemory = 0;
  25.         }
  26.         catch( Exception e )
  27.         {
  28.             Debug.Log( e );
  29.         }
  30.     }
  31.  
  32.     void Update ()
  33.     {
  34.         if( completeCheck == false )
  35.         {
  36.             try
  37.             {
  38.                 size = dataStream.Read( buffer, 0, buffer.Length );
  39.  
  40.                 if( size > 0 )
  41.                 {
  42.                     fileStream.Write( buffer, 0, size );
  43.                     downloadMemory += size;
  44.                     Debug.Log( "正下載 " + ( downloadMemory / 1048576 ).ToString( "f1" ) + "MB / " +
  45.                                 ((float)httpResponse.ContentLength / 1048576 ).ToString( "f1" ) + "MB == " +
  46.                                 (( downloadMemory / (float)httpResponse.ContentLength ) * 100 ).ToString( "f1" ) + "%" );
  47.                 }
  48.                 else
  49.                 {
  50.                     fileStream.Close();
  51.                     httpResponse.Close();
  52.                     buffer = new byte[8192];
  53.  
  54.                     Debug.Log( "下載完成!" );
  55.  
  56.                     completeCheck = true;
  57.                 }
  58.             }
  59.             catch( Exception ex )
  60.             {
  61.                 Debug.Log( ex );
  62.             }
  63.         }
  64.     }
  65. }
--------------------------------------------------------------------------------------------------------

Unity內用WWW載入AssetBundle

大家都知道,AssetBundle是Unity用來打包資源的方式。
大家也知道,AssetBundle對於Script的不方便,一定要在Project內事先放入相同的Script,才能讓AssetBundle上的Script相對應到。

但這都不是重點,本篇的重點是將AssetBundle匯入到Unity程式內使用。
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class AssetBundleLoadController : MonoBehaviour {
  5.  
  6.     void Start ()
  7.     {
  8.         StartCoroutine( LoadAssetBundle() );
  9.     }
  10.  
  11.     private IEnumerator LocalLoad()
  12.     {
  13.         WWW fileBundle = new WWW( "file://D:/xxx.assetbundle" );
  14.         yield return fileBundle;
  15.  
  16.         GameObject tempObject = null;
  17.         yield return tempObject = Instantiate( fileBundle.assetBundle.mainAsset ) as GameObject;
  18.         tempObject.name = tempObject.name.Replace( "(Clone)", string.Empty );
  19.  
  20.         fileBundle.assetBundle.Unload( false );
  21.         Resources.UnloadUnusedAssets();
  22.     }
  23. }
這樣就能使用AssetBundle的內容物了。

2016年9月2日 星期五

開發時,Java的版本設定......

在使用Eclipse、Tomcat等時,很怕Java的JDK、JRE等版本不相對,或是出現"Unsupported major.minor version 52.0"之類的訊息,這時就得去挖所有相關的環境設定,我也被這情況弄過幾次,所以在此記錄一下。

確認執行Tomcat的電腦使用的Java版本,通常可以從控制台的解除安裝程式來看,但是也許你會安裝好幾個版本的Java版本在裡面,所以用CMD來看比較妥當,這樣才能確認電腦到底是使用哪個版本的Java,分別輸入"java -version"和"javac -version",就可以看到結果:


再來是Eclipse內,一般大家都知道的是Project內的Library引用設定,在Project上用滑鼠右鍵開起選單,選擇"Properties":


然後在左邊選擇"Java Build Path",來觀看Libraries內的JRE版本:


但其實還有其它地方也和Java版本有關係,一個是"Java Complier"的"Compiler compliance level":


另一個是"Project Facets"的設定,這些都和Java版本有關:


以後應該不會再被Java版本這種設定給弄到了。