add ready player me POC

This commit is contained in:
2024-11-22 07:08:52 +02:00
parent 855639487b
commit 7c4e48f388
1033 changed files with 224048 additions and 28 deletions
@@ -0,0 +1,20 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3663d6a9358ae4149aad3496e56d4601, type: 3}
m_Name: Avatar Configuration LOD0
m_EditorClassIdentifier:
MeshLod: 0
Pose: 0
TextureAtlas: 1
TextureSizeLimit: 1024
UseHands: 0
MorphTargets: []
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 99552ccf737554f2fab58e864f9416e4
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 259814
packageName: Ready Player Me Avatar and Character Creator
packageVersion: 7.3.1
assetPath: Assets/Ready Player Me/Core/Samples/AvatarLoadingSamples/AvatarLod/Avatar
Configuration LOD0.asset
uploadId: 704624
@@ -0,0 +1,20 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3663d6a9358ae4149aad3496e56d4601, type: 3}
m_Name: Avatar Configuration LOD1
m_EditorClassIdentifier:
MeshLod: 1
Pose: 0
TextureAtlas: 2
TextureSizeLimit: 512
UseHands: 0
MorphTargets: []
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 1d2a8b01037e24f54b99b6aa9a51f0db
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 259814
packageName: Ready Player Me Avatar and Character Creator
packageVersion: 7.3.1
assetPath: Assets/Ready Player Me/Core/Samples/AvatarLoadingSamples/AvatarLod/Avatar
Configuration LOD1.asset
uploadId: 704624
@@ -0,0 +1,21 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3663d6a9358ae4149aad3496e56d4601, type: 3}
m_Name: Avatar Configuration LOD2
m_EditorClassIdentifier:
MeshLod: 2
Pose: 0
TextureAtlas: 3
TextureSizeLimit: 256
UseHands: 0
MorphTargets:
- none
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 5fba8af1affda4895895126e539c6165
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 259814
packageName: Ready Player Me Avatar and Character Creator
packageVersion: 7.3.1
assetPath: Assets/Ready Player Me/Core/Samples/AvatarLoadingSamples/AvatarLod/Avatar
Configuration LOD2.asset
uploadId: 704624
@@ -0,0 +1,122 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using ReadyPlayerMe.Core;
using UnityEngine;
namespace ReadyPlayerMe.Samples.AvatarLoading
{
/// <summary>
/// This class is a simple <see cref="Monobehaviour"/> to serve as an example on how to load a Ready Player Me avatar with multiple LOD's (level of detail) and spawn as a <see cref="GameObject"/> into the scene at runtime.
/// </summary>
public class AvatarLodExample : MonoBehaviour
{
private const string LOD_MESH_SUFFIX = "_LOD";
private const float CULL_TRANSITION = 0.05f;
[SerializeField]
private AvatarLodExampleUI lodExampleUI;
[SerializeField] [Tooltip("Set this to the URL or shortcode of the Ready Player Me Avatar you want to load.")]
private string avatarUrl;
[SerializeField]
private AvatarConfig[] lodConfigs;
private LODGroup lodGroup;
private bool loading;
private GameObject mainAvatar;
private SkinnedMeshRenderer mainMeshRenderer;
private readonly List<SkinnedMeshRenderer> meshRenderersList = new List<SkinnedMeshRenderer>();
private void Start()
{
ApplicationData.Log();
if (lodExampleUI) lodExampleUI.Init();
LoadLodAvatar();
}
/// Loads all the avatar LOD's as per the lodConfigs length and configuration
private async void LoadLodAvatar()
{
var avatarMetadata = new AvatarMetadata();
foreach (var config in lodConfigs)
{
var lodLevel = (int) config.Lod;
var loader = new AvatarObjectLoader();
loader.AvatarConfig = config;
loader.LoadAvatar(avatarUrl);
// use the OnCompleted event to setup the mesh renderers
loader.OnCompleted += (sender, args) =>
{
if (mainAvatar == null)
{
avatarMetadata = args.Metadata;
mainAvatar = Instantiate(args.Avatar);
mainAvatar.name = args.Avatar.name + LOD_MESH_SUFFIX;
mainMeshRenderer = mainAvatar.GetComponentInChildren<SkinnedMeshRenderer>();
var meshTransform = mainMeshRenderer.transform;
meshTransform.name = meshTransform.name += $"{LOD_MESH_SUFFIX}{lodLevel}";
mainMeshRenderer.enabled = false;
meshRenderersList.Add(mainMeshRenderer);
}
else
{
var lodSkinnedMeshRenderer = args.Avatar.GetComponentInChildren<SkinnedMeshRenderer>();
lodSkinnedMeshRenderer.rootBone = mainMeshRenderer.rootBone;
lodSkinnedMeshRenderer.bones = mainMeshRenderer.bones;
lodSkinnedMeshRenderer.transform.name += $"{LOD_MESH_SUFFIX}{lodLevel}";
lodSkinnedMeshRenderer.transform.SetParent(mainAvatar.transform);
lodSkinnedMeshRenderer.transform.SetSiblingIndex(lodLevel);
lodSkinnedMeshRenderer.enabled = false;
meshRenderersList.Add(lodSkinnedMeshRenderer);
}
Destroy(args.Avatar);
loading = false;
};
loading = true;
while (loading)
{
await Task.Yield();
}
}
AddLodGroup();
AvatarAnimationHelper.SetupAnimator(avatarMetadata, mainAvatar);
if (lodExampleUI) lodExampleUI.Show();
}
/// Adds and configures the LODGroup component
private void AddLodGroup()
{
lodGroup = mainAvatar.AddComponent<LODGroup>();
var lods = new LOD[lodConfigs.Length];
for (var i = 0; i < lodConfigs.Length; i++)
{
meshRenderersList[i].enabled = true;
lods[i] = new LOD(CalculateTransitionHeight(i), new Renderer[] { meshRenderersList[i] });
}
lodGroup.SetLODs(lods);
lodGroup.RecalculateBounds();
lodExampleUI.LodGroup = lodGroup;
}
private float CalculateTransitionHeight(int lodConfig)
{
var lodTransition = (lodConfig + 1f) / lodConfigs.Length;
return (1 - lodTransition + CULL_TRANSITION);
}
private void OnDestroy()
{
if (mainAvatar != null)
{
Destroy(mainAvatar);
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 707cd498ac29848c587fbf68dc32aa85
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 259814
packageName: Ready Player Me Avatar and Character Creator
packageVersion: 7.3.1
assetPath: Assets/Ready Player Me/Core/Samples/AvatarLoadingSamples/AvatarLod/AvatarLodExample.cs
uploadId: 704624
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 70100edf1a7db4b519c15b52da0e13f2
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 259814
packageName: Ready Player Me Avatar and Character Creator
packageVersion: 7.3.1
assetPath: Assets/Ready Player Me/Core/Samples/AvatarLoadingSamples/AvatarLod/AvatarLodExample.unity
uploadId: 704624
@@ -0,0 +1,70 @@
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
namespace ReadyPlayerMe.Samples.AvatarLoading
{
public class AvatarLodExampleUI : MonoBehaviour
{
private Slider uiSlider;
private Vector3 cameraStartPos;
private Text lodInfoText;
[SerializeField] private Camera mainCamera;
public LODGroup LodGroup { set; get; }
public void Init()
{
QualitySettings.lodBias = 1f;
lodInfoText = GetComponentInChildren<Text>();
uiSlider = GetComponentInChildren<Slider>();
cameraStartPos = mainCamera ? mainCamera.transform.position : Vector3.zero;
uiSlider.onValueChanged.AddListener(UpdatePosition);
}
public void Show()
{
GetComponent<Canvas>().enabled = true;
}
private void UpdatePosition(float value)
{
mainCamera.transform.position = new Vector3(cameraStartPos.x, cameraStartPos.y, cameraStartPos.z + value);
Invoke(nameof(UpdateCurrentLod), 0.1f);
}
private void UpdateCurrentLod()
{
if (LodGroup != null)
{
Transform lodTransform = LodGroup.transform;
foreach (Transform child in lodTransform)
{
var thisRenderer = child.GetComponent<SkinnedMeshRenderer>();
if (thisRenderer != null && thisRenderer.isVisible)
{
var currentLod = child.name.Split('_').Last();
var vertexCount = thisRenderer.sharedMesh.vertexCount;
var textureSize = thisRenderer.sharedMaterial.mainTexture.height;
var morphTargetCount = thisRenderer.sharedMesh.blendShapeCount;
UpdateLodInfoPanel(currentLod, vertexCount, textureSize, morphTargetCount);
}
}
}
}
private void UpdateLodInfoPanel(string currentLod, int vertexCount, int textureSize, int morphTargetCount)
{
lodInfoText.text = "Current LOD\n" + currentLod + "\n" +
"Vertex Count\n" + vertexCount + "\n" +
"Texture Size\n" + textureSize + "\n" +
"Blend Shapes\n" + morphTargetCount;
}
private void OnDisable()
{
uiSlider.onValueChanged.RemoveAllListeners();
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 260ad8794b02546e5b200807e952ba36
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 259814
packageName: Ready Player Me Avatar and Character Creator
packageVersion: 7.3.1
assetPath: Assets/Ready Player Me/Core/Samples/AvatarLoadingSamples/AvatarLod/AvatarLodExampleUI.cs
uploadId: 704624