はじめに
〜AWSさんに届け〜
S3のサンプルに画像を扱うものもあるとヒヨコには嬉しいです。ぐぐると探している人もいるようでした。
日本語でドンピシャな情報にたどり着けなかったのでメモっておきます。
UnityのテクスチャにAWSの画像を使いたい話です。
3行で要点だけ欲しい人向け情報
- SDKをダウンロードしてきてUnityにインポート
- AWS側の準備する(S3,Cognito,Cognito用IAMロール)
- サンプルを修正して(サンプルだと文字の読み取りなので画像の処理に変更して)動かす
やったこと詳細
環境
- Unity 2017.3.1f1(64bit)
- Mac利用
SDKをダウンロード&インポート
- 公式手順: https://docs.aws.amazon.com/ja_jp/mobile/sdkforunity/developerguide/setup-unity.html
- zipをダウンロードして来て適当に展開する
- UnityのプロジェクトにS3の
AWSSDK.S3.3.3.18.2.unitypackage
をインポートする - unitypackageの名前のとおりですが、自分が使ったバージョンは
aws-sdk-unity_3.3.281.0
でした
AWS側の準備する
S3の準備
- bucketを用意する
- 適当な画像ファイル(自分はPNGを利用しました)をアップロードしておく
- bucket名、ファイル名はあとで使います
Cognitoの設定(IAMロールの設定)
-
Manage Federated Identities
から新規で作成 - IAM ROLEを設定、S3の必要な権限を追加しておく(ひとまず試したいのであれば
S3FullAccess
をくっつけておくと間違いないはず)
Unityに準備したAWSの情報をいれていく
- サンプルの
Assets/Exapmles/S3Example
を開いて編集していく -
S3
というGameObjectがHierarchy内にあるので、選択してInspectorタブでS3 Example(Script)
を見つけて先ほど作ったS3とCognitoの情報を入れ込む - Tokyoリージョンは
ap-northeast-1
デスヨ
サンプルを修正して動かす
とりあえず、疎通確認する
- サンプルなのでそのまま動くだろうと安易にPlayしてみましょう。そして、画像を取ってくるのが目標なので、
Get Object
をポチる。自分はここが動きませんでした - 動かない理由が自分と同じ
InvalidOperationException: Cannot override system-specified headers UnityEngine.Networking.UnityWebRequest.SetRequestHeader (System.String name, System.String value) (at /Users/builduser/buildslave/unity/build/Modules/UnityWebRequest/Public/UnityWebRequest.bindings.cs:424) ...
であれば、Start関数内を以下を参考に修正してください(2行目が追加されています) - 理由はこちら: https://aws.amazon.com/jp/blogs/mobile/unity-v3-support-in-the-aws-sdk-for-net-is-out-of-preview/
S3Example.cs
void Start()
{
UnityInitializer.AttachToGameObject(this.gameObject);
AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest; //added
GetBucketListButton.onClick.AddListener(() => { GetBucketList(); });
PostBucketButton.onClick.AddListener(() => { PostObject(); });
GetObjectsListButton.onClick.AddListener(() => { GetObjects(); });
DeleteObjectButton.onClick.AddListener(() => { DeleteObject(); });
GetObjectButton.onClick.AddListener(() => { GetObject(); });
}
- 再トライ。エラーが出ずに、ファイル名が表示されるようになればOKです。別のエラーなどは、AMIロールの権限かbucket名、ファイル名を確認してみてください
GetObjectのところを画像を取得して貼り替えるものに変更する
- ソースコードを以下のとおり変更
S3Example.cs
public GameObject imagebox = null; // added 画像を貼り付けるオブジェクトとして利用
private void GetObject()
{
Client.GetObjectAsync(S3BucketName, SampleFileName, (responseObj) =>
{
MemoryStream stream = new MemoryStream();
responseObj.Response.ResponseStream.CopyTo(stream);
Texture2D tex = new Texture2D(4, 4);
byte[] results = stream.ToArray();
tex.LoadImage(results);
imagebox.GetComponent<Renderer>().material.mainTexture = tex;
}
);
}
- 保存するとCopyToのところで
Assets/Examples/S3Example.cs(130,49): error CS1061: Type
System.IO.Stream' does not contain a definition forCopyTo' and no extension method
CopyTo' of typeSystem.IO.Stream' could be found. Are you missing an assembly reference?
がでますが、今回は設定を変更して回避 - Edit > Project Settings > Player で、Other Settings内のConfigurationのScripting Runtime Versionを
Experimental(.NET 4.6 Equivalent)
に変更して再起動 - Hierarchy内に適当なCubeなどのオブジェクトを追加
- S3オブジェクトのスクリプトで追加したimageboxに紐付け
- 実行。GetObjectのボタンを押すと、ログのところを消してしまったので、Game画面上は変化ないですが、SceneビューのCubeに画像が貼り付けられます
オワリ
Windowsでも動きました。回り道してたので、なにかもっとズバッといけるところあれば教えてください・・・