Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDK-776] Feature/default asset selection #213

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Runtime/AvatarCreator/Scripts/Managers/AvatarManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ public async Task<GameObject> GetAvatar(string id, BodyType bodyType, bool isPre
return await inCreatorAvatarLoader.Load(avatarId, bodyType, gender, data);
}

public async Task<AvatarProperties> GetAvatarProperties(string id)
{
avatarId = id;
var avatarProperties = new AvatarProperties();
try
{
avatarProperties = await avatarAPIRequests.GetAvatarProperties(avatarId);
}
catch (Exception e)
{
OnError?.Invoke(e.Message);
}

return avatarProperties;
}

/// <summary>
/// Update an asset of the avatar.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ReadyPlayerMe.Core;
Expand Down Expand Up @@ -71,5 +72,21 @@ private async void OnButtonCreated(SelectionButton button, PartnerAsset asset)
var texture = await webRequestDispatcher.DownloadTexture(url);
button.SetIcon(texture);
}

public void SetAssetSelected(AvatarProperties avatarProperties)
{
if (!avatarProperties.Assets.ContainsKey(assetType))
{
Debug.Log($"Avatar properties does not contain asset type {assetType}");
return;
}
var assetId = avatarProperties.Assets[assetType] as string;
if (string.IsNullOrEmpty(assetId))
{
Debug.Log($"Asset id is null or empty {assetId} on type {assetType}");
return;
}
SetButtonSelected(assetId);
}
}
}
12 changes: 12 additions & 0 deletions Runtime/AvatarCreator/Scripts/UI/Elements/SelectionElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,17 @@ private void SetButtonSelected(Transform button)
}
selectedIcon.SetActive(true);
}

protected void SetButtonSelected(string assetId)
{
var button = GetButton(assetId);
if (button == null)
{
Debug.Log($"No button found with id {assetId}");
return;
}
Debug.Log($"Set {button.name} selected");
SetButtonSelected(button.transform);
}
}
}
18 changes: 18 additions & 0 deletions Runtime/AvatarCreator/Scripts/WebRequests/AvatarAPIRequests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,24 @@ public async Task<byte[]> GetAvatar(string avatarId, bool isPreview = false, str
return response.Data;
}

public async Task<AvatarProperties> GetAvatarProperties(string avatarId)
{
var url = $"{RPM_AVATAR_V2_BASE_URL}/{avatarId}.json?";

var response = await authorizedRequest.SendRequest<Response>(
new RequestData
{
Url = url,
Method = HttpMethod.GET
},
ctx: ctx);

response.ThrowIfError();
var json = JObject.Parse(response.Text);
var data = json[DATA]!.ToString();
return JsonConvert.DeserializeObject<AvatarProperties>(data);
}

public async Task<byte[]> UpdateAvatar(string avatarId, AvatarProperties avatarProperties, string parameters = null)
{
var url = $"{RPM_AVATAR_V2_BASE_URL}/{avatarId}?responseType=glb&{parameters}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657826, g: 0.49641263, b: 0.57481676, a: 1}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
Expand Down Expand Up @@ -1524,6 +1524,11 @@ PrefabInstance:
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8416300172646733353, guid: bed67741521b22649bc65f4a8cc74cf1,
type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: bed67741521b22649bc65f4a8cc74cf1, type: 3}
--- !u!224 &729649017 stripped
Expand Down Expand Up @@ -2220,7 +2225,7 @@ PrefabInstance:
- target: {fileID: 1536621870556083727, guid: 2bb6b08b8e48b2d4ca36bf901b0b1a2e,
type: 3}
propertyPath: m_AnchoredPosition.y
value: 0.000015258789
value: 0.000022888184
objectReference: {fileID: 0}
- target: {fileID: 1536621870556083728, guid: 2bb6b08b8e48b2d4ca36bf901b0b1a2e,
type: 3}
Expand Down Expand Up @@ -2773,6 +2778,11 @@ PrefabInstance:
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8416300172646733353, guid: bed67741521b22649bc65f4a8cc74cf1,
type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: bed67741521b22649bc65f4a8cc74cf1, type: 3}
--- !u!224 &1404654432 stripped
Expand Down Expand Up @@ -2824,6 +2834,61 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: f5c8c0dceba52dc439e98eb49fdee50f, type: 3}
m_Name:
m_EditorClassIdentifier:
onAvatarCreated:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 713799765}
m_TargetAssemblyTypeName: ReadyPlayerMe.AvatarCreator.AssetSelectionElement,
ReadyPlayerMe.AvatarCreator
m_MethodName: SetAssetSelected
m_Mode: 0
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
- m_Target: {fileID: 1624350962}
m_TargetAssemblyTypeName: ReadyPlayerMe.AvatarCreator.AssetSelectionElement,
ReadyPlayerMe.AvatarCreator
m_MethodName: SetAssetSelected
m_Mode: 0
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
- m_Target: {fileID: 729649025}
m_TargetAssemblyTypeName: ReadyPlayerMe.AvatarCreator.AssetSelectionElement,
ReadyPlayerMe.AvatarCreator
m_MethodName: SetAssetSelected
m_Mode: 0
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
- m_Target: {fileID: 1528640351}
m_TargetAssemblyTypeName: ReadyPlayerMe.AvatarCreator.AssetSelectionElement,
ReadyPlayerMe.AvatarCreator
m_MethodName: SetAssetSelected
m_Mode: 0
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
assetSelectionElements:
- {fileID: 1624350962}
- {fileID: 1528640351}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
using ReadyPlayerMe.AvatarCreator;
using ReadyPlayerMe.Core;
using UnityEngine;
using UnityEngine.Events;

#pragma warning disable CS4014
#pragma warning disable CS1998

namespace ReadyPlayerMe.Samples.AvatarCreatorExperimental
{

/// <summary>
/// A class responsible for creating and customizing avatars using asset and color selections.
/// </summary>
public class SimpleAvatarCreator : MonoBehaviour
{
public UnityEvent<AvatarProperties> onAvatarCreated;
[SerializeField] private List<AssetSelectionElement> assetSelectionElements;
[SerializeField] private List<ColorSelectionElement> colorSelectionElements;
[SerializeField] private RuntimeAnimatorController animationController;
Expand All @@ -22,20 +28,24 @@ public class SimpleAvatarCreator : MonoBehaviour
private AvatarManager avatarManager;
private GameObject avatar;

/// <summary>
/// Start is used to initialize the avatar creator and loads initial avatar assets.
/// </summary>
private async void Start()
{
await AuthManager.LoginAsAnonymous();
avatarManager = new AvatarManager();

loading.SetActive(true);
GetAssets();
var avatarProperties = await GetAvatar();
LoadAssets();
var avatarProperties = await CreateTemplateAvatar();
GetColors(avatarProperties);
loading.SetActive(false);
}

private void OnEnable()
{
// Subscribes to asset selection events when this component is enabled.
foreach (var element in assetSelectionElements)
{
element.onAssetSelected.AddListener(OnAssetSelection);
Expand All @@ -49,6 +59,7 @@ private void OnEnable()

private void OnDisable()
{
// Unsubscribes from asset selection events when this component is disabled.
foreach (var element in assetSelectionElements)
{
element.onAssetSelected.RemoveListener(OnAssetSelection);
Expand All @@ -60,24 +71,40 @@ private void OnDisable()
}
}

/// <summary>
/// Handles the selection of an asset and updates the avatar accordingly.
/// </summary>
/// <param name="assetData">The selected asset data.</param>
private async void OnAssetSelection(IAssetData assetData)
{
loading.SetActive(true);
var newAvatar = await avatarManager.UpdateAsset(assetData.AssetType, bodyType, assetData.Id);
Destroy(avatar);

// Destroy the old avatar and replace it with the new one.
if (avatar != null)
{
Destroy(avatar);
}
avatar = newAvatar;
SetElements();
SetupAvatar();
loading.SetActive(false);
}

private async void GetAssets()
/// <summary>
/// Loads and initializes asset selection elements for avatar customization.
/// </summary>
private async void LoadAssets()
{
foreach (var element in assetSelectionElements)
{
element.LoadAndCreateButtons(gender);
}
}

/// <summary>
/// Loads and initializes color selection elements for choosing avatar colors.
/// </summary>
/// <param name="avatarProperties">The properties of the avatar.</param>
private void GetColors(AvatarProperties avatarProperties)
{
foreach (var element in colorSelectionElements)
Expand All @@ -86,19 +113,27 @@ private void GetColors(AvatarProperties avatarProperties)
}
}

private async Task<AvatarProperties> GetAvatar()
/// <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()
{
var avatarTemplateFetcher = new AvatarTemplateFetcher();
var templates = await avatarTemplateFetcher.GetTemplates();
var avatarTemplate = templates[1];

var templateAvatarProps = await avatarManager.CreateAvatarFromTemplate(avatarTemplate.Id, bodyType);
avatar = templateAvatarProps.Item1;
SetElements();
SetupAvatar();
onAvatarCreated?.Invoke(templateAvatarProps.Item2);
return templateAvatarProps.Item2;
}

private void SetElements()
/// <summary>
/// Sets additional elements and components on the created avatar, such as mouse rotation and animation controller.
/// </summary>
private void SetupAvatar()
{
avatar.AddComponent<MouseRotationHandler>();
avatar.AddComponent<AvatarRotator>();
Expand Down
Loading