Unityでビルド後に自動でRomをアップロードする拡張
Unityで作ったAndroid用のRomを他の人にテストプレイしてもらうときに、FTPツールを使っていちいちアップロードしていたのだけど、それがいちいちめんどくさかった。そこで自動で行うようにしてみました。
c#でFTPを利用するのは以下を参考にしました。
Simple C# FTP Class - CodeProject
(元記事のupload関数は一部間違っている部分があるので修正が必要です。)
後はUnityのEditor拡張とかの仕方を調べて作ってみました。
下に載せたソース2つをEditorフォルダに入れて、PreferenceでURL(例:ftp://wkpn@wkpn.sakura.ne.jp/www/Output/)とユーザー名とパスワードを設定すると、Androidロムが出来上がった時に指定されたURLにUploadします。
using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; public class RomUploader { private const string cKeyIsFtpUpload = "KeyFtpUpload"; static bool IsFtpUpload { get { string value = EditorUserSettings.GetConfigValue (cKeyIsFtpUpload); return!string.IsNullOrEmpty (value) && value.Equals ("True"); } set { EditorUserSettings.SetConfigValue (cKeyIsFtpUpload, value.ToString ()); } } private const string cKeyFTPURL = "KeyFTPURL"; static string FTPURL { get { return EditorUserSettings.GetConfigValue (cKeyFTPURL); } set { EditorUserSettings.SetConfigValue(cKeyFTPURL, value); } } private const string cKeyFTPUserName = "KeyFTPUserName"; static string UserName { get { return EditorUserSettings.GetConfigValue (cKeyFTPUserName); } set { EditorUserSettings.SetConfigValue(cKeyFTPUserName, value); } } private const string cKeyFTPPassword = "KeyFTPPassword"; static string FTPPass { get { return EditorUserSettings.GetConfigValue (cKeyFTPPassword); } set { EditorUserSettings.SetConfigValue(cKeyFTPPassword, value); } } [PreferenceItem("Rom Upload")] static void OnGUI() { IsFtpUpload = EditorGUILayout.BeginToggleGroup("Android Rom FTP Upload", IsFtpUpload); FTPURL = EditorGUILayout.TextField("FTP URL", FTPURL); UserName = EditorGUILayout.TextField("User Name", UserName); FTPPass = EditorGUILayout.PasswordField("Password", FTPPass); EditorGUILayout.EndToggleGroup(); } [PostProcessBuildAttribute(1)] static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) { Debug.Log( pathToBuiltProject ); if( IsFtpUpload ) { #if UNITY_ANDROID FTPUploader ftp = new FTPUploader(FTPURL, UserName, FTPPass); string filename = System.IO.Path.GetFileName( pathToBuiltProject ); ftp.Upload(filename, pathToBuiltProject); ftp = null;// Release Resources #endif } } }
using UnityEngine; using System; using System.IO; using System.Net; class FTPUploader { private string host = null; private string user = null; private string pass = null; private FtpWebRequest ftpRequest = null; private Stream ftpStream = null; private const int bufferSize = 2048; public FTPUploader(string hostIP, string userName, string password) { host = hostIP; user = userName; pass = password; } public void Upload(string remote_file, string local_file) { try { /* Create an FTP Request */ ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + remote_file); /* Log in to the FTP Server with the User Name and Password Provided */ ftpRequest.Credentials = new NetworkCredential(user, pass); /* When in doubt, use these options */ ftpRequest.UseBinary = true; ftpRequest.UsePassive = true; ftpRequest.KeepAlive = true; /* Specify the Type of FTP Request */ ftpRequest.Method = WebRequestMethods.Ftp.UploadFile; /* Establish Return Communication with the FTP Server */ ftpStream = ftpRequest.GetRequestStream(); /* Open a File Stream to Read the File for Upload */ FileStream localFileStream = new FileStream(local_file, FileMode.Open); /* Buffer for the Downloaded Data */ byte[] byteBuffer = new byte[bufferSize]; int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize); /* Upload the File by Sending the Buffered Data Until the Transfer is Complete */ try { while (bytesSent != 0) { ftpStream.Write(byteBuffer, 0, bytesSent); bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize); } } catch (Exception ex) { Debug.Log(ex.ToString()); } /* Resource Cleanup */ localFileStream.Close(); ftpStream.Close(); ftpRequest = null; } catch (Exception ex) { Debug.Log(ex.ToString()); } return; } }
今回学んだことリスト
- EditorUserSettingsでプロジェクト固有のデータを保存できる
- PostProcessBuildAttribute属性をstatic関数に付与すると、その関数はビルド後に処理が走る
- PostProcessBuildAttributeの引数は実行順
- PreferenceItem属性を付与することで、Preferenceに設定を追加できる
- EditorGUILayout.〜でGUIを作れる
- EditorGUILayout.BeginToggleGroupとEditorGUILayout.EndToggleGroup()で囲むことで、その間に記載したGUIをチェックボックスでOn/Offできる。