diff --git a/CHANGELOG.md b/CHANGELOG.md index 55b61181..4b32aaca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [7.4.0] - 2025.01.15 + +## Updated +- Avatar caching location is now changed when running in the Unity Editor it will now be stored in the `Application.persistentDataPath` directory as it already did for builds. However when loading avatars from the Avatar Loader Editor window it will still store them in the `Assets/Ready Player Me/Avatars folder`. +- AvatarManager and AvatarHandler classes updated so that in the Avatar Creator Elements sample it will re-equip hair when headwear is removed. [#330](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/330) +- AvatarConfigProcessor updated so that by default if morph targets are not set, it will set it to None to improve file size. [#326](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/326) + ## [7.3.1] - 2024.10.30 ## Updated diff --git a/Editor/Core/Scripts/EditorAvatarLoader.cs b/Editor/Core/Scripts/EditorAvatarLoader.cs index b35826d1..bafc75f9 100644 --- a/Editor/Core/Scripts/EditorAvatarLoader.cs +++ b/Editor/Core/Scripts/EditorAvatarLoader.cs @@ -85,7 +85,7 @@ public async Task Load(string url) private static async Task DownloadAvatarModel(AvatarUri avatarUri) { - var folderPath = Path.Combine(Application.dataPath, "Ready Player Me/Avatars"); + var folderPath = Path.Combine(Application.dataPath, $"Ready Player Me/Avatars/{avatarUri.Guid}"); // Ensure the folder exists if (!Directory.Exists(folderPath)) { diff --git a/Runtime/Core/Scripts/Animation/VoiceHandler.cs b/Runtime/Core/Scripts/Animation/VoiceHandler.cs index 86c60fd7..64713573 100644 --- a/Runtime/Core/Scripts/Animation/VoiceHandler.cs +++ b/Runtime/Core/Scripts/Animation/VoiceHandler.cs @@ -8,7 +8,6 @@ using UnityEngine.Android; #endif - namespace ReadyPlayerMe.Core { /// @@ -111,9 +110,10 @@ public void InitializeAudio() { try { + if (AudioSource == null) { - AudioSource = gameObject.AddComponent(); + AudioSource = GetComponent() ?? gameObject.AddComponent(); } switch (AudioProvider) diff --git a/Runtime/Core/Scripts/Data/ApplicationData.cs b/Runtime/Core/Scripts/Data/ApplicationData.cs index 8574e617..885911a1 100644 --- a/Runtime/Core/Scripts/Data/ApplicationData.cs +++ b/Runtime/Core/Scripts/Data/ApplicationData.cs @@ -6,7 +6,7 @@ namespace ReadyPlayerMe.Core { public static class ApplicationData { - public const string SDK_VERSION = "v7.3.1"; + public const string SDK_VERSION = "v7.4.0"; private const string TAG = "ApplicationData"; private const string DEFAULT_RENDER_PIPELINE = "Built-In Render Pipeline"; private static readonly AppData Data; diff --git a/Runtime/Core/Scripts/Utils/AvatarConfigProcessor.cs b/Runtime/Core/Scripts/Utils/AvatarConfigProcessor.cs index 74956f17..11cc2662 100644 --- a/Runtime/Core/Scripts/Utils/AvatarConfigProcessor.cs +++ b/Runtime/Core/Scripts/Utils/AvatarConfigProcessor.cs @@ -42,7 +42,8 @@ public static string ProcessAvatarConfiguration(AvatarConfig avatarConfig) queryBuilder.AddKeyValue(AvatarAPIParameters.USE_HANDS, GetBoolStringValue(avatarConfig.UseHands)); queryBuilder.AddKeyValue(AvatarAPIParameters.USE_DRACO, GetBoolStringValue(avatarConfig.UseDracoCompression)); queryBuilder.AddKeyValue(AvatarAPIParameters.USE_MESHOPT, GetBoolStringValue(avatarConfig.UseMeshOptCompression)); - queryBuilder.AddKeyValue(AvatarAPIParameters.TEXTURE_FORMAT, "jpeg"); + // TODO: Add later when edge cases are handled. + //queryBuilder.AddKeyValue(AvatarAPIParameters.TEXTURE_FORMAT, "jpeg"); return queryBuilder.Query; } diff --git a/Samples~/AvatarCreatorSamples/AvatarCreatorElements/Scripts/AvatarHandler.cs b/Samples~/AvatarCreatorSamples/AvatarCreatorElements/Scripts/AvatarHandler.cs index ae600979..9bdbef82 100644 --- a/Samples~/AvatarCreatorSamples/AvatarCreatorElements/Scripts/AvatarHandler.cs +++ b/Samples~/AvatarCreatorSamples/AvatarCreatorElements/Scripts/AvatarHandler.cs @@ -1,14 +1,10 @@ -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 @@ -39,7 +35,7 @@ public async Task SelectAsset(IAssetData assetData) { OnAvatarLoading?.Invoke(); GameObject newAvatar; - if(assetData.AssetType == AssetType.Headwear && ActiveAvatarProperties.Assets.ContainsKey(AssetType.HairStyle)) + if (assetData.AssetType == AssetType.Headwear && ActiveAvatarProperties.Assets.ContainsKey(AssetType.HairStyle)) { var assets = new Dictionary(); assets.Add(AssetType.HairStyle, ActiveAvatarProperties.Assets[AssetType.HairStyle]); @@ -50,6 +46,7 @@ public async Task SelectAsset(IAssetData assetData) { newAvatar = await avatarManager.UpdateAsset(assetData.AssetType, assetData.Id); } + ActiveAvatarProperties.Assets[assetData.AssetType] = assetData.Id; SetupLoadedAvatar(newAvatar, ActiveAvatarProperties); } diff --git a/Tests/Editor/AvatarConfigProcessorTests.cs b/Tests/Editor/AvatarConfigProcessorTests.cs index b06a10d8..5bb36701 100644 --- a/Tests/Editor/AvatarConfigProcessorTests.cs +++ b/Tests/Editor/AvatarConfigProcessorTests.cs @@ -11,7 +11,7 @@ public class AvatarConfigProcessorTests private const string MORPHTARGETS_EXPECTED_DEFAULT = "mouthOpen,mouthSmile"; private const string MORPHTARGETS_EXPECTED_NONE = "none"; private const string AVATAR_QUERY_PARAMS_ACTUAL = - "pose=T&lod=0&textureAtlas=none&textureSizeLimit=1024&textureChannels=baseColor,normal,metallicRoughness,emissive,occlusion&useHands=false&useDracoMeshCompression=false&useMeshOptCompression=false"; + "pose=T&lod=0&textureAtlas=none&textureSizeLimit=1024&textureChannels=baseColor,normal,metallicRoughness,emissive,occlusion&morphTargets=none&useHands=false&useDracoMeshCompression=false&useMeshOptCompression=false&textureFormat=jpeg"; private readonly string[] morphTargetsDefault = { "mouthOpen", "mouthSmile" }; private readonly string[] morphTargetsNone = { "none" }; private readonly TextureChannel[] textureChannelsAll = diff --git a/Tests/Editor/AvatarLoaderWindowTests.cs b/Tests/Editor/AvatarLoaderWindowTests.cs index 8908ea49..dbe0eb21 100644 --- a/Tests/Editor/AvatarLoaderWindowTests.cs +++ b/Tests/Editor/AvatarLoaderWindowTests.cs @@ -17,8 +17,7 @@ public class AvatarLoaderWindowTests [TearDown] public void Cleanup() { - TestUtils.DeleteAvatarDirectoryIfExists(TestAvatarData.DefaultAvatarUri.Guid, true); - TestUtils.DeleteCachedAvatar(TestAvatarData.DefaultAvatarUri.Guid); + TestUtils.DeleteEditorAvatarDirectoryIfExists(TestAvatarData.DefaultAvatarUri.Guid, true); if (avatar != null) { Object.DestroyImmediate(avatar); @@ -46,7 +45,7 @@ public IEnumerator Avatar_Loaded_Stored_And_No_Overrides() { yield return null; avatar = GameObject.Find(TestAvatarData.DefaultAvatarUri.Guid); - } while (avatar == null && System.DateTime.Now.Subtract(time).Seconds < 5); + } while (avatar == null && System.DateTime.Now.Subtract(time).Seconds < 10); window.Close(); Assert.IsNotNull(avatar); diff --git a/Tests/Editor/Common/TestUtils.cs b/Tests/Editor/Common/TestUtils.cs index d949dff0..0f070681 100644 --- a/Tests/Editor/Common/TestUtils.cs +++ b/Tests/Editor/Common/TestUtils.cs @@ -31,6 +31,15 @@ public static void DeleteAvatarDirectoryIfExists(string avatarGuid, bool recursi } } + public static void DeleteEditorAvatarDirectoryIfExists(string avatarGuid, bool recursive = false) + { + var path = $"{Application.dataPath}/Assets/Ready Player Me/Avatars/{avatarGuid}"; + if (Directory.Exists(path)) + { + Directory.Delete(path, recursive); + } + } + public static void DeleteCachedAvatar(string avatarGuid) { var deleteAsset = AssetDatabase.DeleteAsset($"Assets/Ready Player Me/Avatars/{avatarGuid}"); diff --git a/package.json b/package.json index e06673c0..40c3961d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.readyplayerme.core", - "version": "7.3.1", + "version": "7.4.0", "displayName": "Ready Player Me Core", "description": "This Module contains all the core functionality required for using Ready Player Me avatars in Unity, including features such as: \n - Module management and automatic package setup logic\n - Avatar loading from .glb files \n - Avatar creation \n - Avatar and 2D render requests \n - Optional Analytics\n - Custom editor windows\n - Sample scenes and assets", "unity": "2020.3",