2018年5月11日 星期五

Unity內將檔案上傳到FTP

在做專案時有時會需要將檔案上傳到FTP去,像是照片或影片等,所以這邊便記錄一下做法。

我分別遇過需上傳到一般FTP、SFTP和使用主動模式FTP的情況,因此實做過三種方式:FTP的兩種,SFTP和使用主動模式FTP的一種。

這邊只記錄FTP的兩種,第三種有點麻煩,之後有空整理再另外放上來。

使用WebClient的第一種:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Net;
  4. using System.Threading;
  5. using UnityEngine;
  6.  
  7. public class XXX : MonoBehaviour
  8. {
  9. void Start()
  10. {
  11. StartCoroutine(FTPUpload1());
  12. }
  13. void Update()
  14. {
  15.  
  16. }
  17. IEnumerator FTPUpload1()
  18. {
  19. var filename = "D:/XXX.png";
  20. bool isUploading = false;
  21.  
  22. UnityEngine.Debug.Log("開始!!");
  23.  
  24. ThreadPool.QueueUserWorkItem((o) =>
  25. {
  26. using (WebClient client = new WebClient())
  27. {
  28. client.Credentials = new NetworkCredential("kim", "123");
  29. client.UploadFile("ftp://127.0.0.1/XXX.png", "STOR", filename);
  30. }
  31. isUploading = true;
  32. });
  33.  
  34. while (!isUploading)
  35. {
  36. UnityEngine.Debug.Log("上傳中!!");
  37. yield return new WaitForSeconds(0.1f);
  38. }
  39.  
  40. UnityEngine.Debug.Log("結束!!");
  41. }
  42. }

使用ftpWebRequest的第二種:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using System.Threading;
  6. using UnityEngine;
  7.  
  8. public class XXX : MonoBehaviour
  9. {
  10. void Start()
  11. {
  12. StartCoroutine(FTPUpload2());
  13. }
  14. void Update()
  15. {
  16.  
  17. }
  18. IEnumerator FTPUpload2()
  19. {
  20. var filename = "D:/XXX.png";
  21. bool isUploading = false;
  22.  
  23. UnityEngine.Debug.Log("開始!!");
  24.  
  25. ThreadPool.QueueUserWorkItem((o) =>
  26. {
  27. FtpWebRequest ftpWebRequest = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/XXX.png");
  28.  
  29. ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;
  30. ftpWebRequest.Credentials = new NetworkCredential("kim", "123");
  31. ftpWebRequest.UsePassive = true;
  32. ftpWebRequest.UseBinary = true;
  33. ftpWebRequest.KeepAlive = true;
  34.  
  35. StreamReader sourceStream = new StreamReader(filename);
  36. byte[] fileBytes = File.ReadAllBytes(filename);
  37. sourceStream.Close();
  38. ftpWebRequest.ContentLength = fileBytes.Length;
  39.  
  40. Stream requestStream = ftpWebRequest.GetRequestStream();
  41. requestStream.Write(fileBytes, 0, fileBytes.Length);
  42. requestStream.Close();
  43.  
  44. FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse();
  45. ftpWebResponse.Close();
  46.  
  47. isUploading = true;
  48. });
  49.  
  50. while (!isUploading)
  51. {
  52. UnityEngine.Debug.Log("上傳中!!");
  53. yield return new WaitForSeconds(0.1f);
  54. }
  55.  
  56. UnityEngine.Debug.Log("結束!!");
  57. }
  58. }

2018年2月22日 星期四

Unity內使用Tab切換輸入框的方式

話說我之前有個案子要求可以使用Tab來切換到其他輸入框,如果是Windows程式或是網頁,根本不用為此花功夫;但是Unity就沒這種天經地義的功能了,只好來動手寫一個試看看。

先確立觀念是當按下Tab時,便讓Unity去Focus到某一個介面上,如果先前已點在某一個介面上,便要像是順理成章般地到下一個介面去。

因此做了個簡單的介面:

然後在程式一開始時便Focus在帳號輸入框上,接著按Tab便可在兩個輸入框內不斷切換:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5.  
  6. public class XXX : MonoBehaviour {
  7.  
  8.     private GameObject account;
  9.     private GameObject password;
  10.  
  11.     void Start ()
  12.     {
  13.         account = GameObject.Find("Account");
  14.         password = GameObject.Find("Password");
  15.  
  16.         EventSystem.current.SetSelectedGameObject(account);
  17.     }
  18.  
  19.     void Update ()
  20.     {
  21.         if (Input.GetKeyDown(KeyCode.Tab))
  22.         {
  23.             if (EventSystem.current.currentSelectedGameObject == account)
  24.             {
  25.                 EventSystem.current.SetSelectedGameObject(password);
  26.             }
  27.             else if (EventSystem.current.currentSelectedGameObject == password)
  28.             {
  29.                 EventSystem.current.SetSelectedGameObject(account);
  30.             }
  31.         }
  32.     }
  33. }
  34.  

所以其實很單純,使用兩個API來取得當前Focus的GUI、和設定想Focus的GUI就好了。

EventSystem.current.currentSelectedGameObject可取得當前Focus的GUI。
EventSystem.current.SetSelectedGameObject()可設定想Focus的GUI。

用這方式可以再配合一個List來做出在複雜輸入介面上輕鬆切換的效果,我想可能有更好的觀念和寫法吧,但我自己是喜歡這個很直觀又方便修改的架構。