아바타 적용
소개
이 문서는 Unity, C#을 사용하여 UniMaxstAvatar 사용하는 방법을 안내합니다.
소스코드
해당 문서에서 제공되는 예제는 unipassport를 활용하여 로그인 되있다고 가정하고 작성되었습니다.
Workflow
Step 1. 사용자 아바타 저장정보 조회
- 로그인된 유저가 이전에 저장한 아바타 정보를 API서버에 요청합니다.
Step 2. 어플리케이션 에서 선택할수 있는 아바타 아이템 로드
- 어플리케이션 에서 선택할수 있는 아바타아이템을 API서버에 요청합니다.
- 아바타 아이템 로드가 완료되면 아바타 커스터마이징 화면으로 이동합니다. 이전에 아바타 착장정보가 저장된 상태라면, 착장정보 조회 API를 요청하여 이전에 착용하였던 아바타 정보를 조회할수 있고 해당값으로 로드할수있습니다. 이전에 아바타 착장 정보가 없다면 어플리케이션에서 착용할수 있는 아이템을 착용한상태로 화면에 진입하게 됩니다.
Step 3. 아바타 아이템 선택 및 애니매이션 테스트
- 아바타 아이템을 선택 및 변경 할수 있고, 변경된 모습을 확인할수 있습니다.
- 변경된 아이템을 착용한 채로 애니매이션 테스트를 할수 있습니다.
Step 4. 아바타 아이템 선택 정보 저장
- 아바타 아이템 선택이 완료되면 API서버에 요청하여 해당정보를 저장할수 있습니다.
- 아바타 아이템 착장정보 저장이 완료되면, 이후에 어플리케이션 재실행시 아바타 아이템 선택한 값을 아바타에 반영하여 로드할수 있습니다.
시작하기
Step 1. 프로젝트 구성
해당 프로젝트는 unipassport sdk 로 구성된 NetCore 폴더와 유니티 프로젝트 unimaxstavatar 폴더로 구성되어 있습니다.
Step 2. 프로젝트 열기
unimaxstavatar 프로젝트를 열고 Asset/scenes/SampleScene 을 클릭합니다.
Step 3. 로그인
SampleScene을 이용하여 로그인 및 아바타 화면을 호출할수 있습니다. 실제로 작업하려는 프로젝트에 SampleScene의 구성을 참고하여 진행하시면 됩니다.
로그인 진행 할수 있도록 아래 이미지를 참고하여 ClientID, RedirectURI 값을 등록해 주셔야합니다. 자세한 방법은 unipassport sdk 페이지를 참고하시면 됩니다.
⚠️ 해당 화면은 1920 * 1080 에 최적화 되어 있습니다.
Step 4. 플랫폼별 아바타아이템 리소스 설정
빌드 타겟 플랫폼에 따라 로드되어야 하는 리소스가 달라집니다. 아래 이미지를 참고하여 해당 타겟 플랫폼에 맞는 리소스가 다운로드 되도록 설정해야 합니다. 현재 맥스트에서 제공되는 아바타아이템은 Window, Android, iOS 를 제공합니다.
Step 5. 아바타 화면
⚠️ 0.3.0 버전 부터 AvatarScene에서 Manager게임오브젝트에 AvatarCustomizerManager.cs 및 AvatarAddressableManager.cs를 포함한 AvatarCustomizerManager 게임오브젝트의 사용을 더이상 권장하지 않습니다. AvatarSceneUIBehaviour 를 이용하여 리소스로드를 권장합니다.
- AvatarSceneUIBehaviour
해당 스크립트는 AvatarScene에서 리소스를 로드하고 UI처리를 하는 기능이 포함되어 있습니다.
기본적으로는 Start() 호출시 로그인한 유저의 아바타 착장정보를 조회하고, 착장정보 유무에 따라 이전상태의 아바타착장정보로 로드되거나 앱에서 제공되는 기본리소스를 입고 로드되도록 구성되어 있습니다.
아바타리소스 로드 관련 코드는 avatarResourceRepo 의 가이드를 참고하면 됩니다.
- AvatarCustomizerManager (Legacy)
- 해당 기능을 이용해야 한다면 씬 로드전 아래 소스코드를 호출한후 로드가 완료된 경우 씬을 호출하도록 구성하여야 합니다.
var appId = TokenRepo.Instance.GetToken().accessTokenDictionary.GetTypedValue<string>(JwtTokenConstants.app);
FetchAvatarResource(() => {
Debug.Log("[AvatarResourceManager] res load complete!");
SceneManager.LoadScene("AvatarScene");
});
아바타 리소스 로드 설정 변수에 따라, 리소스를 내려받아 아바타에 적용되는 방식이 다르게 동작합니다. isResourceAllLoad 값이 false 이면 리스트에서 아이템 선택시 리소스를 내려받고, true일 경우 아바타 리소스 선택화면 진입후 해당리소스를 전부다 로드후 화면이 동작하게 됩니다. 기본값은 false 이고 0.1.3 이전버전의 기능으로 로드해야 할 경우 해당값을 true로 설정하면 됩니다.
로그인 완료후 Avatar 버튼을 클릭했을때 지정한 AppId에 해당하는 아바타 아이템 정보를 받고, 아바타 화면으로 이동후 해당 아이템을 로드하게 됩니다.
이전에 저장한 값으로 아바타를 로드 하고 싶다면, Recipe 버튼을 클릭하여 착장정보 조회후 Avatar 버튼을 클릭하여 아바타 화면으로 이동하면 됩니다.
화면이 로드되면 제공되는 아이템을 변경할수 있고, 착용된 상태에서 기본 제공되는 애니매이션을 확인해 볼수 있습니다.
⚠️ 해당 화면은 360 * 800 에 최적화 되어 있습니다.
AvatarResourceRepo.class
해당 객체를 최초로 이용하기전 Init() 함수를 호출하여 해더 및 토큰을 셋팅합니다. 아래는 예시코드 입니다.
AvatarResourceRepo avatarResourceRepo;
avatarResourceRepo = AvatarResourceRepo.Instance;
avatarResourceRepo.Init();api 호출 완료 및 리소스 로드 완료시 Event 객체를 통하여 상태를 전달합니다. 아래 예제코드를 참고하여 해당 화면에 구현하여 이벤트를 전달 받을수 있습니다.
private void OnEnable() {
avatarResourceRepo.loadSlotListEvent.AddObserver(this, LoadSlotList);
}
private void OnDisable() {
avatarResourceRepo.loadSlotListEvent.RemoveAllObserver(this);
}
private void LoadSlotList(List<AvatarResource> list) {
// implementation
}
public SaveRecipeExtensions GetSaveRecipeExtensions(DynamicCharacterAvatar avatar)
현재 아바타의 착장정보를 반환합니다. 매개변수로 전달되는 아바타의 착장정보가 객체로 반환됩니다. 반환되는 객체에는 string 형태의 json 값과, 착용된 리소스의 id리스트가 포함되어 있습니다.
매개변수 | 타입 | 설명 |
---|---|---|
avatar | DynamicCharacterAvatar | 착장정보를 추출할 아바타 |
public async UniTask<string> PostSaveRecipeExtensions(SaveRecipeExtensions saveRecipeExtension)
아바타 착장 정보를 서버에 저장합니다.
매개변수 | 타입 | 설명 |
---|---|---|
saveRecipeExtensions | SaveRecipeExtensions | 아바타 착용정보 객체 |
public async UniTask LoadSaveRecipeExtensions(Platform platform)
서버에 저장된 유저의 착장정보를 조회합니다. 조회가 완료되면 loadUserAvatarRecipeEvent 객체로 이벤트가 전달됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
platform | Platform | 해당 플랫폼 |
public async UniTask LoadAvatarResource(UserAvatar userAvatar, bool isHighPriority = false)
전달받은 UserAvatar 객체에 포함된 리소스를 로드합니다. 리소스가 N개일때(헤어, 상의, 하의 기타등등) 각각 로드가 완료된 시점에 loadUserAvatarResourceAddressableEvent 가 N번 호출되고 UserAvatar에 포함된 모든 리소스가 로드가 완료됬을때 loadUserAvatarResourceDoneEvent 가 호출됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
userAvatar | UserAvatar | 유저의 착장정보 |
isHighPriority | bool | 리소스 로드 우선순위 변수, 현재는 미사용 |
public async UniTask LoadResourceThumbnail(AvatarResource avatarResource, Action<ThumbnailDownLoadUri> action = null)
리소스 업로드시 등록한 썸내일 이미지를 로드합니다. 로드가 완료되면 action 객체로 반환되고, 매개변수로 받은 AvatarResource 내부에 ThumbnailDownLoadUri 객체에 값이 셋팅됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
avatarResource | AvatarResource | 썸내일 로드할 리소스 객체 |
action | Action<ThumbnailDownLoadUri> | 썸내일 로드 완료후 반환받을 Action |
public async UniTask LoadAvatarResource(AvatarResource avatarResource, bool isHighPriority = false)
아바타 리소스 랜더링에 필요한 실제 데이터를 내려받습니다. 리소스가 내려받는 중간에 resourceDownloadStatusEvent 객체로 DownloadStatus 가 반환됩니다. 해당리소스 로드가 완료되고 시스템에서 적용이 끝난후 loadAvatarResourceAddressableEvent 가 호출됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
avatarResource | AvatarResource | 로드할 리소스 정보 객체 |
isHighPriority | bool | 리소스 로드 우선순위 변수, 현재는 미사용 |
public async UniTask LoadAllSlotList(string mainCategory, string platformString, List<string> appIds)
요청한 앱에서 사용할수 있는 전체 아바타리소스 리스트를 조회합니다. 리스트 조회가 완료된후 loadSlotListEvent가 호출됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
mainCategory | string | AvatarConstant.MAIN_CATEGORY 상수값 고정입니다. |
platformString | string | ResourceSettingSO 에 설정된 플랫폼값의 string 값 입니다. |
appIds | List<string> | maxverse 에서 제공되는 appid를 입력합니다. 일반적으로는 해당 앱에서 제공되는 토큰값에서 appid값을 입력하여 사용합니다. 다른앱의 리소스 리스트를 조회하고 싶다면 다른앱의 appid를 추가로 입력하여 사용할수 있습니다. |
public async UniTask LoadSlotList(string mainCategory, string subCategory, string platformString, string appId)
요청한 앱에서 사용할수 있는 카테고리별 아바타리소스 리스트를 조회합니다. 리스트 조회가 완료된후 loadSlotListEvent가 호출됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
mainCategory | string | AvatarConstant.MAIN_CATEGORY 상수값 고정입니다. |
subCategory | string | Category Enum 항목의 string 값입니다. |
platformString | string | ResourceSettingSO 에 설정된 플랫폼값의 string 값 입니다. |
appIds | List<string> | maxverse 에서 제공되는 appid를 입력합니다. 일반적으로는 해당 앱에서 제공되는 토큰값에서 appid값을 입력하여 사용합니다. 다른앱의 리소스 리스트를 조회하고 싶다면 다른앱의 appid를 추가로 입력하여 사용할수 있습니다. |
AvatarResourceManager.class (Legacy)
- AvatarResourceRepo를 사용할 경우 기본적으로 해당클래의 기능을 이용할 필요는 없습니다.
public void SetVisibleResAppIds(List<string> appIds)
아바타 리소스 리스트에 보여질 리소스를 포함하고 있는 Appid를 등록합니다. 기본값은 해당 AppId와 맥스트에서 제공하는 공용리소스를 포함하고 있는 AppId 입니다.
매개변수 | 타입 | 설명 |
---|---|---|
appIds | List<string> | Maxverse 콘솔에 등록된 AppId |
public void AvatarSaveExtensionsDataListener(SaveRecipeExtensions saveRecipeExtensions)
AvatarScene에서 저장이벤트가 발생시 호출되는 함수입니다. 기본적으로 호출시 바로 서버에 저장되도록 재공됩니다.
매개변수 | 타입 | 설명 |
---|---|---|
saveRecipeExtensions | SaveRecipeExtensions | 아바타 착용정보 및 해당리소스의 실제 주소가 들어있는 저장데이터 |
public void PostSaveRecipeExtensions(SaveRecipeExtensions saveRecipeExtensions, Action<string> action = null)
아바타 착장 정보를 서버에 저장합니다.
매개변수 | 타입 | 설명 |
---|---|---|
saveRecipeExtensions | SaveRecipeExtensions | 아바타 착용정보 객체 |
action | Action<string> | 저장완료후 호출되는 Action |
public async void FetchSaveRecipeExtensions(Action<UserAvatar> action)
아바타 착장 정보를 서버에서 조회합니다.
매개변수 | 타입 | 설명 |
---|---|---|
action | Action<UserAvatar> | 착장정보 조회 완료 이후 호출될 Action |
public async void FetchAvatarResource()
아바타 리소스 조회 함수입니다. 기본적으로 해당앱에 등록된 리소스와 맥스트에서 제공되는 공용리소스가 조회되도록 재공됩니다. 원하는 리소스만 로드되길 원할경우, 해당 함수에서 필요한 리소스만 FetchAppAvatarResources() 호출되도록 수정해야 합니다.
public async UniTask FetchAppAvatarResources(string mainCategory, List<Category> subCategoryList, Platform platform, string appId, Action<Dictionary<Category, List<AvatarResource>>> onComplete)
매개변수 | 타입 | 설명 |
---|---|---|
mainCategory | string | AvatarConstant.MAIN_CATEGORY 고정 |
subCategoryList | List<Category> | 조회할 카테고리 리스트, 기본적으로는 전체조회 |
platform | Platform | 현재 사용중인 플랫폼 값으로 셋팅 |
appId | string | 조회할 리소스가 Maxverse에 등록된 AppId |
onComplete | Action<Dictionary<Category, List<AvatarResource>> | 리소스 로드 완료후 실행될 Action |
public async void FetchSaveAvatarResources(UserAvatar saveRecipeExtensions, string token,Action<Dictionary<Category, List<AvatarResource>>> onComplete)
매개변수 | 타입 | 설명 |
---|---|---|
saveRecipeExtensions | UserAvatar | 아바타 착용정보 및 해당리소스의 실제 주소가 들어있는 저장데이터 |
token | string | passport 발급 유저토큰 |
onComplete | Action<Dictionary<Category, List<AvatarResource>>> | 저장데이터 로드 완료후 실행될 Action |
API
공통
//Header
{
"Authorization": "Bearer token.passport",
...
}
아바타 리소스 조회
GET /asset-integration/assets/avatars
Request
Param
Name | Description |
---|---|
mainCategory | avatar |
subCategory | category(Chest, Hair, Legs, Feet) |
os | platform(Android, iOS, StandaloneWindows64) |
appId | maxverse AppId |
Reseponse
[
{
"id": ,
"mainCategory": "Avatar",
"subCategory": "",
"name": "",
"imageUri": "",
"hidden": ,
"resources": [
{
"os": "",
"catalogUri": "",
"hashUri": "",
"bundleUris": [
""
]
}
],
"createdAt": ""
}
}
아바타 착장정보 조회
GET /asset-integration/users/avatar/assets
Request
Param | Name | Description | | -------------- | -------- | | os | platform(Android, iOS, StandaloneWindows64) |
Reseponse
{
"recipeStr": "{}",
"slots": [
{
"slot": "",
"itemId": ,
"recipe": "",
"assetResourceInfo": [
{
"os": "",
"catalogUri": "",
"hashUri": "",
"bundleUris": [
""
]
}
]
},
]
}
아바타 착장정보 저장
POST /asset-integration/users/avatar/assets
//Header
{
"Content-Type" : "application/json",
...
}
Request
{
"recipeStr": "{}",
"itemIds": [1, 2, 3, 4]
}
Reseponse
200