블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2861)
Unity3D (899)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (192)
협업 (65)
3DS Max (3)
Game (12)
Utility (142)
Etc (99)
Link (34)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday


링크 : http://nukestorm.tistory.com/97

반응형
Posted by blueasa
, |


Link : https://aws.amazon.com/ko/documentation/sdk-for-unity/

반응형
Posted by blueasa
, |

Amazon Web Services 한국 블로그

AWS Unity SDK 로 간단한 게임 구현하기

on  | in AWS LambdaAWS SDK한국 기술 문서한국 소식 | 

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의 소개와 설치에 대한 부분은 아래 링크에서 상세히 가이드하고 있습니다. 아래 링크를 참조하시어 개발 환경 구성을 구성하십시오. 순서를 요약하면 아래와 같습니다.

  1. Unity 다운로드 및 설치
  2. AWS Unity SDK 다운로드 설치
  3. AWS Unity SDK 설정 (생략을 하고 코드에서 직접 지정을 할 수도 있습니다.)
  4. Amazon Cognito를 통해 AWS Credentials 획득
  5. 주요 개발 문서:

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를 생성합니다.

C#

public string IDENTITY_POOL_ID = "";
public string ANALYTICS_APP_ID = "";
public RegionEndpoint ENDPOINT = RegionEndpoint.USEast1;

private CognitoAWSCredentials credentials;
private CognitoSyncManager syncManager;

// Create a Credentials provider that uses Cognito Identity
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를 생성

C#


// Cognito Sync Manager
syncManager = new DefaultCognitoSyncManager(
credentials, new AmazonCognitoSyncConfig { RegionEndpoint = ENDPOINT });
//UserDataManager에서 플레이어 위치 정보를 저장하고 읽어 올 수 있도록 구현합니다.
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를 이용하면 편리합니다.

C#

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;

	// check for errors
	if (www.error == null) {
		GameManager.Instance.UpdateStatusMessage("DLC updating...");
		Debug.Log("WWW Ok!: " + www.text);
		ParseAndUpdateDLC(www.text);
		GameManager.Instance.UpdateStatusMessage("Facebook initializing...");
	//  FB.Init(FacebookInitCallback);

		GameManager.Instance.OnDLCUpdateEnded();
	} else {
		Debug.Log("WWW Error: "+ www.error);
		GameManager.Instance.UpdateStatusMessage("Failed to update content: " + www.error, false);
		}
}

AmazonS3Client를 활용할 경우 아래의 예제 코드를 간단히 변경하여 적용이 가능합니다.

C#

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를 생성하고 원하는 통계치 메트릭을 추가합니다.

C#

// Amazon Mobile Analytics Manager
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객체를 생성하고 데이터를 넣는 예제입니다.

C#

// Dynamo DB 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 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김일호 솔루션즈 아키텍트께서 작성해주셨습니다.


출처 : https://aws.amazon.com/ko/blogs/korea/aws-unity-sdk-game/

반응형
Posted by blueasa
, |


링크 : http://www.thisisgame.com/webzine/news/nboard/4/?n=60622

반응형
Posted by blueasa
, |

[홈페이지] http://www.glorylogic.com


링크 : http://clason.tistory.com/372

반응형
Posted by blueasa
, |





출처 : http://www.slideshare.net/ndoors/2014-33402528

반응형
Posted by blueasa
, |
using System;

// 1200초(20분) 받아서 시간:분:초 표시하기
TimeSpan ts = new TimeSpan(0, 0, 1200);
string strTemp = string.Format("{0:HH:mm:ss}", ts);

Debug.Log(strTemp);


[날짜/시간 출력 참조]

http://www.csharp-examples.net/string-format-datetime/


반응형
Posted by blueasa
, |

프로젝트를 진행하다보면 NGUI의 label만으로는 표현이 뭔가 아쉬운 경우가 있다. 특히 게임 캐릭터나 유닛이 데미지를 받는다거나, 스코어를 보여준다거나 하는 상황에서 사이즈가 큰 폰트를 써야 할 경우가 많은데, 이럴 경우 기본 폰트의 크기가 작아 폰트가 지저분하게 보인다거나 게임 자체가 뭔가 허접(?)하게 보일 확률이 높다.

"0부터 9까지의 숫자 부분만 따로 떼어 특별한 이미지로 만든 후에 이것을 label로 쓸 수 있다면..?"

이런 생각으로, 데미지 폰트를 만드는 방법을 검색해 보았으나... BMFont를 이용한 폰트를 만드는 방법은 여기저기 블로그 등에 널려(...) 있는데 비해, 이미지로 구성된 숫자 폰트를 만드는 방법은 의외로 찾아보기 어려웠다. 약간의 삽질 끝에 숫자 폰트를 만드는 방법을 확실히 알게 되어 공유해 보겠다. 

준비물
Unity, NGUI, BMFont, 폰트로 만들 0부터 9까지의 이미지

참고로 여기서 사용한 각 툴의 버전은 다음과 같다.
Unity3D: 4.1.5
NGUI: 2.6.3
BMFont: 1.13

1. BMFont를 띄우고 0부터 9까지 폰트로 만들 숫자를 선택한다.


일반적인 BMFont를 만드는 과정과 거의 비슷한데, 폰트 중에 숫자 부분만을 선택(클릭)한다는 점이 다르다. (보통 인터넷에 돌아다니는 KS1001.txt 파일을 import하는 과정...)
숫자를 클릭하면 어두운 회색 박스가 약간 밝은 회색 박스로 변한다. 이런 식으로 0부터 9까지 선택을 한다.

2. Image Manager를 띄운다.


일반 폰트를 만들 때는 존재조차 있는지 몰랐던, Image Manager를 띄운다.

3. Import Image


Image Manager를 띄우면 달랑 메뉴 하나에 빈 창만 보이는데, 메뉴의 Image => Import image를 클릭한다.

4. Id 입력


파일을 선택하는 창이 뜨는데, 준비해둔 숫자 폰트 중 0번 이미지를 선택하자. 그러면 위와 같은 Icon Image 창이 뜬다.
여기서 주의할 점은 Id 부분인데, 0번 이미지의 Id를 48로 변경하고 Ok를 눌러주자.
나머지 1번부터 9번까지는 0번 이미지부터 순서대로 Id값을 1씩 늘려나가면 된다. 이렇게 하면 9번 이미지는 Id가 57번이 된다.


5. 설정 확인


0번부터 9번 이미지를 모두 Import했다면 위와 같은 화면을 볼 수 있을 것이다.
0부터 9까지의 문자 박스에 하늘색 점이 표시되어 있고, 밝은 회색 박스로 변해 있다는 것을 알 수 있다. 만약 자신이 작업한 결과물이 위의 스샷과 다르다면 지금까지의 작업 과정을 다시 한 번 차근차근 확인해 보자.


6. Export Options


이제 Export Options를 설정해야 한다. BMFont의 Options => Export Options를 클릭하여 옵션 창을 띄우자.
확인할 사항은 두 가지이다. 첫 번째는 Bit depth인데 32비트로 바꾸면 된다. 만약 8비트 상태 그대로 둔다면 원래의 색상이 아니라 희멀건 폰트를 보게 될 것이다. 두 번째는 Textures인데, 유니티 프로젝트에서는 대부분 png 이미지를 사용하므로, png로 바꾸면 된다.
Save bitmap font as...를 누르면 저장할 이름을 결정하는 창이 뜬다.
여기서는 DamageFont라고 정해보았다.


[참고] 이후의 과정은 일반적인 BMFont를 만드는 과정과 같다.

7. fnt를 txt로 변경


저장하면 fnt와 png 파일이 생긴다. 이 중 fnt 파일의 확장자를 fnt에서 txt로 바꾼다.


8. txt와 png를 유니티의 프로젝트로 드래그&드롭


앞의 과정에서 만든 txt와 png를 유니티의 프로젝트에 드래그&드롭한다.
이제 NGUI의 Font Maker를 열어 폰트를 만들면 되는데, 유니티 메뉴 => NGUI => Open the Font Maker를 클릭한다.


9. Font 아틀라스 만들기


지금까지의 과정을 정상적으로 진행했다면 위와 같은 모습을 볼 수 있다. 앞의 과정에서 프로젝트에 포함시켰던 txt 파일을 Font Data로 드래그하고, png 파일은 Texture로 드래그한다.
Font Name을 입력하고 Create 버튼을 누르면 프로젝트 폴더에 아틀라스와 마테리얼이 생성된다.


10. 최종 테스트


NGUI의 Widget Tool을 띄운 후, 조금 전 만든 DamageFont 아틀라스를 Font로 선택한다. Label을 만든 후 정상적으로 폰트가 출력되는지 확인하자. 지금까지의 과정을 차근차근 따라했다면 위의 스샷처럼 Scene 화면에서 데미지 폰트로 된 Label을 확인할 수 있을 것이다.


출처 : http://lianes.tistory.com/49

반응형
Posted by blueasa
, |

코루틴(Coroutine)++

Unity3D/Tips / 2015. 10. 19. 11:32

출처 : http://unityindepth.tistory.com/21


원문은 이곳에서 보실수 있습니다.



그는 코루틴으로 속임수를 쓴다.
그들은 실행되고,  왜 때때로 작동하지 않는가!!!
또, 컷 시퀀스를 만드는 방법과 강력한 기술을 사용하여 
오랫동안 실행시키는 방법에 대해서 배워 보자

목적


만약 코루틴에 대해서 확실하게 모르거나, 원하는 작업을 하고자 할 때 문제가 발생했다면 당신은 반드시 이 튜토리얼을 읽어야 한다.


코루틴은 다음과 같은 훌륭한 방법이다:

  • 특정 일을 단계적으로 발생하게 한다.

  • 시간이 흐름에 따라 발생하는 루틴을 작성할 수 있다.

  • 다른 연산이 완료될때까지 기다리는 루틴을 작성할 수 있다.
예를 들어, 컷 씬 시퀀스를 조직하는데 코루틴을 사용하는 것을 쉽게 생각할 수 있다. 혹은 단순히 적이 죽는 애니메이션을  기다린 다음, 재생성을 할 수 있을 것이다.

코루틴은 유니티의 매우 강력한 부분이지만, 종종 초심자에 의해서 이 주제에 대해 많은 오해를 받는다. 이 튜토리얼은 당신이 강력하고 융통성있는 코루틴을 파악하고, 그들이 어떻게 작동하는지 이해하는데 도움을 줄 것이다.


만약 단지 몇 초 동안 특정 연산을 지연시키기를 원한다면, Invoke를 사용하는 것을 고려해봐라. 물론 코루틴을 사용할 수는 있지만, 초보자들에게는 Invoke가 더 쉽다.

쓰레드와 코루틴


우선, 이들에 대해서 명확하게 하자, 코루틴은 쓰레드가 아니다. 코루틴은 비동기가 아니다
(not asynchronous).
(역자 주 : 비동기가 아니다라는 말은, 쉽게 말해서 동시에 발생하지 않는다는 뜻이다.)
쓰레드의 비동기와 동기의 개념이 잘 이해가 안된다면

쓰레드는 프로그램에서 다른 쓰레드와 함께 비동기로 실행된다. 멀티프로세서 기계에서, 쓰레드는 실제 다른 쓰레드와 함께 동시에 코드가 실행될 수 있다. 이는 쓰레드를 프로그래밍하는 것을 이해하기 복잡하게 만드는데, 왜냐하면 하나의 쓰레드는, 다른 쓰레드가 특정 부분을 읽고 있는 동시에, 그것을 변경할 수 있기 때문이다.

이는 더 복잡한데, 왜냐하면 당신이 작성한 코드는 컴파일러에 의해서 어셈블리어로 변경이되는데, 이는 다른 쓰레드가 당신의 소스코드의 한 부분을 처리하면서, 실제로 게임 중에 특정 부분을 변경할 수 있다는 것을 의미한다.이 때문에, 당신은 공유 메모리영역을 만들지 않거나, 공유된 자원을 읽거나 변경시키고 있을 때에는, 공유된 자원으로부터 다른 쓰레드를 잠궈버림으로서, 이런 상황을 발생시키지 않도록 하기 위해서 고생을 겪을 것이다.

쓰레드는 다음 글의 주제가 될 것이다.

그래서 코루틴이 무엇인가?


우리는 분명하게 코루틴이 쓰레드가 아니라는 것을 확실하게 했다. 이는 한번에 오직 하나의 코루틴이 실행되고, 게임의 주된 쓰레드에서 그것이 실행된다는 것을 의미한다. 사실, 한때 게임의 핵심 코드로 실행되는 것들 중 하나에 불과하다.


코루틴을 프로그래밍할 때, 당신은 절대 동기화와 특정 값을 잠금하는 것에 대해서 걱정할 필요가 없다. 당신의 코드에서 yield를 실행하기 전까지 완전한 통제를 할 수 있을 것이다.

그래서 여기 코루틴에 대한 정의가 나와있다:

코루틴은 부분적으로, 그리고 특정한 상황이 맞아 떨어졌을 때 실행되는 함수로써,
그 작업이 완료가 되기전까지, 미래의 어느시점에 재개될 수 있다.

유니티는 코루틴을 하나 혹은 여러개를 가지는 모든 객체에 대해서 게임의 모든 프레임마다 코루틴을 처리한다.
이 처리는 대부분의 yield 문에 대해서 Update가 끝나고, LateUpdate가 시작하기전에발생하는데, 그러나 여기 특별한 경우가 있다:

코루틴이 활성화되었을 때, 바로 다음 yield 문까지 실행될 것이고, 그것은 다시 시작될 때까지 일시정지할 것이다. 위에 다이어 그램을 통해서, 당신이 yield한 것을 기반으로 어디에서 재시작되는지 알 수 있을 것이다.


정말 간단한 코루틴을 보자:
1
2
3
4
5
6
7
8
IEnumerator TestCoroutine()
{
      while(true)
      {
           Debug.Log(Time.time);
           yield return null;
      }
}

이 코루틴은 명백하게 영원히 작동하는 루프를 가지고 있다. 이 코루틴은 현재 시간으로 로그를 남기고, 그 다음 yield한다. 다시 재개될 때, 다시 루프를 돌아서 로그를 남기고, 한번 더 yield될 것이다.

루프안에 있는 코드는 정확하게 Update 함수와 같다. 단지 Update 루틴이 실행된 후에(만약 Update문이 있다면), 모든 프레임마다 한번 실행이 되는 것이다.


StartCoroutine(TestCoroutine())를 호출할 때, 코드는 첫번째 yield를 만날때까지 즉시 실행되며,
유니티 프로세스가 이 객체에 대해서 코루틴을 처리할 때, 다시 재개된다.


Start, Update, OnCollisionEnter함수에서처럼 게임 객체의 처리 앞부분에 코루틴을 시작한다면, 코루틴은 즉시 첫번째 yield까지 실행될 것이고, 만약 yield return null을 사용했다면 같은 프레임 동안 다시 재개가 될 것이다. 만약 당신이 이것을 이해하지 못한다면 때로 이상한 효과를 초래할 수도 있다.

Start와 OnColiisionEnter를 코루틴으로 만드는 것은 문제가 되지 않는다.

한계를 넘어

자 이제 한가지 더 - 우리의 테스트 코루틴에서의 명백한 무한 루프는 무한하지 않다는 것이 판명되었다. 

만약 게임 객체에 대해서 코루틴을 중단하는 함수를 호출하거나, 객체가 파괴가 된다면, 이 무한 루프는 절대 다시 실행이 되지 않을 것이다. 또한 스크립트가 직접적으로 또는 SetActiveResursively(false)를 통해서 비활성화(disable)되면, 코루틴은 멈추게 될 것이다.

I Yield Sir

나는 마지막 섹션에 문장을 하나 만들었는데, 당신은 아마 의문이 들 것이다. 


하나 혹은 여러개의 코루틴을 가지는 게임내 모든 객체에 대해서 유니티는 매프레임마다 코루틴을 처리한다.
당신은 아마, 만약 yield return new WaitForSeconds(1) 같은 문장을 사용한다면, 그것은 1초동안 어떤 것도 처리하지 않기때문에  "오, 그렇지 않다" 라고 생각할지도 모른다. 

실제로 유니티는 매 프레임마다 올바른 시간이 경과되었는지 검사를 하면서, 코루틴을 처리한다.
- 이것은 당신의 코드에서 처리하지 않는다. 그러나 당신의 코드를 둘러 싸고 있는 랩퍼인 코루틴을 처리한다.

몇가지 값들을 yield함으로써 우리의 코드를 효과적으로 멈출수 있다는 것을 알았다. 여기에는 우리가 yield할 수 있는 것들이다.

  • null - Update구문의 수행이 완료될 때까지 대기한다.

  • WaitForEndOfFrame - 현재 프레임의 렌더링 작업이 끝날 때까지 대기한다.

  • WaitForFixedUpdate - FixedUpdate구문의 수행이 완료될 때까지 대기한다.

  • WaitForSeconds - 지정한 초만큼 대기한다.

  • WWW - 웹에서 데이터의 전송이 완료될 때까지 대기한다.
    (WaitForSeconds or null처럼 재시작한다.)

  • Another coroutine - 새로운 코루틴은 yielder가 재시작되기 전에 완료 될 것이다.


또한 yield break; 명령어를 실행할 수 있다. 이는 즉시 코루틴을 멈춘다.


WaitForEndOfFrame때문에,모든 카메라가 렌더링과 GUI의 출력이 완료되었을 때,  코루틴은 render texture로부터 정보를 얻는데 사용될 수 있다.
만약 Time.timeScale이 0으로 설정되어 있다면, yield return new WaitForSeconds(x)를 사용하는 것은 절대 재시작 되지 않는다.
물론, 이 모든 것들에 대해 가장 좋은 것은 특정 기간 동안 실행되는 코드를 작성하거나, 혹은 약간의 외부 이벤트가 일어나기를 기다리는 코드를 작성하고, 그것들을 당신의 코드를 훨씬 더 읽기 쉽게 만드는 하나의 함수 안에서 관리하는 것이다.(만약 여러 개의 함수를 작성해야 했거나, 상태를 확인하기 위해서 많은 코드를 작성해야 했다면)

요약

  1. 코루틴은 시간에 따라 혹은 외부의 처리가 완료되었을 때, 연산이 일어나는 순서를 정하는 정말 멋진 방법이다.

  2. 코루틴은 쓰레드가 아니다. 그리고 비동기가 아니다(동시에 일어나지 않는다.)

  3. 코루틴이 실행되고 있을 때, 다른 어떤 것들도 실행되지 않는다.

  4. 코루틴은 yield 문의 조건을 만족시켰을 때, 재개될 것이다.

  5. 코루틴은 스크립트가 비활성화(disabled)되거나, 객체가 파괴되었을 때, 비활성화 된다.

  6. yield return new WaitForSeconds는 Time.timeScale에 의해 영향을 받는다.

코루틴의 활용


바라건대, 우리는 코루틴이 무엇인지 그리고 그들이 어떻게 작동하는지 알아봤다. 우리의 상급 튜토리얼은 그들 뒤에 있는 기술에 대해서 살펴볼 것이다.

어떤 일을 하는 코루틴을 사용해보자. 몇몇 간단한 헬퍼 함수는 실제로 코루틴을 사용해서 쉽게 컷 시퀀스를 만드는 것을 도와준다.

우리는 물체를 목표 위치와, 회전값으로 움직이게하는 코루틴을 작성할 수 있다. 또 우리는 애니메이션이 일정 비율에 도달 했을 때까지 기다리는 코루틴을 작성할 수도 있다. 이 두가지 도구를 사용하여, 우리는 쉽게 하나의 함수로 전체 컷 시퀀스를 읽기 쉽게 스크립트 할 수 있을 것이다. 


코루틴에서 어떤 것을 움직일 때를 기다리는 것은, 동시에 객체의 위치를 조작하는 다른 코루틴 또는 업데이트 함수간의 충돌이 없다는 것을 보장한다.

당신은 오직 한번에 하나의 객체에 영향을 미치는 코루틴을 만들어야하고, 객체를 움직이게 하는 Update는 비활성화 시켜야 한다.

여기 애니메이션이 특정 부분 완료되기까지를 기다리는 코루틴의 예가 있다:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
//Wait for an animation to be a certain amount complete
IEnumerator WaitForAnimation(string name, float ratio, bool play)
{
    //Get the animation state for the named animation
    var anim = animation[name];
    //Play the animation
    if(play) animation.Play(name);
 
    //Loop until the normalized time reports a value
    //greater than our ratio.  This method of waiting for
    //an animation accounts for the speed fluctuating as the
    //animation is played.
    while(anim.normalizedTime + float.Epsilon + Time.deltaTime < ratio)
        yield return new WaitForEndOfFrame();
 
}

당신은 애니메이션을 기다리는 코루틴을 다음과 같이 작성할 수 있다.
01
02
03
04
05
06
07
08
09
10
11
IEnumerator Die()
{
       //Wait for the die animation to be 50% complete
       yield return StartCoroutine(WaitForAnimation("die",0.5f, true));
       //Drop the enemies on dying pickup
       DropPickupItem();
       //Wait for the animation to complete
       yield return StartCoroutine(WaitForAnimation("die",1f, false));
       Destroy(gameObject);
 
}

비디오는 당신에게 더 많은 것들을 보여준다. 예제 프로젝트는 여기서 얻을 수 있다.

비디오


만약 강력한 코루틴 도구를 어떻게 만들고, easing 함수를 적용하고, 코루틴을 다음 단계로 개발하는 방법을 알고싶다면, 반드시 이 비디오를 봐야한다.
이 비디오는 꽤 길지만, 그것은 정말 멋지다. 코루틴을 사용해서 전체의 컷 시퀀스를 만드는 방법을 배워라. 그리고 어떻게 easing 함수에 yield 문을 적용하는지를 봐라.

비디오의 끝 무렵에, 우리는 어떻게 고급 코루틴 도구를 만드는지와 멋진 효과를 만들기위해 그것들을 사용하는 방법에 대해 알게 될 것이다. 다운로드한 프로젝트는 비디오에서 보여주었던 모든 부분을 담고 있다.











반응형
Posted by blueasa
, |


[Link] https://www.google.com/get/noto/

반응형

'Utility > Fonts' 카테고리의 다른 글

[코딩폰트] Dina-Font-TTF-Remastered  (0) 2024.08.21
개발자용(Dina) 폰트  (0) 2010.06.18
Posted by blueasa
, |