-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathAvatarHandler.cs
143 lines (120 loc) · 5.17 KB
/
AvatarHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ReadyPlayerMe.AvatarCreator;
using ReadyPlayerMe.Core;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
using TaskExtensions = ReadyPlayerMe.AvatarCreator.TaskExtensions;
namespace ReadyPlayerMe.Samples.AvatarCreatorElements
{
public class AvatarHandler : MonoBehaviour
{
[SerializeField] private RuntimeAnimatorController animationController;
public UnityEvent<AvatarProperties> OnAvatarLoaded;
public UnityEvent OnAvatarLoading;
private AvatarManager avatarManager;
private readonly CancellationTokenSource cancellationTokenSource = new();
private GameObject avatar;
public AvatarProperties ActiveAvatarProperties { get; private set; }
private void Awake()
{
avatarManager = new AvatarManager(token: cancellationTokenSource.Token);
}
public async Task LoadAvatar(string avatarId)
{
await LoadAvatarWithId(avatarId);
}
public async Task SelectAsset(IAssetData assetData)
{
OnAvatarLoading?.Invoke();
GameObject newAvatar;
if(assetData.AssetType == AssetType.Headwear && ActiveAvatarProperties.Assets.ContainsKey(AssetType.HairStyle))
{
var assets = new Dictionary<AssetType, object>();
assets.Add(AssetType.HairStyle, ActiveAvatarProperties.Assets[AssetType.HairStyle]);
assets.Add(AssetType.Headwear, assetData.Id);
newAvatar = await avatarManager.UpdateAssets(assets);
}
else
{
newAvatar = await avatarManager.UpdateAsset(assetData.AssetType, assetData.Id);
}
SetupLoadedAvatar(newAvatar, ActiveAvatarProperties);
}
public async Task SaveActiveAvatar()
{
await avatarManager.Save();
AuthManager.StoreLastModifiedAvatar(avatarManager.AvatarId);
}
public async Task CreateNewAvatarFromTemplate()
{
await CreateTemplateAvatar();
}
public async void LoadPreviousOrCreateNewAvatar()
{
var session = AuthManager.UserSession;
await TaskExtensions.HandleCancellation(string.IsNullOrEmpty(session.LastModifiedAvatarId) ? CreateTemplateAvatar() : LoadAvatarWithId(session.LastModifiedAvatarId));
}
private async Task<AvatarProperties> LoadAvatarWithId(string avatarId)
{
OnAvatarLoading?.Invoke();
var newAvatar = await avatarManager.GetAvatar(avatarId);
var newAvatarProperties = await avatarManager.GetAvatarProperties(avatarId);
SetupLoadedAvatar(newAvatar, newAvatarProperties);
AuthManager.StoreLastModifiedAvatar(avatarId);
return newAvatarProperties;
}
/// <summary>
/// Creates an avatar from a template and sets its initial properties.
/// </summary>
/// <returns>The properties of the created avatar.</returns>
private async Task<AvatarProperties> CreateTemplateAvatar()
{
OnAvatarLoading?.Invoke();
var avatarTemplateFetcher = new AvatarTemplateFetcher(cancellationTokenSource.Token);
var templates = await avatarTemplateFetcher.GetTemplates();
var avatarTemplate = templates[1];
return await LoadAvatarFromTemplate(avatarTemplate.Id);
}
public async Task<AvatarProperties> LoadAvatarFromTemplate(string templateId)
{
OnAvatarLoading?.Invoke();
var templateAvatarResponse = await avatarManager.CreateAvatarFromTemplateAsync(templateId);
SetupLoadedAvatar(templateAvatarResponse.AvatarObject, templateAvatarResponse.Properties);
return templateAvatarResponse.Properties;
}
private void SetupLoadedAvatar(GameObject newAvatar, AvatarProperties newAvatarProperties)
{
if (avatar != null)
{
Destroy(avatar);
}
avatar = newAvatar;
ActiveAvatarProperties = newAvatarProperties;
SetupAvatar(newAvatarProperties);
OnAvatarLoaded?.Invoke(newAvatarProperties);
}
/// <summary>
/// Sets additional elements and components on the created avatar, such as mouse rotation and animation controller.
/// </summary>
private void SetupAvatar(AvatarProperties newAvatarProperties)
{
avatar.AddComponent<MouseRotationHandler>();
avatar.AddComponent<AvatarRotator>();
var animator = avatar.GetComponent<Animator>();
AvatarAnimationHelper.SetupAnimator(new AvatarMetadata
{ BodyType = newAvatarProperties.BodyType, OutfitGender = newAvatarProperties.Gender }, animator);
animator.runtimeAnimatorController = animationController;
}
private void OnDestroy()
{
cancellationTokenSource.Cancel();
cancellationTokenSource.Dispose();
}
}
}