AWS는 다양한 프로그래밍 언어를 위한 소프트웨어 개발 도구(SDK)를 제공하고 있습니다. Python, Java, PHP 등은 물론이고, 최근에는 C/C++를 지원하는 SDK도 발표를 하였습니다. 또한, 모바일 앱을 개발을 지원하는 AWS Mobile SDK가 있습니다. AWS Mobile SDK는 iOS, Android, Fire OS 그리고 오늘 설명 드릴 Unity를 지원합니다.
Unity는 잘 알려진 게임 개발 통합 플랫폼입니다. 주로 3D게임을 편리하게 개발하기 위한 기능과 툴을 제공하고 있으며, Unity를 통해 개발된 많은 게임이 존재합니다. Unity는 게임 디자인부터 사운드와 물리 엔진 등의 여러가지 기능과 네트워크 기능도 제공하고 있습니다. AWS Mobile SDK는 기본적으로 Mobile apps에서 AWS 를 쉽게 접근할 수 있도록 함수를 제공하는 것이 기본적인 목적입니다.
따라서, AWS Mobile SDK for Unity는 Unity를 통해서 모바일 게임 등을 개발할 때 직접 Unity 코드에서 SDK를 이용하여 AWS 에서 제공하는 서비스들을 편리하게 사용할 수 있습니다.
아래 내용은 SurvivalShooter라는 공개 데모 게임에 AWS Unity SDK를 설치하고 개발하여 실제 게임에서 AWS Cognito를 통해 인증 및 데이타 싱크, S3에서 설정 파일 다운로드, Facebook과 인증 연동, 게임 정보와 로그를 DynamoDB에 기록, Mobile analytics로 게임 로그 전송을 구현한 예제입니다. 전체 코드를 참조하여 주시고, 설명은 각각의 주요 내용에 대한 핵심 부분을 간략히 설명하겠습니다.
☞샘플 코드: https://s3-ap-northeast-1.amazonaws.com/www.cloudinternal.com/SurvivalShooterAWS.zip
참고: 본 가이드는 AWS Mobile SDK for Unity Preview 버전을 기반으로 작성되어 최신 정식 SDK 버전과 약간의 차이가 있을 수 있습니다.
1. AWS Mobile SDK for Unity 소개
AWS Unity SDK는 현재(21-Oct-2015) 아래 AWS 서비스를 지원하고 있습니다. 아래 AWS 서비스를 사용하기 위한 .NET Classes를 제공하고 있어, Unity로 게임을 개발하면서 아래 서비스를 사용하기 위해 클래스를 호출하여 개발을 하게 됩니다. 최근에는 AWS Lambda를 추가로 지원하면서 Unity로 개발된 게임에서 Lambda 함수를 호출하여 (별도 백엔드 서버를 통한 처리가 아니라) 이벤트 기반 개발 로직 처리 및 구현이 가능합니다. SDK 내용을 보면 아래의 각 서비스의 플러그인 패키지로 구성되어 있습니다.
2. Unity 및 AWS Unity SDK 설치
AWS Unity SDK는 Unity version 4.x 와 5.x 의 버전과의 호환성을 가지고 있으며, 4.0~4.2버젼의 경우는 설치 시에 몇 가지 작업이 필요합니다. AWS Unity SDK의 소개와 설치에 대한 부분은 아래 링크에서 상세히 가이드하고 있습니다. 아래 링크를 참조하시어 개발 환경 구성을 구성하십시오. 순서를 요약하면 아래와 같습니다.
- Unity 다운로드 및 설치
- AWS Unity SDK 다운로드 설치
- AWS Unity SDK 설정 (생략을 하고 코드에서 직접 지정을 할 수도 있습니다.)
- Amazon Cognito를 통해 AWS Credentials 획득
- 주요 개발 문서:
3. Amazon Cognito 인증하기
AWS Unity SDK에서 AWS 리소스에 접근하기 위해서는 인증이 필요하게 됩니다. 인증을 위한 정보가 바로 AWS Credential입니다. 보통 access key, secret key로 구성하나, 모바일 게임을 개발하면서 지정된 키를 직접 코드에 넣는 것은 좋은 방법이 아닙니다. 모바일 인증을 손쉽게 하기 위한 빌딩 블럭인 Amazon Cognito를 통해 쉽게 구성할 수 있습니다.
Amazon Cognito는 Identity pool을 구성하고 해당 풀에 사용자 정보를 저장할 수 있습니다. 그리고 해당 Identity pool에 IAM 역할(role)을 정의하여 게임 사용자가 어떤 AWS 서비스를 이용할 수 있는지 정할 수 있습니다. 예를 들어 IAM role에서 DynamoDB에 PutItem API를 허락하도록 추가한다면 사용자는 AWS Cognito를 통해 전달 받은 임시 토큰을 통해 DynamoDB에 직접 데이터를 입력할 수 있습니다.
그 과정을 살펴 보도록 하겠습니다. 먼저 아래 아래 코드와 같이 AWSManager.cs
파일에 Credential provider를 생성합니다.
public string IDENTITY_POOL_ID = "";
public string ANALYTICS_APP_ID = "";
public RegionEndpoint ENDPOINT = RegionEndpoint.USEast1;
private CognitoAWSCredentials credentials;
private CognitoSyncManager syncManager;
credentials = new CognitoAWSCredentials(IDENTITY_POOL_ID, ENDPOINT);
IDENTITY_POOL_ID를 입력 받아 코드에서 해당 Identity pool ID를 읽어 인증을 진행하게 됩니다. Unity개발 도구의 Inspector에서 생성한 ID를 입력하도록 합니다. AWS 콘솔에서는 아래와 같이 Amazon Cognito 메뉴로 이동하여, Identity pool을 생성하여 인증 사용자와 비인증 사용자가 이용할 IAM 역할(Role)을 선택합니다. 위에서 설명 드린 것처럼 IAM Role에 AWS 서비스에 접근할 수 있는 권한이 주어져야 개발된 게임에서 해당 서비스에 접근을 할 수 있습니다.
4. Amazon Cognito 데이터 싱크
Amazon Cognito는 사용자 별로 데이터를 각각 저장하고 동기화하는 기능을 제공합니다. 멀티 플랫폼에서 사용자와 애플리케이션 정보를 유지하여 지속적으로 서비스에 활용하도록 하는 기능입니다. 데모 게임에서는 플레이어의 위치를 Cognito Dataset에 저장하고 다음 플레이에 해당 위치에서 시작하도록 예를 구성하였습니다.
AWSManager 클래스에서 CognitoSynchManager를 생성
syncManager = new DefaultCognitoSyncManager(
credentials, new AmazonCognitoSyncConfig { RegionEndpoint = ENDPOINT });
public Dataset GetUserProfileDataset() {
return userProfileDataset;
}
public void SetPlayerPosition(Vector3 pos) {
userProfileDataset.Put("position", NDCUtil.stringFromVector3(pos));
}
public Vector3 GetUserPosition() {
Vector3 pos = NDCUtil.vector3FromString(userProfileDataset.Get("position"));
if (pos == null) {
pos = new Vector3(0, 0, 0);
userProfileDataset.Put("position", NDCUtil.stringFromVector3(pos));
}
return pos;
}
public void SyncUserProfile() {
userProfileDataset.Synchronize();
}
Amazon S3 파일 가져오기
Amazon S3 스토리지 서비스를 게임 자원의 DLC(Downloadable Content)에 활용하면 편리하게 파일 형태의 데이터를 저장하고 읽어 올 수 있습니다. 정적 콘텐츠(Static Contents)는 물론 게임 내에서 활용할 설정이나 환경 설정(Configuration) 정보를 저장하여 게임 시작 시 다운로드하여 게임에 쉽게 활용할 수 있습니다.
이 예제 게임에서는 S3 URL을 입력하여 간단한 JSON 형태의 입력 파일을 게임 시작 시 다운로드 합니다. DLCManager 클래스에서 다운로드 코드를 구현합니다. S3를 보다 잘 사용하기 위해서는 AmazonS3Client를 이용하면 편리합니다.
public string DLC_URL = "";
public void CheckDLC() {
WWW www = new WWW(DLC_URL);
print (GameManager.Instance);
StartCoroutine(WaitForDLCRequest(www));
}
IEnumerator WaitForDLCRequest(WWW www) {
yield return www;
if (www.error == null) {
GameManager.Instance.UpdateStatusMessage("DLC updating...");
Debug.Log("WWW Ok!: " + www.text);
ParseAndUpdateDLC(www.text);
GameManager.Instance.UpdateStatusMessage("Facebook initializing...");
GameManager.Instance.OnDLCUpdateEnded();
} else {
Debug.Log("WWW Error: "+ www.error);
GameManager.Instance.UpdateStatusMessage("Failed to update content: " + www.error, false);
}
}
AmazonS3Client를 활용할 경우 아래의 예제 코드를 간단히 변경하여 적용이 가능합니다.
private void GetObject() {
ResultText.text = string.Format("fetching {0} from bucket {1}",
SampleFileName, S3BucketName);
Client.GetObjectAsync(S3BucketName, SampleFileName, (responseObj) =< {
string data = null;
var response = responseObj.Response;
if (response.ResponseStream != null) {
using (StreamReader reader = new StreamReader(response.ResponseStream)) {
data = reader.ReadToEnd();
}
ResultText.text += "\n";
ResultText.text += data;
}
});
}
5. Facebook과 인증 연동하기
Amazon Cognito Identity 는 Facebook, Google, Amazon, Twitter/Digits 및 OpenID를 이용한 연동 인증을 지원합니다. 이 게임 예제에서는 Facebook을 인증 제공자로 선택하여 인증할 수 있도록 구현하였습니다.
앞에 설명한 것처럼 Cognito는 비인증 사용자(Unauthenticated user)와 인증 사용자(Authenticated user)를 구분하여 지원할 수 있습니다. Facebook developers 페이지에서 앱을 등록하여 ID를 발급받아 Amazon Cognito Identity pool에 등록하는 과정이 필요합니다.
아래와 같이 Facebook developer 페이지에서 앱을 등록하여 ID를 발급받습니다.
Amazon Congito 에서 생성한 Identity pool의 설정에 아래와 같이 ID를 등록합니다.
보다 상세한 내용은 아래 링크를 참조해 주십시오.
http://docs.aws.amazon.com/cognito/devguide/identity/external-providers/facebook/
Unity에 Facebook 연동으로 위해 Facebook SDK를 설치합니다. 아래 링크에서 다운로드가 가능합니다.
https://developers.facebook.com/docs/android
Facebook 연동 인증은 FacebookManager.cs
로 구현되어 있습니다. GUI로 화면에서 로긴 정보를 입력할 수 있도록 구현되어 있습니다.
위에서 Find Access Token을 누르면 Facebook 페이지에서 사용자 토큰(User token)을 발급받아 입력할 수 있습니다. 키를 입력하고 Login을 누르면 Facebook 과 연동하여 Authenticated user로 인증을 진행 할 수 있습니다.
6. Amazon Mobile Analytics 사용하기
Amazon Mobile Analytics 서비스는 모바일 게임 또는 서비스에서 나오는 사용자 및 매출 통계, 캠페인을 통한 결과 등 비지니스를 위한 다양한 정보를 그래프와 함께 제공해 주는 기능입니다. 또한 맞춤형 이벤트(Custom Events)를 만들어주면 원하는 통계를 받아 볼 수 있습니다. 게임이라면 게임 내에 일어나는 다양한 이벤트를 Amazon Mobile Analytics로 간단히 추가해서 반영할 수 있습니다.
이 게임 예제에서는 게임 중에 Enemy와 Damage에 대한 정보와, 세션 시간에 대한 정보를 예제로 Amazon Mobile Analytics Custom events로 보내는 내용이 구현되어 있습니다. 참조하여 다양한 정보를 간단한 코드 추가로 분석해 볼 수 있는 기능입니다.
Amazon Mobile Analytics를 이용하기 위해서는 App을 등록하는 과정이 필요합니다 등록하여 ID를 발급 받아 해당 아디이로 생성한 App에 데이터를 넣을 수 있게 됩니다. 아래 그림은 콘솔에서 Mobile analytics app을 생성한 내용입니다.
위에 App ID를 Unity inspector에서 Cognito ID처럼 동일하게 값을 입력하여 코드에서 읽어 사용하게 됩니다.
AWSManage 클래스에 구현되어 있는 코드는 아래와 같습니다. AnalyticsManager를 생성하고 원하는 통계치 메트릭을 추가합니다.
analyticsManager = AmazonMobileAnalyticsManager.GetOrCreateInstance(
credentials, ENDPOINT, ANALYTICS_APP_ID);
public void RecordEnemyHit(string weapon, int damage, string enemyName, int score) {
AmazonMobileAnalyticsEvent customEvent = new AmazonMobileAnalyticsEvent("ShooterEnemyHit");
customEvent.AddAttribute("Enemy", enemyName);
customEvent.AddMetric("Damage", damage);
analyticsManager.RecordEvent(customEvent);
}
public void RecordSessionTime(int time) {
AmazonMobileAnalyticsEvent customEvent = new AmazonMobileAnalyticsEvent("SessionTime");
customEvent.AddMetric("SessionTime", time);
analyticsManager.RecordEvent(customEvent);
}
DynamoDB에 데이터 적재하기
AWS Unity SDK는 직접 DynamoDB에 데이터를 넣고 쓸 수 있도록 지원하고 있습니다. 중간에 다른 Back-end server를 구현하지 않고, 직접 NoSQL 데이터베이스인 DynamoDB를 읽고 쓸 수 있는 방법은 비용을 줄이고 빠르게 개발할 수 있는 장점이 있습니다. 이 게임 예제에서는 UserInfo와 ShotInfo라는 두 개의 테이블을 만들어 사용자 정보와 사용자가 게임을 하면서 발생하는 적과 데미지 무기 종류에 대한 정보를 지속적으로 DynamoDB에 넣을 수 있도록 구현하였습니다.
아래는 코드 예제로 Cognito 인증 정보를 통해 DynamoDB client객체를 생성하고 데이터를 넣는 예제입니다.
dynamoClient = new AmazonDynamoDBClient(new CognitoAWSCredentials(IDENTITY_POOL_ID, ENDPOINT), ENDPOINT);
dynamoContext = new DynamoDBContext(dynamoClient);
public void PutUserShotInfo(string weapon, int damage, string enemyName, int score) {
string userId = GameManager.Instance.userDataManager.userId;
UserShotInfo userShotInfo = new UserShotInfo{
Id = userId,
Timestamp = NDCUtil.CurrentTimestamp(),
Weapon = weapon,
Damage = damage,
Score = score
};
dynamoContext.SaveAsync<UserShotInfo>(userShotInfo,
(AmazonDynamoResult<VoidResponse> r) =< {
if (r.Exception != null) {
Debug.LogError("Save error");
Debug.LogException(r.Exception);
return;
}
}, null);
}
AWS Mobile SDK를 통해 서버를 통하지 않고 직접 AWS의 다양한 서비스를 활용하는 방법은 최근 이야기되는 Serverless architecture를 이용하여 낮은 비용과 빠른 개발 시간을 통해 다양한 게임을 개발할 수 있는 새로운 방법을 제공하여 줍니다.
더불어 Unity라는 게임 개발 플랫폼에서 게임 개발과 동시에 AWS의 서비스를 직접 활용할 수 있도록 하는 AWS Mobile SDK for Unity는 예제와 같이 단순한 코드로 콘텐츠, NoSQL DB, 분석 등의 다양한 기능을 직접 구현할 수 있도록 게임 개발자 분들에게 편리한 기능을 제공합니다. Unity로 게임을 개발하면서 Back-end service를 AWS로 구성하여 다양한 게임을 개발하는데 도움이 되었으면 합니다.
본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김일호 솔루션즈 아키텍트께서 작성해주셨습니다.