GoogleスプレッドシートとのUnity統合





遅かれ早かれ、最も単純なゲームの開発プロセスにおいても、その作成者はデータ管理のタスクに直面します。それはゲーム内アイテム(ユニット、武器、スキル)のパラメーター、ゲームの経済性、ローカリゼーションまたはアプリケーションの動作に必要なデータになります。



スプレッドシートは、この問題を解決するための便利なツールです。 データの視覚表示と視覚化に適しています。 数式の並べ替えと使用は、経済性、ゲームサイクル、レベル管理のレンダリングにおいて数学的な正確さを実現するのに役立ちます。 Googleスプレッドシートの利点は、多数の人がオンラインで同時に作業できることです。これにより、開発速度が大幅に向上し、プログラマ、アーティスト、ゲームデザイナーなどのチームメンバー間で信頼性の高いわかりやすいコミュニケーションが確立されます。



この記事では、スプレッドシートがもたらすメリット、Googleスプレッドシートを操作するためのゲームを準備するときに直面した困難、およびUnityプロジェクトとGoogleスプレッドシートの統合に関する小さなチュートリアルを共有したいと思います。





ゲームのケースを考慮すると、Googleテーブルを使用してデータを保存し、キャラクターの配色を整理し、ゲーム内通貨でその値を計算し、プレーヤーのタスクシステムを構築しました。 アプリケーションのソフトウェア部分の責任者として、テーブルを使用することで、特にグラフィックデータとデザイナーとのコラボレーションに関しては、多くの時間を節約できました。







お気づきかもしれませんが、さまざまな配色により、かなりシンプルなゲームにひねりが加えられ、ユーザーにとっては少し魅力的で興味深いものになりました。 データの体系化がなければ、これは事実上不可能です。







並べ替えの式とテクニックは、ゲーム内のタスク(課題)のすべてのパラメーター(順序、目標、報酬)を計算するのに役立ちました。 経済を構築するための適切なアプローチは、ユーザーをゲーム内に保持するために非常に重要であり、テーブルが提供するデータを変更する際の機動性がこの場合に役立ちます。







次に、GoogleスプレッドシートをUnityと統合する技術的な側面に進みましょう。 Unityゲームエンジンは、Googleスプレッドシートを含むインターネットリソースと対話するための多くの方法を提供します。そのうちの1つは、スタンドアロンアプリケーションに基づく統合です。 ただし、この場合の主な課題は、.NET 2.0エンジンを使用することです。



2015年5月5日に、Googleは従来のOAuth 1.0認証プロトコルのサポートを停止し、新しいOAuth 2.0にアップグレードしなかったアプリケーションはすべて機能しなくなりました。 私が使用した無料のプラグインの開発者であるUnity-GDataUnity-Quicksheetの更新バージョンはこれを処理せず、自分で解決策を見つけるしかありませんでした。



最初は、このトピックに関するドキュメントは網羅的であるため、UnityおよびC#での承認に関する問題は発生しないように思われました。 しかし、それはそれほど単純ではないことが判明しました。



まず、OAuth 2.0リクエストの一部のパラメーター、たとえば「アクセスタイプ」や「トークンタイプ」がGoogleスプレッドシートのドキュメントで指定されていないため、認証プロセス自体に問題がありました。



第二に、モノラル用のGoogle Data API SDKからインポートしたGoogle Data APIの更新された.dllデータライブラリの一部で、Unityでコンパイルエラーが発生しました。Unity-GDataプラグインの古い.dllでも同様です。 私は結合しなければなりませんでした。



第三に、JSONリクエストを処理するために適切なNewtonsoftライブラリを追加する必要がありました。



ビジネスに取り掛かろう 。 GoogleスプレッドシートをUnityと統合するプロセスは、いくつかの段階に分けることができます。



最初に、必要なすべてのライブラリとスクリプトがすでに含まれているunitypackageをダウンロードする必要があります。



プリセットGoogleアカウント









Google Drive APIへのアクセスを設定する





スクリプト例を示します。

ここにスクリプトがあります
using UnityEngine; using UnityEditor; using System.Collections; using System.Collections.Generic; using Google.GData.Client; using Google.GData.Spreadsheets; [InitializeOnLoad] public class SpreadsheetEntity : MonoBehaviour { // enter Client ID and Client Secret values const string _ClientId = ""; const string _ClientSecret = ""; // enter Access Code after getting it from auth url const string _AccessCode = ""; // enter Auth 2.0 Refresh Token and AccessToken after succesfully authorizing with Access Code const string _RefreshToken = ""; const string _AccessToken = ""; const string _SpreadsheetName = ""; static SpreadsheetsService service; public static GOAuth2RequestFactory RefreshAuthenticate() { OAuth2Parameters parameters = new OAuth2Parameters() { RefreshToken = _RefreshToken, AccessToken = _AccessToken, ClientId = _ClientId, ClientSecret = _ClientSecret, Scope = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds", AccessType = "offline", TokenType = "refresh" }; string authUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters); return new GOAuth2RequestFactory("spreadsheet", "MySpreadsheetIntegration-v1", parameters); } static void Auth() { GOAuth2RequestFactory requestFactory = RefreshAuthenticate(); service = new SpreadsheetsService("MySpreadsheetIntegration-v1"); service.RequestFactory = requestFactory; } // Use this for initialization static SpreadsheetEntity(){ if (_RefreshToken == "" && _AccessToken == "") { Init(); return; } Auth(); Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery(); // Make a request to the API and get all spreadsheets. SpreadsheetFeed feed = service.Query(query); if (feed.Entries.Count == 0) { Debug.Log("There are no spreadsheets in your docs."); return; } AccessSpreadsheet(feed); } // access spreadsheet data static void AccessSpreadsheet(SpreadsheetFeed feed) { string name = _SpreadsheetName; SpreadsheetEntry spreadsheet = null; foreach (AtomEntry sf in feed.Entries) { if (sf.Title.Text == name) { spreadsheet = (SpreadsheetEntry)sf; } } if (spreadsheet == null) { Debug.Log("There is no such spreadsheet with such title in your docs."); return; } // Get the first worksheet of the first spreadsheet. WorksheetFeed wsFeed = spreadsheet.Worksheets; WorksheetEntry worksheet = (WorksheetEntry)wsFeed.Entries[0]; // Define the URL to request the list feed of the worksheet. AtomLink listFeedLink = worksheet.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null); // Fetch the list feed of the worksheet. ListQuery listQuery = new ListQuery(listFeedLink.HRef.ToString()); ListFeed listFeed = service.Query(listQuery); foreach (ListEntry row in listFeed.Entries) { //access spreadsheet data here } } static void Init() { //////////////////////////////////////////////////////////////////////////// // STEP 1: Configure how to perform OAuth 2.0 //////////////////////////////////////////////////////////////////////////// if (_ClientId == "" && _ClientSecret == "") { Debug.Log("Please paste Client ID and Client Secret"); return; } string CLIENT_ID = _ClientId; string CLIENT_SECRET = _ClientSecret; string SCOPE = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds https://docs.google.com/feeds"; string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"; string TOKEN_TYPE = "refresh"; //////////////////////////////////////////////////////////////////////////// // STEP 2: Set up the OAuth 2.0 object //////////////////////////////////////////////////////////////////////////// // OAuth2Parameters holds all the parameters related to OAuth 2.0. OAuth2Parameters parameters = new OAuth2Parameters(); parameters.ClientId = CLIENT_ID; parameters.ClientSecret = CLIENT_SECRET; parameters.RedirectUri = REDIRECT_URI; //////////////////////////////////////////////////////////////////////////// // STEP 3: Get the Authorization URL //////////////////////////////////////////////////////////////////////////// parameters.Scope = SCOPE; parameters.AccessType = "offline"; // IMPORTANT and was missing in the original parameters.TokenType = TOKEN_TYPE; // IMPORTANT and was missing in the original // Authorization url. string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters); Debug.Log(authorizationUrl); Debug.Log("Please visit the URL above to authorize your OAuth " + "request token. Once that is complete, type in your access code to " + "continue..."); parameters.AccessCode = _AccessCode; if (parameters.AccessCode == "") { Application.OpenURL(authorizationUrl); return; } //////////////////////////////////////////////////////////////////////////// // STEP 4: Get the Access Token //////////////////////////////////////////////////////////////////////////// OAuthUtil.GetAccessToken(parameters); string accessToken = parameters.AccessToken; string refreshToken = parameters.RefreshToken; Debug.Log("OAuth Access Token: " + accessToken + "\n"); Debug.Log("OAuth Refresh Token: " + refreshToken + "\n"); } }
      
      







特定の機能に注意してください。このスクリプトは、Unityエディターの起動時に実行されます 。メインアプリケーションコードが実行される前にすべてのデータがすでに配置されているため、非常に便利です 。詳細はこちら



必要なすべての手順を完了すると、プロジェクトはGoogleスプレッドシートで作業できるようになります。



Googleスプレッドシートからデータを取得して保存する



Googleでは、テーブルを操作するプロセスについては、上記の開発者向けドキュメントで詳しく説明されています。 しかし、明確にするために、小さな例を示します。 データには、リストベースのフィードを使用し、ストレージにはXMLファイルを使用します。 UnityでXMLを操作する方法の詳細については、 こちらをご覧ください



コード例
 // modified AccessSpreadsheet Method void AccessSpreadsheet(SpreadsheetFeed feed) { string name = _SpreadsheetName; SpreadsheetEntry spreadsheet = null; foreach (AtomEntry sf in feed.Entries) { if (sf.Title.Text == name) { spreadsheet = (SpreadsheetEntry)sf; } } if (spreadsheet == null) { Debug.Log("There is no such spreadsheet with such title in your docs."); return; } // Get the first worksheet of the first spreadsheet. WorksheetFeed wsFeed = spreadsheet.Worksheets; WorksheetEntry worksheet = (WorksheetEntry)wsFeed.Entries[0]; // Define the URL to request the list feed of the worksheet. AtomLink listFeedLink = worksheet.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null); // Fetch the list feed of the worksheet. ListQuery listQuery = new ListQuery(listFeedLink.HRef.ToString()); ListFeed listFeed = service.Query(listQuery); //create list to add dynamic data List<TestEntity> testEntities = new List<TestEntity>(); foreach (ListEntry row in listFeed.Entries) { TestEntity entity = new TestEntity(); entity.name = row.Elements[0].Value; entity.number = int.Parse(row.Elements[1].Value); //use Parse method to get int value Debug.Log("Element: " + entity.name + ", " + entity.number.ToString()); testEntities.Add(entity); } TestContainer container = new TestContainer(testEntities.ToArray()); container.Save("test.xml"); } // classes for xml serialization public class TestEntity { public string name; public int number; public TestEntity(){ name = "default"; number = 0; } } [XmlRoot("TestCollection")] public class TestContainer { [XmlArray("TestEntities")] [XmlArrayItem("testEntity")] public TestEntity[] testEntities;// = new skinEntity[]; public TestContainer(){ } public TestContainer(TestEntity[] arch){ testEntities = arch; } public void Save(string path) { var serializer = new XmlSerializer(typeof(TestContainer)); using(var stream = new FileStream(path, FileMode.Create)) { serializer.Serialize(stream, this); } } public static TestContainer Load(string path) { var serializer = new XmlSerializer(typeof(TestContainer)); using(var stream = new FileStream(path, FileMode.Open)) { return serializer.Deserialize(stream) as TestContainer; } } }
      
      







スクリプトはエディターでのみ動作することを追加する価値があります。少なくとも私が見つけたプラグインのバージョンでは、デバイス上のGoogleテーブルの機能を使用できません。これは、一部のライブラリと一部のプラットフォームの互換性の問題によるものです unitypackageで提案したライブラリは、エディター以外のプラットフォームではコンパイルできません。 それでもデバイスでテーブルを使用する必要がある場合、Unityバージョン5では、プラグインインスペクターを使用してプラグインがサポートするプラットフォームを選択できます。以前のバージョンでは、プラグインを目的のフォルダーに配置します 。詳細はこちら



そのため、スプレッドシートはゲーム開発プロセスに不可欠なツールです。 ルーチン作業を最適化し、チーム全体の相互作用を確立し、膨大なデータ配列を視覚化し、数学を使用して計算します。 Google SpreadsheetsとUnityの統合は簡単なプロセスですが、少し知識と努力が必要です。



ここにgithubプロジェクトへのリンクがあります。



ご清聴ありがとうございました。この記事がお役に立てば幸いです。



All Articles