こんにちわ。今回は「AWS Mobile SDK for Unity」を使ってサーバーレスなアプリを開発する方法を記載します。

サーバーレスなアプリの魅力

サーバーレスなアプリの魅力はなんと言っても、ミニマムの運用コストがゼロになることです。

これまで弊社が開発したアプリの中に残念ながらサービスが終了してしまったものがいくつかあるのですが、サービス終了の判断になるのが運用コストです。

当然ながら、アプリから得られる収益が運用コストを下回れば赤字になります。 そうなってしまった場合、運営・開発側は力を合わせて試行錯誤しますが、改善の兆しが見られなければどこかのタイミングでサービス終了の判断がなされ、アプリで遊べなくなってしまいます。

数ヶ月費やして開発したアプリがサービス終了してしまうことは、やはり開発側にとっても悲しいですし、 なにより少人数であっても遊んでいただいていたユーザーの方にも申し訳が無いです。

もし、運用コストを減らすことができれば、もしそのアプリで収益を得ることができなかったとしても、サービス終了までの判断をいくらか伸ばす事ができるかもしれません。

つまり、アプリの改善に使う時間がさらに取れるようになります。

サービスが継続したとしても、運用コストは減らすに越した事はありません。

そのため、サーバーレスな環境を構築できれば、非常にメリットが大きいのです。

AWS Mobile SDK for Unityとは

AWSの各種サービスをUnityで開発したアプリから直接利用できるSDKです。2015年5月にAWSからリリースされました。

AWS Mobile SDK for Unity - 公式ドキュメント

現時点(2016/4/14)では、以下のAWSのサービスが対応しています。

  • Amazon Cognito
  • Amazon DynamoDB
  • AWS Identity and Access Management
  • Amazon Kinesis Streams
  • AWS Lambda
  • Amazon Mobile Analytics
  • Amazon Simple Email Service
  • Amazon Simple Notification Service
  • Amazon Simple Queue Service
  • Amazon Simple Storage Service

従来であれば、これらのサービスをアプリから使用するためにはEC2などアプリケーション・サーバーを経由しなければいけなかったのですが、このSDKのおかげでEC2を立ち上げずに各種サービスが利用できます。

今回は簡単な例として、アプリのローカルに保存しているファイルをS3に保存する方法を紹介しようと思います。 (簡単な例のはずが、SDKに同梱されているサンプルが動かず若干ハマりました。。)

導入手順(AWS側)

まずはAWS側で必要な環境の構築を行います。

S3でbucket作成

ファイルを保存しておくためのバケットを作成します。

Cognitoでidentity poolを作成する

Cognitoとは、ユーザー認証やユーザーデータを蓄積しておくことができるサービスです。 「AWS Mobile SDK for Unity」ではcognitoの利用が前提となっているため、cognitoの環境を構築します。

Amazon Cognito

画像赤枠内のボタンを押下して、CognitoでIdentityPoolを作成します。

AWSその1

「Identity pool name」に任意の名前を入力し、「Create Pool」ボタンを押下します。

AWSその2

この画面では何もせず、そのまま「許可」ボタンを押下します。 ちなみに、IdentityPoolに紐づくロールが2つできていますが、上が認証済みユーザーに対するロールで、下が未認証ユーザーに対するロールです。

Cognitoの機能を使ってFacebookやTwitter,また独自の認証システムにより認証を行うことができますが その際に認証済みとそうではないユーザーに対してそれぞれロールを分けることがあるので、このように2つロールができています。

今回は認証の仕組みは使わないため、すべてのユーザーは未認証ユーザー扱いとなります。

AWSその3

IAMでロールポリシー作成

次にIAMの画面に遷移し、先ほど作成したCognito用のロールにS3にファイルを作るためのポリシーを作成します。 画像赤枠内のボタンを押下します。

AWSその4

そのまま「選択」ボタンを押下します。

AWSその5

この画面では選択したロールに付与するアクセス権限の設定を行います。 今回はAWSサービスにはS3を、アクションにはテストなので全てを、ARNには作成したS3のバケットのARNを指定して下さい。 (バケット名がexamplebucketであれば、ARNはarn:aws:s3:::examplebucket/*)

指定が終わったら、「ステートメントを追加」ボタン、「次のステップボタン」を押下します。

AWSその6

「ポリシーの適用」ボタンを押下します。

AWSその7

以上で、AWS側で必要な手順は終了です。

導入手順(Unity側)

AWS Mobile SDK for Unityをダウンロードします

AWS Mobile SDK for Unity

解凍し,S3のunitypackageをUnityプロジェクトにインポートします。

S3Exampleというサンプルのシーンが含まれているので、このシーンを開き S3GameObjectにアタッチS3Exampleコンポーネントに対して CognittoのIdentity PoolIdとRegion、 S3のバケット名とRegionを設定します。

Unityその1

この状態で起動し、「Post Object」ボタンを押下するとサンプルのファイルが作成したバケットに送信・保存される。。。 はずなんですが、バケットの中を見てみると何もファイルがありません。

そして、エラーログも出力されていない。。

試行錯誤を経て、サンプルのPostObjectAsyncでは動作せず、PutObjectAsyncを使えば正常に動作することがわかりました。 PutObjectAsyncを使って書き換えたサンプル実装が以下です。

public void PostObject ()
{
    ResultText.text = "Retrieving the file";

    string fileName = GetFileHelper ();

    var stream = new FileStream (Application.persistentDataPath + Path.DirectorySeparatorChar + fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

    AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;
    ResultText.text += "\nCreating request object";

    var request = new PutObjectRequest();
    request.BucketName = S3BucketName;
    request.Key = fileName;
    request.InputStream = stream;
    request.CannedACL = S3CannedACL.Private;

    Client.PutObjectAsync (request, (responseObj)=>{

        if (responseObj.Exception == null)
        {
            Debug.Log("SUCCESS");
        }
        else
        {
            Debug.LogError("ERROR");
        }
    });
}

ポイントは、

AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;

を呼び出して、HTTPのPutメソッドが動作するように設定しているところです。 (デフォルトのWWWだとPutはサポートされていません)

そんなこんなで無事、Unityから直接、S3にファイルを保存することができるようになりました。

所感

これまでであればEC2を構築し、EC2経由で行わなければならなかったことが直接できるようになったので EC2のパフォーマンスを考慮しなくてもよくなり、「AWS Mobile SDK For Unity」のおかげでよりアプリの開発に専念できるようになりました。

今回はS3にファイルを保存しただけですが、Lamdaを使用すれば サーバー側でロジックを動かすこともでき、さらにサーバーレスでできることの幅が広がります。