Retrieve Unity Asset Bundle from S3.

Hal Brooks
4 min readFeb 17, 2022

Objective: Securely use Amazon S3 to retrieve asset bundle from Amazon S3.

First create the SecureKeys script within the Assets > Scripts folder. Using Git Bash from within the project directory, echo Assets/Scripts/SecureKeys.cs >> .gitignore and echo Assets/Scripts/SecureKeys.cs.meta >> .gitignore to add these fiel to .gitignore. For Amazon AWS this looks as shown below.

SecureKeys is ignored by Git.

Log into AWS Console and select Cognito to create a new identity pool, enabling unauthorized users. Note the region in which it was created as each region is separate, although globally accessible. Copy the identity pool ID from the script example, and paste into the awsKey string.

From AWS console select S3 and Create Bucket with new name, “S3 bucket name”. This needs to be unique form all other and as an added layer of security put this in secure keys as bucket.

Go to the AWS IAM policies to create new policy. Select S3 as service and allow access to GetObject and ListBucket. You can further restrict resources by deselecting Any and selecting ARN which allows entry of specific bucket or objects. Do not add any tags and select create policy which will build the JSON file for the policy.

Now create an empty game object and name it AWSManager.

AWSManager component setup.

Add a new script AWSManager, which will need a few namespaces, shown below.

AWSManager required namespaces.

Turn the AWSManager into a singleton so it can be easily accessed, see below. The private _instance variable is assigned later in void Awake().

Next set up the Amazon region, _S3Region, as shown below. the S3Region is a public variable, allowing the region name to be entered into the inspector as a string. This string is then converted to a RegionEndpoint recognized by AWS.

Define S3Region in AWSManager script.

The _identityPoolID is defined using the SecureKeys.awsKey defined above. This _identityPoolID with the _S3Region is used to create _credentials to access the S3 client.

Credentials needed for S3 client in AWSManager

The S3Client is defined as shown below using the Credentials and _S3Region.

In void Awake, complete the singleton assignment of this script to _instance. Use the UnityInitializer followed by AWSConfig to establish a connection with Amazon AWS. Call the S3GetBundle() method to download the Unity Asset Bundle for horse to create the HorsePrefab.

The S3GetBundle() is shown below, and uses the S3Client to GetObjectAsync. The responseObj.Response is checked for content, i.e. not null. A byte[] array is initialized to store the data into memory. Next a StreamReader, reader, opens a stream based upon the responseObj.Respose.ResponseStream. Next a MemoryStream, memory is created using the buffer byte array. The stream is then written to memory using bytesRead int, which is subsequently stored in data. The data is converted to an AssetBundle, bundle, using AssetBundle.LoadFromMemory. The HorsePrefab is stored as the horse game object.

GetS3Bundle() method in AWSManager script.

When you run this app in the Unity editor the app will work, but when running on an Android device Amazon AWS is inaccessible. Android Logcat is a useful package for Unity that can be used to monitor the Android device for errors using developer options. The link below details how to allow access to AWS. This error still persists as of Unity 2020.3.28f1.

Make sure that the BuildTarget is set to Android for the BuildPipeline, see below. Make sure this target file is stored in your Amazon S3 bucket on the cloud. In the inspector for AR Session Origin set the Tracked Image Prefab to none. Rename HorsePrefab to HorsePrefab_old so that it will not incorporate into build.

CreateAssetBundles must be set to Android device.

This article uses assets from GameDevHQ Filebase.

--

--