AWS SDKをUnity(2018.1以降)で使う

[AWS & Game Advent Calendar 2020](https://qiita.com/advent-calendar/2020/aws-game)の7日目の記事です。

# はじめに

この記事では、Unity(**2018.1以降**)でAWS SDKを利用する方法について、実際にやってみたことを紹介したいと思います。

そもそもUnityからAWSサービスを利用する方法としては大きく2つあります。
1つは自前のAPIサーバをバックエンドとして構築して、AWSサービスはAPIサーバから利用し、UnityからはAPIサーバが提供するAPIを叩くという方法です。Unity側からAWSサービスを直接触ることはない構成となり、AWSSDKは不要です。
もう1つはUnityのスクリプトからAWSSDKを利用して直接AWSサービスのAPIを叩く方法です。バックエンドを持たずにスタンドアロンで動くゲームにおいてS3へのファイルアップロードをゲームから直接行ったり、クライアント側で[Amazon Cognito](https://aws.amazon.com/jp/cognito/)による認証や[Amazon Pinpoint](https://aws.amazon.com/jp/pinpoint/)によるユーザアクティビティ解析などを利用したい場合などが当てはまります。

“Unity AWS SDK” などとweb検索すると、[Mobile SDK for Unity](https://docs.aws.amazon.com/ja_jp/mobile/sdkforunity/developerguide/what-is-unity-plugin.html)に関するものが多く出てきます。しかし[Mobile SDK for Unityのリポジトリ](https://github.com/aws/aws-sdk-unity-net)には以下の記述があります。

> （一部抜粋）
> If you are using Unity 2018.1 or later, please use the AWS SDK for .NET .NET Standard 2.0 binaries.
...
This is the archive for legacy Unity support.

意訳：Mobile SDK for Unityはアーカイブだから、Unity 2018.1以降では**AWSSDK .NET Standard 2.0を使ってね**

実際、AWS公式ブログ「[AWS SDK for .NET v3.5 Now Generally Available](https://aws.amazon.com/jp/blogs/developer/aws-sdk-for-net-v3-5-now-generally-available/)」にて、AWS SDK for .NET v3.5のGAと各プラットフォームサポート状況が説明されています。Unityに関しては、これまで13サービスしか利用できなかったところが、他SDKで提供されているのと同様ほぼ全てのサービスが利用できるようになったとあります。

今回は[AWS SDK for .NET](https://github.com/aws/aws-sdk-net)の.NET Standard 2.0をUnityで使って、ごく簡単な例としてS3バケットを作成する処理をしてみたいと思います。

## 本記事における環境

* Windows10 Version 1909
* Unity Version 2019.4.15f1
* AWSSDK .NET Standard 2.0 Version 3.5.62.0

# (2021/3/16 update) AWSSDK for .Net version 3.5.109 以降から、依存関係のあるDLLファイルも同梱されるようになりました

[こちらの公式ドキュメント](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/unity-special.html)より引用：

> You need to include the following DLLs in your Unity project alongside the DLLs for AWSSDK.Core and the other AWS services you're using. Starting with version 3.5.109 of the AWS SDK for .NET, the .NET Standard ZIP file contains these additional DLLs.
> - Microsoft.Bcl.AsyncInterfaces.dll
> - System.Runtime.CompilerServices.Unsafe.dll
> - System.Threading.Tasks.Extensions.dll

AWSSDK for .Net version 3.5.109 以降から、依存関係のあるDLLファイルも同梱されるようになりました、とのことで、後続の手順にて解説しているような依存関係のあるDLLを自分でダウンロードしてくる必要がなくなりました。
AWSSDK.Core.dllと同時に上記3つのDLLもUnityへインポートしてあげることでセットアップできるようになります。


# 手順

導入にあたってのおおまかな注意点はブログ「[Referencing the AWS SDK for .NET Standard 2.0 from Unity, Xamarin, or UWP](https://aws.amazon.com/jp/blogs/developer/referencing-the-aws-sdk-for-net-standard-2-0-from-unity-xamarin-or-uwp/)」に記載があります。以下では細かい手順も含めて記載していきます。[^1]

[^1]: 2020/12/7時点での手順であって、今後バージョンアップに伴い変化がある可能性はあります。

## 1. AWS SDK .NET Standard のバイナリをダウンロード、展開

.NETのAWSSDK自体はNuGetからインストールして利用できるのですが、Unityの場合はバイナリを直接ダウンロードして利用します。ダウンロードは[こちらの公式ドキュメント](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-obtain-assemblies.html#download-zip-files)のリンクから。

ダウンロードしたzipファイルを解凍するとdllファイルが得られます。dllファイルはサービスごとに分かれていて、実際使うサービスものに絞って利用できます。（ただし`AWSSDK.Core.dll`は他のdllが依存しているものなので基本必要となります。）

## 2. UnityのAssets/Pluginsフォルダを作成し、必要なdllを格納

Unityを起動し、まずAssetsフォルダ内にPluginsフォルダを作成します。
次にPluginsフォルダ内に利用するdllをドラッグ&ドロップします。今回は`AWSSDK.Core.dll`と`AWSSDK.S3.dll`を利用します。

が、ここで依存関係にまつわるエラーが発生します。

> Assembly 'Assets/Plugins/AWSSDK.Core.dll' will not be loaded due to errors:
Unable to resolve reference 'Microsoft.Bcl.AsyncInterfaces'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
Unable to resolve reference 'System.Threading.Tasks.Extensions'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.

`AWSSDK.Core.dll`が依存しているdllがないよ、とのことです。。

### 依存関係を解決する

NuGetを使うと依存関係解決してくれるので楽なのですが、ここでは依存関係を追って必要なdllを入手し、それらも一緒にUnityへインポートする必要があります。[^3]
依存関係を追う方法として[こちらのページ](https://docs.microsoft.com/ja-jp/visualstudio/gamedev/unity/unity-scripting-upgrade#add-packages-from-nuget-to-a-unity-project)を参考にしました。ざっくり言うと、NuGetのパッケージ提供ページの「Dependencies」から依存関係を辿り、各パッケージのページにてパッケージをダウンロード、拡張子を.nupkgから.zipに変更して解凍するとdllが得られるのでこれを繰り返す、というものです。

[^3]: [NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity/releases)を使うと、依存関係も含めてインストールしてくれるようなので、こちら使うのも手です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20539/37f11779-8e0b-044f-aab0-886e18fc5482.png)

結果として`AWSSDK.Core.dll`が依存している以下3つのdllを入手できました。

- Microsoft.Bcl.AsyncInterfaces
- System.Threading.Tasks.Extensions
- System.Runtime.CompilerServices.Unsafe

上記dllも含めてAssets/Pluginsフォルダへ入れると、めでたくエラーなしでインポートできました。

## 3. C#スクリプト内で利用

あとはスクリプトを書けば動くはずです。
C#ScriptをAwsSdkTest.csという名前で作成し、以下のコードを記述します。
`new AmazonS3Client("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");`のダブルクォートの箇所は、お使いのAWSアカウントにて、最低限S3バケット作成の権限を持つIAMユーザーのアクセスキー・シークレットアクセスキーを作成し、置き換えます。[^2]

[^2]: 本記事では簡単なテストのため、API呼び出しの認証にアクセスキー/シークレットアクセスキーを利用しコードに直接記載していますが、セキュリティの観点から、実際には[Amazon Cognitoによる一時認証情報を利用する](https://docs.aws.amazon.com/ja_jp/sdk-for-net/v3/developer-guide/cognito-creds-provider.html)などし、コード上にキーを直接記載しないようにしましょう！

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System;
using System.Threading.Tasks;

using Amazon.S3;
using Amazon.S3.Model;

public class AwsSdkTest : MonoBehaviour
{
    string bucketName = "awssdktest-unity-bucket";
    
    async void Start()
    {
        var s3Client = new AmazonS3Client("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");

        var putBucketRequest = new PutBucketRequest
        {
            BucketName = bucketName,
            UseClientRegion = true
        };

        Task<PutBucketResponse> responseTask = s3Client.PutBucketAsync(putBucketRequest);

        try
        {
            PutBucketResponse responseObject = await responseTask;
            Debug.Log($"Created a bucket '{bucketName}'");
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
    }
}
```

Sceneに空のGameObjectを作成して上記スクリプトをアタッチし、再生すると、`bucketName`に指定した名前でS3バケットが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20539/978cae3a-889d-85bf-fbba-eb0fb86b7ef4.png)


# まとめ

Unity(**2018.1以降**)でAWSSDKを使い、簡単なコードを実行する手順を紹介しました。[Mobile SDK for Unity](https://docs.aws.amazon.com/ja_jp/mobile/sdkforunity/developerguide/what-is-unity-plugin.html)はアーカイブされていますので、[AWS SDK for .NET](https://github.com/aws/aws-sdk-net)の.NET Standard 2.0を使いましょう。
本記事が皆様のゲーム開発の一助になれば幸いです。

(免責) 本記事の内容はあくまでも個人の意見であり、所属する企業や団体とは関係がございません。内容に誤りがありましたらコメントいただければ幸いです。