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-600] Feature/avatar template element #164

Merged
merged 14 commits into from
Nov 29, 2023
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
61 changes: 61 additions & 0 deletions Runtime/AvatarCreator/AvatarTemplateFetcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ReadyPlayerMe.AvatarCreator
{
/// <summary>
/// This class can be used to fetch avatar template data including icon renders from the avatarAPI.
/// </summary>
public class AvatarTemplateFetcher
{
private readonly CancellationToken ctx;
private readonly AvatarAPIRequests avatarAPIRequests;

public AvatarTemplateFetcher(CancellationToken ctx = default)
{
this.ctx = ctx;
avatarAPIRequests = new AvatarAPIRequests(ctx);
}

/// <summary>
/// Fetches all avatar templates without the icon renders via the avatarAPI.
/// </summary>
/// <returns></returns>
public async Task<List<AvatarTemplateData>> GetTemplates()
{
return await avatarAPIRequests.GetAvatarTemplates();
}

/// <summary>
/// Fetches all avatar template data with the icon renders via the avatarAPI.
/// This will wait for all the icons to be downloaded.
/// </summary>
/// <returns></returns>
public async Task<List<AvatarTemplateData>> GetTemplatesWithRenders()
{
var templates = await avatarAPIRequests.GetAvatarTemplates();
return await FetchTemplateRenders(templates);
}

/// <summary>
/// Fetches the renders for all the templates provided.
/// </summary>
public async Task<List<AvatarTemplateData>> FetchTemplateRenders(List<AvatarTemplateData> templates)
{
var tasks = templates.Select(async templateData =>
{
templateData.Texture = await avatarAPIRequests.GetAvatarTemplateImage(templateData.ImageUrl);
}).ToList();

while (!tasks.All(x => x.IsCompleted) &&
!ctx.IsCancellationRequested)
{
await Task.Yield();
}

return templates;
}
}
}
13 changes: 13 additions & 0 deletions Runtime/AvatarCreator/Data/AssetLibrary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace ReadyPlayerMe.AvatarCreator
{
public struct AssetLibrary
HarrisonHough marked this conversation as resolved.
Show resolved Hide resolved
{
public PartnerAsset[] Assets;
public Pagination Pagination;
}

public struct Pagination
{
public int TotalPages;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace ReadyPlayerMe.AvatarCreator
{
[Serializable]
public class TemplateData
public class AvatarTemplateData
{
public string ImageUrl;
[JsonConverter(typeof(GenderConverter))]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
using Newtonsoft.Json;
using Newtonsoft.Json;
using ReadyPlayerMe.Core;

namespace ReadyPlayerMe.AvatarCreator
{
public struct AssetData
{
public PartnerAsset[] Assets;
public Pagination Pagination;
}

public struct PartnerAsset
{
public string Id;
Expand All @@ -17,15 +11,8 @@ public struct PartnerAsset
[JsonConverter(typeof(GenderConverter))]
public OutfitGender Gender;
[JsonProperty("iconUrl")]
public string Icon;
[JsonProperty("maskUrl")]
public string Mask;
public string ImageUrl;
[JsonProperty("lockedCategories")]
public string[] LockedCategories;
}

public struct Pagination
{
public int TotalPages;
}
}
11 changes: 11 additions & 0 deletions Runtime/AvatarCreator/Data/PartnerAsset.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Runtime/AvatarCreator/PartnerAssetsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public PartnerAssetsManager()
assetsByCategory = new Dictionary<Category, List<PartnerAsset>>();
}

public async Task<Dictionary<Category,List<PartnerAsset>>> GetAssets(BodyType bodyType, OutfitGender gender, CancellationToken token = default)
public async Task<Dictionary<Category, List<PartnerAsset>>> GetAssets(BodyType bodyType, OutfitGender gender, CancellationToken token = default)
{
var startTime = Time.time;

Expand Down Expand Up @@ -96,7 +96,7 @@ private async Task DownloadIcons(List<PartnerAsset> chunk, Action<string, Textur

foreach (var asset in chunk)
{
var url = asset.Category == Category.EyeColor ? asset.Mask + EYE_MASK_SIZE_SIZE : asset.Icon + ASSET_ICON_SIZE;
var url = $"{asset.ImageUrl}{ASSET_ICON_SIZE}";
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
var iconTask = partnerAssetsRequests.GetAssetIcon(url, icon =>
{
Expand Down Expand Up @@ -126,7 +126,7 @@ public PrecompileData GetPrecompileData(Category[] categories, int numberOfAsset
.Select(kvp => kvp.Key)
.ToArray();

var dictionary = categoriesFromMap.ToDictionary(category => category, category =>
var dictionary = categoriesFromMap.ToDictionary(category => category, category =>
GetAssetsByCategory(CategoryHelper.PartnerCategoryMap[category])
.Take(numberOfAssetsPerCategory)
.ToArray());
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

210 changes: 210 additions & 0 deletions Runtime/AvatarCreator/Prefabs/Buttons/ButtonElement.prefab
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &313019198674256499
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 313019198674256498}
- component: {fileID: 313019198674256496}
- component: {fileID: 313019198674256497}
m_Layer: 5
m_Name: RawImage
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &313019198674256498
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019198674256499}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 313019200304032552}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &313019198674256496
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019198674256499}
m_CullTransparentMesh: 1
--- !u!114 &313019198674256497
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019198674256499}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!1 &313019200304032553
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 313019200304032552}
- component: {fileID: 313019200304032557}
- component: {fileID: 313019200304032558}
- component: {fileID: 313019200304032559}
- component: {fileID: 313019200304032556}
m_Layer: 5
m_Name: ButtonElement
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &313019200304032552
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019200304032553}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 313019198674256498}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 180, y: 180}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &313019200304032557
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019200304032553}
m_CullTransparentMesh: 1
--- !u!114 &313019200304032558
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019200304032553}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 4d267838cc649284dac0e347a0072f24, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &313019200304032559
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019200304032553}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 313019200304032558}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!114 &313019200304032556
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 313019200304032553}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f2bb8ce1b8cb99c40b9103b9350c8105, type: 3}
m_Name:
m_EditorClassIdentifier:
button: {fileID: 313019200304032559}
rawImage: {fileID: 313019198674256497}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading