Connecting Unity3D with AWS services
Tags: unity3d, csharp, aws, services
Published: 2023-06-30 00:43:57

In my [last articles](https://medium.com/@alexandre.bruffa), I realized direct integrations between Unity3D and AWS using the AWS SDK for .NET. I generally don't dive into details about how the connection between Unity3D and the AWS services is made in order to focus on the primary topic. Still, it deserves a whole article because it’s not that simple!

There are many ways to access AWS resources from Unity. In this article, I will summarize three of them: using an IAM user, using a Cognito guest user, and using a Cognito authenticated user.

**General considerations**: For this article, we will use the AWS SDK for .NET. Since Unity uses .NET Standard 2.1, you will need the .NET Standard 2.0 assemblies available [here](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-obtain-assemblies.html#download-zip-files) and unzip the file in your Unity project's `Plugins` folder. Since we will perform asynchronous calls, you will also need the [AsyncInterfaces](https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces/) package.

If you prefer to watch a video instead of reading this article, here you have!

{% embed https://youtu.be/IW1b30AbiLw %}

## 1. Using an IAM User

Suppose you want to allow a specific user (i.e., a third-party app) to upload files to one of your S3 buckets. However, you only want to give programmatic access without implementing a signup or login flow. Using an IAM user is a perfect fit in this case.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kchxzqnrlu7iha1e6lwl.png)

Let’s simulate the process: 

- In the S3 console, create a new S3 private bucket. I will call mine `awsresourcesbucket`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s888m0ep9zh10eqlj38i.png)

- In the IAM console, create an IAM user with programmatic access and create a new Access Key; you will be given an Access Key and a Secret Access Key. Once created, don't forget to copy the Secret Access Key. It is shown just one time!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2oxkxj7tbyi934iup8w5.png)

- Attach a new policy to the IAM user. The policy gives the required permissions to write into the S3 bucket.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lc8xg2trygeilr90567.png)

- In Unity, build an S3 Client thanks to the IAM user's Access Key and Secret Access Key, and upload the file.

{% embed https://gist.github.com/alexandre-bruffa/09cc84d7babc7855a4cabf1e3907ba7d %}

Comments about the above code:
- We use the [NativeGallery package](https://assetstore.unity.com/packages/tools/integration/native-gallery-for-android-ios-112630) to pick an image from the device.
- We use the [PutObjectAsync](https://docs.aws.amazon.com/sdkfornet/latest/apidocs/items/MS3S3PutObjectAsyncPutObjectRequestCancellationTokenNET45.html) function as described in the [AWS documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example_s3_PutObject_section.html).
- The `UploadFileAsync` function is asynchronous; you can call it with the `await` operator inside an `async` function.

## 2. Using a Cognito Guest User

You may remember my [last article](https://medium.com/better-programming/building-a-real-time-multiplayer-game-with-unity3d-and-amazon-gamelift-228f706cfbec), where I built a real-time multiplayer game with Unity3D and Amazon GameLift. The Unity client calls a Lambda function to start playing, and we want that everybody who has downloaded the game can play without being logged in. You can achieve it using guest users of a Cognito Identity Pool. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h15scz9u94vrlkdnysrz.png)

Let’s simulate it: 

- In the Lambda console, create a simple Lambda function returning a dummy value (I will call it `awsResourcesFunction`). I will do it in Python, but it's up to you to choose your favorite programming language.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0wkz1sc40ckzxqk7zns.png)

- In the Cognito console, create a Cognito Identity Pool with guest access. During the Pool creation, you will be asked to create a new guest role; I will call them respectively `awsResourcesIdentityPool` and `awsResourcesCognitoGuestRole`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7snz8o3dprf849gh2nm.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e398k90pdigw401ftf87.png)

- Once the Identity Pool is created, enter the guest role and attach a new policy. The policy gives the required permissions to invoke the Lambda function we have created before.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05lnedn5kd27s7mzmz8o.png)

- In Unity, we first build the AWS Credentials thanks to the Identity Pool ID and then the Lambda Client with those credentials.

{% embed https://gist.github.com/alexandre-bruffa/4807e5c7c174fb7a9edd4ba3f9d2ae49 %}

Comments about the above code: 
- The [AWS documentation](https://docs.aws.amazon.com/lambda/latest/dg/API_InvokeAsync.html) indicates that the `InvokeAsync` function has been deprecated, but remember that we are using the .NET Standard 2.0 assemblies, so it's valid for us!
- The [InvokeAsync](https://docs.aws.amazon.com/sdkfornet/latest/apidocs/items/MLambdaLambdaInvokeAsyncStringNET45.html) function is asynchronous; you can call it with the `await` operator inside an `async` function.

## 3. Using a Cognito Authenticated User

Now imagine that you want to allow the players of your game to upload a profile picture, but you require a login to do it. This case is a bit more complex because your game will handle guest and authenticated users. You can achieve it by creating a User Pool and adding authenticated access to our Identity Pool.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjso0sfckcavi7dyzr8r.png)

Let's try:

- In the Cognito console, create a new User Pool. You also be asked to create an Application Client during the User Pool creation. Don't forget to enable the `ALLOW_USER_PASSWORD_AUTH` as authentication flow. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cunhl5qtm22yglnej2n1.png)

- For this example, we assume we already have a user registered and confirmed. Please take a look at this [article](https://medium.com/better-programming/signing-up-users-from-unity3d-to-aws-cognito-using-the-aws-sdk-for-net-4a45f3a5f1fc) of mine to learn how to do it. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3seoc33pv2qmlcc4228.png)

- Then, go back to the Identity Pool we created before, click on "Add identity provider" of the Authenticated access section, choose "Amazon Cognito User Pool", and link the Cognito User Pool we have created previously. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmhle53yzjf79l597e51.png)

- Go then to "Edit role", create a new role, and attach a new policy to the role (or you can reuse the policy we created for the IAM User). The policy gives the required permissions to write into the S3 bucket.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gkd0fdu6w4c1l9h0ycer.png)

- In Unity, we first login to the Cognito User Pool with the user Credentials; a `Token ID` is returned. Then we build the AWS Credentials thanks to the Identity Pool ID, and we add the login data to the AWS Credentials: the `Token ID` and the User Pool `Provider Name`. We can finally build the S3 Client with the AWS Credentials and upload a file. 

{% embed https://gist.github.com/alexandre-bruffa/51e517d2ba855ba88ce4c7fe995de9f8 %}

Comments about the above code:

- We log in to the Cognito User Pool thanks to the [InitiateAuthAsync](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CognitoIdentityProvider/MCognitoIdentityProviderInitiateAuthInitiateAuthRequest.html) function.
- We add the login data to the AWS Credentials thanks to the [AddLogin](https://docs.aws.amazon.com/sdkfornet/latest/apidocs/items/MCognitoIdentityCognitoAWSCredentialsAddLoginStringStringNET45.html) function.
- The `Provider Name` is the concatenation of the following: `cognito-idp.` + region + `.amazonaws.com/` + Cognito User Pool ID.

## Final Thoughts

Connecting Unity3D with AWS services is challenging work; I hope that this article could help you!

All ids and tokens shown in this article are fake or expired; if you try to use them, you will not be able to establish any connections.

Every code of this article has been tested using Unity 2021.3.3 and Visual Studio Community 2022 for Mac. The mobile device I used to run the Unity app is a Galaxy Tab A7 Lite with Android 11.

A special thanks to [Gianca Chavest](https://www.instagram.com/niimde/) for designing the fantastic illustration.