From a34857c25ec6501cfdb7ea919016c9a910608317 Mon Sep 17 00:00:00 2001 From: mriise Date: Thu, 14 May 2026 08:40:06 -0700 Subject: [PATCH 1/8] feat: split com.basis.creator out of framework - Avatar and prop authoring package: visemes, blink, lipsync, recorder, animator data moved from framework. BasisPlayer relocated to SDK to break the circular dep. - Editor preview of avatar. --- Basis/Packages/com.basis.creator/Avatar.meta | 8 +++ .../Avatar/Animator.meta | 0 .../BasisPreviousAndCurrentAnimatorData.cs | 0 ...asisPreviousAndCurrentAnimatorData.cs.meta | 0 .../Avatar/BasisAvatarRecorder.cs | 0 .../Avatar/BasisAvatarRecorder.cs.meta | 0 .../com.basis.creator/Basis Creator.asmdef | 19 ++++++ .../Basis Creator.asmdef.meta | 7 +++ Basis/Packages/com.basis.creator/Drivers.meta | 8 +++ .../com.basis.creator/Drivers/Common.meta | 8 +++ .../Common/BasisAudioAndVisemeDriver.cs | 6 +- .../Common/BasisAudioAndVisemeDriver.cs.meta | 0 .../Drivers/Common/BasisOpenLipSyncContext.cs | 0 .../Common/BasisOpenLipSyncContext.cs.meta | 0 .../com.basis.creator/Drivers/Local.meta | 8 +++ .../Local/BasisLocalFacialBlinkDriver.cs | 0 .../Local/BasisLocalFacialBlinkDriver.cs.meta | 0 .../Editor.meta} | 2 +- .../Editor/Basis Creator.Editor.asmdef | 21 +++++++ .../Editor/Basis Creator.Editor.asmdef.meta | 7 +++ .../BasisAvatarEditorPreviewBootstrap.cs | 13 ++++ .../BasisAvatarEditorPreviewBootstrap.cs.meta | 11 ++++ .../Editor}/BasisEditorPreviewLocalPlayer.cs | 45 ++++++++++++-- .../BasisEditorPreviewLocalPlayer.cs.meta | 2 + .../BasisEditorPreviewParametersFoldout.cs | 59 ++++++++++++++++-- ...asisEditorPreviewParametersFoldout.cs.meta | 2 + Basis/Packages/com.basis.creator/Sim.meta | 8 +++ .../Sim/BasisAvatarSimMic.cs | 58 +++++++++++++++++ .../Sim/BasisAvatarSimMic.cs.meta | 11 ++++ .../Sim/BasisAvatarSimPlayer.cs | 62 +++++++++++++++++++ .../Sim/BasisAvatarSimPlayer.cs.meta | 11 ++++ Basis/Packages/com.basis.creator/package.json | 18 ++++++ .../com.basis.creator/package.json.meta | 7 +++ .../BasisEventDriver.asmdef | 2 + .../BasisEditor.asmdef | 3 +- .../Basis Framework.asmdef | 3 +- .../Basis.Integration.AudioLink.asmdef | 1 + .../Editor/BasisAutomaticSetupAvatarEditor.cs | 31 +++++----- .../BasisEditorPreviewLocalPlayer.cs.meta | 2 - ...asisEditorPreviewParametersFoldout.cs.meta | 2 - ...asisAvatarSDKInspector.AvatarBehaviours.cs | 4 ++ .../SDKInspector/BasisAvatarSDKInspector.cs | 11 +--- .../Scripts/Players/BasisLocalPlayerData.cs | 5 +- .../Scripts/Players}/BasisPlayer.cs | 1 - .../Scripts/Players}/BasisPlayer.cs.meta | 0 .../Systems/Runtime/HVR.Basis.Comms.asmdef | 1 + .../Scripts/Runtime/HVR.LicenseReview.asmdef | 1 + Basis/Packages/packages-lock.json | 8 +++ 48 files changed, 427 insertions(+), 49 deletions(-) create mode 100644 Basis/Packages/com.basis.creator/Avatar.meta rename Basis/Packages/{com.basis.framework => com.basis.creator}/Avatar/Animator.meta (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Avatar/BasisAvatarRecorder.cs (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Avatar/BasisAvatarRecorder.cs.meta (100%) create mode 100644 Basis/Packages/com.basis.creator/Basis Creator.asmdef create mode 100644 Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta create mode 100644 Basis/Packages/com.basis.creator/Drivers.meta create mode 100644 Basis/Packages/com.basis.creator/Drivers/Common.meta rename Basis/Packages/{com.basis.framework => com.basis.creator}/Drivers/Common/BasisAudioAndVisemeDriver.cs (97%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Drivers/Common/BasisOpenLipSyncContext.cs (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Drivers/Common/BasisOpenLipSyncContext.cs.meta (100%) create mode 100644 Basis/Packages/com.basis.creator/Drivers/Local.meta rename Basis/Packages/{com.basis.framework => com.basis.creator}/Drivers/Local/BasisLocalFacialBlinkDriver.cs (100%) rename Basis/Packages/{com.basis.framework => com.basis.creator}/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta (100%) rename Basis/Packages/{com.basis.sdk/Scripts/Editor/Players.meta => com.basis.creator/Editor.meta} (77%) create mode 100644 Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef create mode 100644 Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta create mode 100644 Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs create mode 100644 Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta rename Basis/Packages/{com.basis.sdk/Scripts/Editor/Players => com.basis.creator/Editor}/BasisEditorPreviewLocalPlayer.cs (61%) create mode 100644 Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs.meta rename Basis/Packages/{com.basis.sdk/Scripts/Editor/Players => com.basis.creator/Editor}/BasisEditorPreviewParametersFoldout.cs (57%) create mode 100644 Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs.meta create mode 100644 Basis/Packages/com.basis.creator/Sim.meta create mode 100644 Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs create mode 100644 Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs.meta create mode 100644 Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs create mode 100644 Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs.meta create mode 100644 Basis/Packages/com.basis.creator/package.json create mode 100644 Basis/Packages/com.basis.creator/package.json.meta delete mode 100644 Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs.meta delete mode 100644 Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs.meta rename Basis/Packages/{com.basis.framework/Players/Common => com.basis.sdk/Scripts/Players}/BasisPlayer.cs (99%) rename Basis/Packages/{com.basis.framework/Players/Common => com.basis.sdk/Scripts/Players}/BasisPlayer.cs.meta (100%) diff --git a/Basis/Packages/com.basis.creator/Avatar.meta b/Basis/Packages/com.basis.creator/Avatar.meta new file mode 100644 index 0000000000..922795e68e --- /dev/null +++ b/Basis/Packages/com.basis.creator/Avatar.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9eaf2bdb0c49482f9d21a64db55ea32f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.framework/Avatar/Animator.meta b/Basis/Packages/com.basis.creator/Avatar/Animator.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Avatar/Animator.meta rename to Basis/Packages/com.basis.creator/Avatar/Animator.meta diff --git a/Basis/Packages/com.basis.framework/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs b/Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs similarity index 100% rename from Basis/Packages/com.basis.framework/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs rename to Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs diff --git a/Basis/Packages/com.basis.framework/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta b/Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta rename to Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta diff --git a/Basis/Packages/com.basis.framework/Avatar/BasisAvatarRecorder.cs b/Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs similarity index 100% rename from Basis/Packages/com.basis.framework/Avatar/BasisAvatarRecorder.cs rename to Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs diff --git a/Basis/Packages/com.basis.framework/Avatar/BasisAvatarRecorder.cs.meta b/Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Avatar/BasisAvatarRecorder.cs.meta rename to Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs.meta diff --git a/Basis/Packages/com.basis.creator/Basis Creator.asmdef b/Basis/Packages/com.basis.creator/Basis Creator.asmdef new file mode 100644 index 0000000000..20913af4b4 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Basis Creator.asmdef @@ -0,0 +1,19 @@ +{ + "name": "Basis Creator", + "rootNamespace": "", + "references": [ + "BasisSDK", + "BasisDebug", + "Unity.Mathematics", + "Basis.OpenLipSync.Runtime" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} diff --git a/Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta b/Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta new file mode 100644 index 0000000000..4c3b5cfa41 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1d9a7d8b1cf84994b029ee62498bad89 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Drivers.meta b/Basis/Packages/com.basis.creator/Drivers.meta new file mode 100644 index 0000000000..b3f76e61d9 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Drivers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6aee75d491d047a1a39b929f13e7ddf1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Drivers/Common.meta b/Basis/Packages/com.basis.creator/Drivers/Common.meta new file mode 100644 index 0000000000..9d31fd89d8 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Drivers/Common.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e7008f1d087b4c0ea7061e245f8ff23b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.framework/Drivers/Common/BasisAudioAndVisemeDriver.cs b/Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs similarity index 97% rename from Basis/Packages/com.basis.framework/Drivers/Common/BasisAudioAndVisemeDriver.cs rename to Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs index 4634d4023a..f108ec950b 100644 --- a/Basis/Packages/com.basis.framework/Drivers/Common/BasisAudioAndVisemeDriver.cs +++ b/Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs @@ -268,10 +268,12 @@ public void TryShutdown() public volatile bool InVisemeRange = true; // Slot in BasisRemoteAudioDriver.Drivers; -1 when not registered. - [System.NonSerialized] internal int RegisteredIndex = -1; + // Public for cross-asmdef access from Framework's BasisRemoteAudioDriver only — do not mutate externally. + [System.NonSerialized] public int RegisteredIndex = -1; // Slot in BasisRemoteAudioDriver.ActiveDrivers; -1 when out of range. - [System.NonSerialized] internal int ActiveIndex = -1; + // Public for cross-asmdef access from Framework's BasisRemoteAudioDriver only — do not mutate externally. + [System.NonSerialized] public int ActiveIndex = -1; /// /// Callback that updates whether viseme processing is active based on face visibility. diff --git a/Basis/Packages/com.basis.framework/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta b/Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta rename to Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta diff --git a/Basis/Packages/com.basis.framework/Drivers/Common/BasisOpenLipSyncContext.cs b/Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs similarity index 100% rename from Basis/Packages/com.basis.framework/Drivers/Common/BasisOpenLipSyncContext.cs rename to Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs diff --git a/Basis/Packages/com.basis.framework/Drivers/Common/BasisOpenLipSyncContext.cs.meta b/Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Drivers/Common/BasisOpenLipSyncContext.cs.meta rename to Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs.meta diff --git a/Basis/Packages/com.basis.creator/Drivers/Local.meta b/Basis/Packages/com.basis.creator/Drivers/Local.meta new file mode 100644 index 0000000000..06b84cefce --- /dev/null +++ b/Basis/Packages/com.basis.creator/Drivers/Local.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 959a90b3fcf14c23acd300ff68e5fdd6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalFacialBlinkDriver.cs b/Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs similarity index 100% rename from Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalFacialBlinkDriver.cs rename to Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs diff --git a/Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta b/Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta rename to Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players.meta b/Basis/Packages/com.basis.creator/Editor.meta similarity index 77% rename from Basis/Packages/com.basis.sdk/Scripts/Editor/Players.meta rename to Basis/Packages/com.basis.creator/Editor.meta index 93b5dcdfed..f4dfadde37 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players.meta +++ b/Basis/Packages/com.basis.creator/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7b82c20af2150374aa69fc5ffccab2a3 +guid: dab33da8331106747acf9fdce050d4e0 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef b/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef new file mode 100644 index 0000000000..c2e3cd2142 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef @@ -0,0 +1,21 @@ +{ + "name": "Basis Creator.Editor", + "rootNamespace": "", + "references": [ + "Basis Creator", + "BasisSDK", + "BasisSDKEditor", + "BasisDebug" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} diff --git a/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta b/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta new file mode 100644 index 0000000000..8faf388eec --- /dev/null +++ b/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dbb3a5483bf2460e975c402e2a94d1ad +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs b/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs new file mode 100644 index 0000000000..0d5bc7a337 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs @@ -0,0 +1,13 @@ +using UnityEditor; + +namespace Basis.Scripts.BasisSdk.Players.Editor +{ + internal static class BasisAvatarEditorPreviewBootstrap + { + [InitializeOnLoadMethod] + private static void Register() + { + BasisAvatarSDKInspector.PreviewFoldoutFactory = BasisEditorPreviewParametersFoldout.Create; + } + } +} diff --git a/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta b/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta new file mode 100644 index 0000000000..9b00eb5d4e --- /dev/null +++ b/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4a957b49cc4485e81ced9dba1d0ecaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs similarity index 61% rename from Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs rename to Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs index 663cb871ad..f2396629b0 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs +++ b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs @@ -1,4 +1,3 @@ -#if !BASIS_FRAMEWORK_EXISTS using Basis.Scripts.Animator_Driver; using System.Threading.Tasks; using UnityEditor; @@ -6,9 +5,8 @@ namespace Basis.Scripts.BasisSdk.Players.Editor { - // Avatar preview for projects without com.basis.framework. Compiled out when framework - // is installed (gated via versionDefine BASIS_FRAMEWORK_EXISTS) — framework's real - // BasisLocalPlayer registers itself with BasisLocalPlayerData at play-mode init. + // Avatar preview shipped by com.basis.creator. Backs off when framework's + // BasisLocalPlayer has already registered with BasisLocalPlayerData (play mode). internal sealed class BasisEditorPreviewLocalPlayer : IBasisLocalPlayer { private const string FallbackControllerPath = "Packages/com.basis.sdk/Animator/BasisLocomotion.controller"; @@ -18,6 +16,8 @@ internal sealed class BasisEditorPreviewLocalPlayer : IBasisLocalPlayer public static BasisAvatar ActiveAvatar { get; private set; } public static BasisAnimatorVariableApply Applier { get; private set; } + public static BasisAvatarSimPlayer ActiveSimPlayer { get; private set; } + public static BasisAvatarSimMic ActiveSimMic { get; private set; } public static event System.Action StateChanged; private static GameObject _previewRoot; @@ -25,10 +25,32 @@ internal sealed class BasisEditorPreviewLocalPlayer : IBasisLocalPlayer [InitializeOnLoadMethod] private static void Register() { + EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; + EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + + if (BasisLocalPlayerData.Instance != null) return; BasisLocalPlayerData.Instance = _instance; BasisLocalPlayerData.RaiseLocalPlayerInitialized(); } + private static void OnPlayModeStateChanged(PlayModeStateChange state) + { + // The preview is created during play mode (via the inspector's Test-in-Editor flow, + // which enters play mode and resolves the pending avatar from SessionState). Unity's + // play-mode revert destroys the preview root + clone automatically — we just need + // to drop our static refs so they don't dangle into the next session. + if (state == PlayModeStateChange.ExitingPlayMode) + { + if (ActiveSimMic != null) ActiveSimMic.StopCapture(); + _previewRoot = null; + ActiveAvatar = null; + Applier = null; + ActiveSimPlayer = null; + ActiveSimMic = null; + StateChanged?.Invoke(); + } + } + public Task CreateAvatarFromMode(BasisLoadMode LoadMode, BasisLoadableBundle BasisLoadableBundle) { if (LoadMode != BasisLoadMode.ByGameobjectReference) @@ -46,7 +68,7 @@ public Task CreateAvatarFromMode(BasisLoadMode LoadMode, BasisLoadableBundle Bas DisposeActive(); - _previewRoot = new GameObject(PreviewRootName) { hideFlags = HideFlags.DontSave }; + _previewRoot = new GameObject(PreviewRootName); inSceneItem.transform.SetParent(_previewRoot.transform, worldPositionStays: false); inSceneItem.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); @@ -72,19 +94,30 @@ public Task CreateAvatarFromMode(BasisLoadMode LoadMode, BasisLoadableBundle Bas ActiveAvatar = avatar; avatar.NotifyAvatarReady(true); + + // SimPlayer + SimMic provide play-mode ticking for blink and visemes. + // The MonoBehaviours only tick in play mode; in edit mode they're inert. + ActiveSimPlayer = _previewRoot.AddComponent(); + ActiveSimPlayer.Bootstrap(avatar); + + ActiveSimMic = _previewRoot.AddComponent(); + ActiveSimMic.Driver = ActiveSimPlayer.Viseme; + StateChanged?.Invoke(); return Task.CompletedTask; } public static void DisposeActive() { + if (ActiveSimMic != null) ActiveSimMic.StopCapture(); if (_previewRoot != null) Object.DestroyImmediate(_previewRoot); _previewRoot = null; ActiveAvatar = null; Applier = null; + ActiveSimPlayer = null; + ActiveSimMic = null; StateChanged?.Invoke(); } } } -#endif diff --git a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs.meta b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs.meta new file mode 100644 index 0000000000..913611bc25 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bdc48551ca8324e4a98c25e5cf6c4af9 \ No newline at end of file diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs similarity index 57% rename from Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs rename to Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs index 4bbd122611..ee2597963a 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs +++ b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs @@ -1,4 +1,3 @@ -#if !BASIS_FRAMEWORK_EXISTS using UnityEditor; using UnityEngine; using UnityEngine.UIElements; @@ -6,9 +5,10 @@ namespace Basis.Scripts.BasisSdk.Players.Editor { // Drives the live preview avatar's animator parameters from an inspector foldout. - // Mounted by BasisAvatarSDKInspector when the SDK preview is the active driver - // (framework absent). Generic over Animator.parameters — works for the locomotion - // hashes (VelocityX/VelocityZ/IsCrouched/...) and any custom FX-layer params alike. + // Mounted into BasisAvatarSDKInspector via PreviewFoldoutFactory delegate registered + // by BasisAvatarEditorPreviewBootstrap at editor load. Generic over Animator.parameters + // — works for the locomotion hashes (VelocityX/VelocityZ/IsCrouched/...) and any + // custom FX-layer params alike. internal static class BasisEditorPreviewParametersFoldout { public static VisualElement Create() @@ -29,6 +29,8 @@ public static VisualElement Create() return root; } + private static int _selectedMicIndex; + private static void Draw() { var avatar = BasisEditorPreviewLocalPlayer.ActiveAvatar; @@ -40,10 +42,14 @@ private static void Draw() if (GUILayout.Button("Stop Preview")) { - BasisEditorPreviewLocalPlayer.DisposeActive(); + // Exiting play mode is the cleanup. Unity reverts the play-mode scene, + // which destroys the preview root + clone; OnPlayModeStateChanged clears statics. + EditorApplication.ExitPlaymode(); return; } + DrawMicSection(); + Animator anim = avatar.Animator; foreach (AnimatorControllerParameter p in anim.parameters) { @@ -80,6 +86,47 @@ private static void Draw() } } } + + private static void DrawMicSection() + { + var mic = BasisEditorPreviewLocalPlayer.ActiveSimMic; + if (mic == null) return; + + EditorGUILayout.Space(4); + EditorGUILayout.LabelField("Microphone", EditorStyles.boldLabel); + + string[] devices = Microphone.devices; + if (devices.Length == 0) + { + EditorGUILayout.HelpBox("No microphones detected.", MessageType.Info); + return; + } + + // Keep the dropdown selection in sync with whatever the mic is currently using + if (mic.IsCapturing && !string.IsNullOrEmpty(mic.DeviceName)) + { + int idx = System.Array.IndexOf(devices, mic.DeviceName); + if (idx >= 0) _selectedMicIndex = idx; + } + _selectedMicIndex = Mathf.Clamp(_selectedMicIndex, 0, devices.Length - 1); + + using (new EditorGUI.DisabledScope(mic.IsCapturing)) + { + _selectedMicIndex = EditorGUILayout.Popup("Device", _selectedMicIndex, devices); + } + + if (mic.IsCapturing) + { + if (GUILayout.Button("Stop Mic")) mic.StopCapture(); + } + else + { + if (GUILayout.Button("Start Mic")) + { + if (!mic.StartCapture(devices[_selectedMicIndex])) + Debug.LogWarning("[Basis SDK Preview] Failed to start mic capture."); + } + } + } } } -#endif diff --git a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs.meta b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs.meta new file mode 100644 index 0000000000..002db13c19 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 381583f845a005747a6cedc41625c7cb \ No newline at end of file diff --git a/Basis/Packages/com.basis.creator/Sim.meta b/Basis/Packages/com.basis.creator/Sim.meta new file mode 100644 index 0000000000..115d34efba --- /dev/null +++ b/Basis/Packages/com.basis.creator/Sim.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b64301a783814a909a23d72d5228360f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs new file mode 100644 index 0000000000..f65f9f1640 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs @@ -0,0 +1,58 @@ +using Basis.Scripts.Drivers; +using UnityEngine; + +namespace Basis.Scripts.BasisSdk.Players +{ + // Mic capture for the editor preview. Routes raw PCM samples from the OS + // mic to a BasisAudioAndVisemeDriver via OnAudioFilterRead. AudioSource + // volume stays at 0 so the mic doesn't echo to speakers. + [RequireComponent(typeof(AudioSource))] + public sealed class BasisAvatarSimMic : MonoBehaviour + { + public BasisAudioAndVisemeDriver Driver; + public string DeviceName; + public bool IsCapturing { get; private set; } + + private AudioSource _source; + private AudioClip _clip; + private const int ClipLengthSeconds = 1; + + public bool StartCapture(string device) + { + if (IsCapturing) StopCapture(); + if (Microphone.devices.Length == 0) return false; + + DeviceName = string.IsNullOrEmpty(device) ? Microphone.devices[0] : device; + + Microphone.GetDeviceCaps(DeviceName, out int minFreq, out int maxFreq); + int sampleRate = maxFreq > 0 ? maxFreq : AudioSettings.outputSampleRate; + + _clip = Microphone.Start(DeviceName, true, ClipLengthSeconds, sampleRate); + if (_clip == null) return false; + + _source = GetComponent(); + _source.clip = _clip; + _source.loop = true; + _source.volume = 0f; + _source.Play(); + IsCapturing = true; + return true; + } + + public void StopCapture() + { + if (!IsCapturing) return; + if (!string.IsNullOrEmpty(DeviceName)) Microphone.End(DeviceName); + if (_source != null) _source.Stop(); + _clip = null; + IsCapturing = false; + } + + private void OnAudioFilterRead(float[] data, int channels) + { + Driver?.ProcessAudioSamples(data, channels, data.Length); + } + + private void OnDisable() => StopCapture(); + } +} diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs.meta b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs.meta new file mode 100644 index 0000000000..c1ff2223b7 --- /dev/null +++ b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1d0451c4f604815a946015776cb8b5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs new file mode 100644 index 0000000000..0f9f8cd82d --- /dev/null +++ b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs @@ -0,0 +1,62 @@ +using Basis.Scripts.BasisSdk; +using Basis.Scripts.BasisSdk.Helpers; +using Basis.Scripts.Drivers; +using UnityEngine; + +namespace Basis.Scripts.BasisSdk.Players +{ + // Runtime tick host for the avatar package's editor preview. Attached to the + // preview root after the avatar is loaded so blink + visemes have somewhere + // to live in play mode. + public sealed class BasisAvatarSimPlayer : BasisPlayer + { + public BasisLocalFacialBlinkDriver Blink = new BasisLocalFacialBlinkDriver(); + public BasisAudioAndVisemeDriver Viseme = new BasisAudioAndVisemeDriver(); + + public void Bootstrap(BasisAvatar avatar) + { + IsLocal = true; + BasisAvatar = avatar; + FaceIsVisible = true; + + if (avatar.FaceVisemeMesh != null) + { + FaceRenderer = BasisHelpers.GetOrAddComponent(avatar.FaceVisemeMesh.gameObject); + } + + // Zero animator params for an idle-pose preview. The locomotion controller defaults + // CurrentSpeed to 1, which puts the avatar mid-walk before the user touches anything. + // The foldout's sliders still let the user drive these afterwards. + if (avatar.Animator != null && avatar.Animator.runtimeAnimatorController != null) + { + foreach (var p in avatar.Animator.parameters) + { + if (avatar.Animator.IsParameterControlledByCurve(p.nameHash)) continue; + switch (p.type) + { + case AnimatorControllerParameterType.Float: avatar.Animator.SetFloat(p.nameHash, 0f); break; + case AnimatorControllerParameterType.Bool: avatar.Animator.SetBool(p.nameHash, false); break; + case AnimatorControllerParameterType.Int: avatar.Animator.SetInteger(p.nameHash, 0); break; + } + } + } + + Blink.Initialize(this, avatar); + Viseme.TryInitialize(this); + } + + private void Update() + { + Blink.Simulate(Time.timeAsDouble); + Viseme.Simulate(Time.deltaTime); + BasisOpenLipSyncContext.ProcessAllPending(); + Viseme.Apply(); + } + + private void OnDestroy() + { + Blink.OnDestroy(); + Viseme.OnDestroy(); + } + } +} diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs.meta b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs.meta new file mode 100644 index 0000000000..40dfd07adb --- /dev/null +++ b/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ac2331c71974f0c8cf33631007ec6b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/package.json b/Basis/Packages/com.basis.creator/package.json new file mode 100644 index 0000000000..a0b80e7fb1 --- /dev/null +++ b/Basis/Packages/com.basis.creator/package.json @@ -0,0 +1,18 @@ +{ + "name": "com.basis.creator", + "displayName": "Basis Creator", + "version": "0.0.1", + "description": "Creator-side runtime for Basis avatars and props: visemes, facial blink, lip-sync context, recorder, animator data. Pairs with BasisSDK to author both avatars and props without the full client.", + "author": { + "name": "BasisVR", + "url": "https://github.com/BasisVR" + }, + "license": "MIT", + "dependencies": { + "com.unity.mathematics": "1.3.3" + }, + "vpmDependencies": { + "com.basis.openlipsync": "0.2.0", + "com.basis.sdk": "0.0.1" + } +} diff --git a/Basis/Packages/com.basis.creator/package.json.meta b/Basis/Packages/com.basis.creator/package.json.meta new file mode 100644 index 0000000000..f1296992dd --- /dev/null +++ b/Basis/Packages/com.basis.creator/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f085d7c9d6a8473eaeadb4a3cd6e9394 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef b/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef index 3cde6efd7c..fe3027d4e8 100644 --- a/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef +++ b/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef @@ -3,7 +3,9 @@ "rootNamespace": "", "references": [ "BasisConsoleDisplay", + "BasisSDK", "Basis Framework", + "Basis Creator", "Unity.InputSystem", "com.gator-dragon-games.jigglephysics", "SteamAudioUnity", diff --git a/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef b/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef index 74b50fb076..6fdc9875c5 100644 --- a/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef +++ b/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef @@ -19,7 +19,8 @@ "Unity.Addressables.Editor", "Basis.OpenLipSync.Runtime", "BasisEventDriver", - "Unity.TextMeshPro" + "Unity.TextMeshPro", + "Basis Creator" ], "includePlatforms": [ "Editor" diff --git a/Basis/Packages/com.basis.framework/Basis Framework.asmdef b/Basis/Packages/com.basis.framework/Basis Framework.asmdef index 668b74ab6b..684f1abe70 100644 --- a/Basis/Packages/com.basis.framework/Basis Framework.asmdef +++ b/Basis/Packages/com.basis.framework/Basis Framework.asmdef @@ -33,7 +33,8 @@ "BasisSettings", "com.cqf.urpvolumetricfog.runtime", "OpusSharp", - "Basis.OpenLipSync.Runtime" + "Basis.OpenLipSync.Runtime", + "Basis Creator" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Basis/Packages/com.basis.integration.audiolink/Runtime/Basis.Integration.AudioLink.asmdef b/Basis/Packages/com.basis.integration.audiolink/Runtime/Basis.Integration.AudioLink.asmdef index ee327a61a9..a40da93a80 100644 --- a/Basis/Packages/com.basis.integration.audiolink/Runtime/Basis.Integration.AudioLink.asmdef +++ b/Basis/Packages/com.basis.integration.audiolink/Runtime/Basis.Integration.AudioLink.asmdef @@ -2,6 +2,7 @@ "name": "Basis.Integration.AudioLink", "rootNamespace": "Basis.Integration.AudioLink", "references": [ + "BasisSDK", "Basis Framework", "AudioLink" ], diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAutomaticSetupAvatarEditor.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAutomaticSetupAvatarEditor.cs index 0cf675047f..647fcf2d8e 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAutomaticSetupAvatarEditor.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAutomaticSetupAvatarEditor.cs @@ -13,32 +13,29 @@ public static class BasisAutomaticSetupAvatarEditor public static void TryToAutomatic(BasisAvatarSDKInspector Inspector) { BasisAvatar avatar = Inspector.Avatar; - if (avatar != null) + // Inspector can redraw with a destroyed/cleared target during play-mode transitions + // and asset reloads. Bail silently — it's not an error worth logging on every redraw. + if (avatar == null) return; + + if (TryFindOrCheckAvatar(avatar)) { - if (TryFindOrCheckAvatar(avatar)) + if (CheckAnimator(avatar)) { - if (CheckAnimator(avatar)) + if (TryFindNeckAndHead(avatar, out Transform Neck, out Transform Head)) { - if (TryFindNeckAndHead(avatar, out Transform Neck, out Transform Head)) - { - TrySetAvatarEyePosition(avatar); - TrySetAvatarMouthPosition(avatar, Head); - } + TrySetAvatarEyePosition(avatar); + TrySetAvatarMouthPosition(avatar, Head); } } - else - { - Debug.LogError("Animator component not found on GameObject " + avatar.gameObject.name); - } - UpdateAvatarRenders(avatar); - - EditorUtility.SetDirty(avatar); - AssetDatabase.Refresh(); } else { - Debug.LogError("Avatar instance is null."); + Debug.LogError("Animator component not found on GameObject " + avatar.gameObject.name); } + UpdateAvatarRenders(avatar); + + EditorUtility.SetDirty(avatar); + AssetDatabase.Refresh(); } private static bool CheckAnimator(BasisAvatar avatar) { diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs.meta deleted file mode 100644 index d487765f85..0000000000 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewLocalPlayer.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 52797d3e87169014cb7c262de9a87bcc \ No newline at end of file diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs.meta deleted file mode 100644 index 1ca03aba44..0000000000 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/Players/BasisEditorPreviewParametersFoldout.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 87df41ce57a93e3478768be9d3eedcc2 \ No newline at end of file diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.AvatarBehaviours.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.AvatarBehaviours.cs index 24e0e8010e..13a56b8e1c 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.AvatarBehaviours.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.AvatarBehaviours.cs @@ -54,6 +54,10 @@ private static bool IsVisibleInAvatarMenu(Type type) private void RefreshNetworkBehaviours() { + // Inspector can redraw during play-mode transitions when the target avatar has + // been destroyed (Unity reroutes selection slightly later). Bail rather than throw. + if (Avatar == null) return; + _attachedContainer.Clear(); _availableContainer.Clear(); diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs index f49f04088d..f0877f0fae 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs @@ -23,6 +23,7 @@ public partial class BasisAvatarSDKInspector : Editor public static event Action InspectorGuiCreated; public static event Action ButtonClicked; public static event Action ValueChanged; + public static Func PreviewFoldoutFactory; public VisualTreeAsset visualTree; public BasisAvatar Avatar; public VisualElement uiElementsRoot; @@ -138,9 +139,8 @@ public override VisualElement CreateInspectorGUI() SetupItems(); AvatarSDKVisemes.Initialize(this); SetupNetworkBehaviours(); -#if !BASIS_FRAMEWORK_EXISTS - rootElement.Add(Basis.Scripts.BasisSdk.Players.Editor.BasisEditorPreviewParametersFoldout.Create()); -#endif + var previewFoldout = PreviewFoldoutFactory?.Invoke(); + if (previewFoldout != null) rootElement.Add(previewFoldout); InspectorGuiCreated?.Invoke(this); } else @@ -624,7 +624,6 @@ public void GenerateMeshLODs(int lodLimit = -1) #endif public void AvatarTestInEditorClickFunction() { -#if BASIS_FRAMEWORK_EXISTS if (!Application.isPlaying) { bool result = EditorUtility.DisplayDialog( @@ -642,10 +641,6 @@ public void AvatarTestInEditorClickFunction() { RequestAvatarLoad(); } -#else - // SDK preview runs in either edit or play mode — no play-mode prompt needed. - RequestAvatarLoad(); -#endif } public void RequestAvatarLoad() { diff --git a/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs index b04365f0af..d18a82e1c2 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs @@ -9,8 +9,9 @@ public interface IBasisLocalPlayer } // SDK-side local player data. Framework's BasisLocalPlayer writes Instance - // when present; otherwise the SDK editor preview writes a stand-in (gated - // by BASIS_FRAMEWORK_EXISTS so only one writer ever runs). + // when present; otherwise com.basis.creator's editor preview writes a stand-in + // (the preview only registers when Instance is still null, so only one writer + // ever wins). public static class BasisLocalPlayerData { public static IBasisLocalPlayer Instance; diff --git a/Basis/Packages/com.basis.framework/Players/Common/BasisPlayer.cs b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisPlayer.cs similarity index 99% rename from Basis/Packages/com.basis.framework/Players/Common/BasisPlayer.cs rename to Basis/Packages/com.basis.sdk/Scripts/Players/BasisPlayer.cs index 3f1eaa6b76..71f3d18bb2 100644 --- a/Basis/Packages/com.basis.framework/Players/Common/BasisPlayer.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisPlayer.cs @@ -1,4 +1,3 @@ -using Basis.Scripts.Drivers; using System; using System.Text.RegularExpressions; using UnityEngine; diff --git a/Basis/Packages/com.basis.framework/Players/Common/BasisPlayer.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisPlayer.cs.meta similarity index 100% rename from Basis/Packages/com.basis.framework/Players/Common/BasisPlayer.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Players/BasisPlayer.cs.meta diff --git a/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef b/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef index 93f6e8fdef..9dfd9f836d 100644 --- a/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef +++ b/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef @@ -6,6 +6,7 @@ "Unity.Mathematics", "BasisNetworkCore", "Basis Framework", + "Basis Creator", "BasisDebug", "HVR.Basis.Comms.HVRUtility", "Unity.Addressables", diff --git a/Basis/Packages/dev.hai-vr.hvr.license-review/Scripts/Runtime/HVR.LicenseReview.asmdef b/Basis/Packages/dev.hai-vr.hvr.license-review/Scripts/Runtime/HVR.LicenseReview.asmdef index 069b50ebf7..8bb1cbcf1a 100644 --- a/Basis/Packages/dev.hai-vr.hvr.license-review/Scripts/Runtime/HVR.LicenseReview.asmdef +++ b/Basis/Packages/dev.hai-vr.hvr.license-review/Scripts/Runtime/HVR.LicenseReview.asmdef @@ -2,6 +2,7 @@ "name": "HVR.LicenseReview", "rootNamespace": "", "references": [ + "BasisSDK", "Basis Framework", "Unity.Addressables", "Unity.ResourceManager" diff --git a/Basis/Packages/packages-lock.json b/Basis/Packages/packages-lock.json index 92229dbb22..21cdf82f2e 100644 --- a/Basis/Packages/packages-lock.json +++ b/Basis/Packages/packages-lock.json @@ -12,6 +12,14 @@ "source": "embedded", "dependencies": {} }, + "com.basis.creator": { + "version": "file:com.basis.creator", + "depth": 0, + "source": "embedded", + "dependencies": { + "com.unity.mathematics": "1.3.3" + } + }, "com.basis.bundlemanagement": { "version": "file:com.basis.bundlemanagement", "depth": 0, From cadc3009624f65343be9fc1e5a88bdc157d1f1cb Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 07:54:42 -0700 Subject: [PATCH 2/8] chore: update unitypackage and vpm pkg ci --- .github/scripts/unitypackagegen.sh | 38 +++++++++++++++++++++++------- .github/vpm-packages.txt | 2 ++ .github/workflows/compilation.yml | 5 ++++ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/.github/scripts/unitypackagegen.sh b/.github/scripts/unitypackagegen.sh index 8d437c0602..c49445b99d 100755 --- a/.github/scripts/unitypackagegen.sh +++ b/.github/scripts/unitypackagegen.sh @@ -17,6 +17,11 @@ EXTRASUBFOLDER="" EXTRASUBFOLDERS="" MOREFILES="" +# Creator-side authoring packages +CREATOR_SUBFOLDERS="Packages/com.basis.creator: + Packages/com.basis.openlipsync: + Packages/dev.hai-vr.basis.ndmf" + if [[ "$1" == "full" ]]; then @@ -24,15 +29,18 @@ if [[ "$1" == "full" ]]; then PACKAGES+=":Packages/com.valvesoftware.unity.openvr-1.2.1.tgz" - # Need this for framework (But only framework) + SUBFOLDERS+=":${CREATOR_SUBFOLDERS}" + + # Framework + client-only additions on top of the SDK + creator base. SUBFOLDERS+=":Packages/com.avionblock.opussharp: + Packages/com.basis.addon.snapcontrols: Packages/com.basis.common: Packages/com.basis.eventdriver: Packages/com.basis.examples: Packages/com.basis.framework: Packages/com.basis.framework.editor: Packages/com.basis.gizmos: - Packages/com.basis.openlipsync: + Packages/com.basis.integration.audiolink: Packages/com.basis.openvr: Packages/com.basis.openxr: Packages/com.basis.profilerintergration: @@ -41,21 +49,17 @@ if [[ "$1" == "full" ]]; then Packages/com.basis.textmeshpro: Packages/com.basis.vehicles: Packages/com.basis.visualtrackers: - Packages/com.basis.zeromessenger: Packages/com.cnlohr.cilbox: Packages/com.cqf.urpvolumetricfog: - Packages/com.hecomi.ulipsync: Packages/com.llealloo.audiolink: Packages/com.steam.steamaudio: Packages/com.steam.steamvr: Packages/com.unity.3rdpersondemo: - Packages/com.unity.render-pipelines.core: Packages/com.unity.render-pipelines.universal: - Packages/com.unity.xr.openxr: Packages/com.xiph.rnnoise: Packages/dev.hai-vr.basis.comms: - Packages/HVRBasisNDMF: Packages/nuget.meamod.dns: + Packages/org.basisvr.k4os.compression.lz4: Assets/AddressableAssetsData: Assets/Basis: Assets/MetaXR: @@ -72,14 +76,30 @@ if [[ "$1" == "full" ]]; then elif [[ "$1" == "sdk" ]]; then echo "Producing SDK package" # All things are already included. + +elif [[ "$1" == "creator" ]]; then + + echo "Producing CREATOR package" + + SUBFOLDERS+=":${CREATOR_SUBFOLDERS}" + else - echo "Only full and sdk targets are specified." + echo "Only full, sdk, and creator targets are specified." die - exit + exit 1 fi set -e +# Fail loudly if a listed Packages/ path doesn't exist +for ddv in $(echo "$SUBFOLDERS" | tr : '\n'); do + ddv_trimmed=$(echo "$ddv" | tr -d '[:space:]') + if [[ -n "$ddv_trimmed" && "$ddv_trimmed" == Packages/* && ! -d "Basis/$ddv_trimmed" ]]; then + echo "ERROR: SUBFOLDERS lists '$ddv_trimmed' but Basis/$ddv_trimmed does not exist." >&2 + exit 1 + fi +done + cd Basis rm -rf generate_unitypackage diff --git a/.github/vpm-packages.txt b/.github/vpm-packages.txt index 9f6700ac08..b471c1e57f 100644 --- a/.github/vpm-packages.txt +++ b/.github/vpm-packages.txt @@ -9,6 +9,7 @@ com.basis.server com.basis.framework com.basis.framework.editor com.basis.openlipsync +com.basis.creator com.basis.common com.basis.eventdriver com.basis.profilerintergration @@ -37,6 +38,7 @@ com.llealloo.audiolink com.xiph.rnnoise com.cnlohr.cilbox dev.hai-vr.basis.comms +dev.hai-vr.basis.ndmf # VR / spatial-audio (Apache 2.0 / BSD-3). com.steam.steamaudio diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index 89e76b6fba..31a91a90f0 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -353,6 +353,9 @@ jobs: - name: "Produce SDK unitypackage." timeout-minutes: 5 run: .github/scripts/unitypackagegen.sh sdk + - name: "Produce Creator unitypackage." + timeout-minutes: 5 + run: .github/scripts/unitypackagegen.sh creator - name: "Produce full unitypackage." timeout-minutes: 5 run: .github/scripts/unitypackagegen.sh full @@ -362,6 +365,7 @@ jobs: name: unitypackage_upload path: | Basis/Basis.sdk.unitypackage + Basis/Basis.creator.unitypackage Basis/Basis.full.unitypackage - name: "Release unitypackage" if: github.ref_type == 'tag' @@ -370,4 +374,5 @@ jobs: with: files: | Basis/Basis.sdk.unitypackage + Basis/Basis.creator.unitypackage Basis/Basis.full.unitypackage From 0c1186f69ee69f1c0cc424fa71b16ddd194d7836 Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 08:58:30 -0700 Subject: [PATCH 3/8] feat: merge avatar systems into sdk --- .github/scripts/unitypackagegen.sh | 16 ++------------ .github/vpm-packages.txt | 1 - .github/workflows/compilation.yml | 5 ----- .../com.basis.creator/Basis Creator.asmdef | 19 ----------------- .../Basis Creator.asmdef.meta | 7 ------- Basis/Packages/com.basis.creator/Editor.meta | 8 ------- .../Editor/Basis Creator.Editor.asmdef | 21 ------------------- .../Editor/Basis Creator.Editor.asmdef.meta | 7 ------- Basis/Packages/com.basis.creator/package.json | 18 ---------------- .../com.basis.creator/package.json.meta | 7 ------- .../BasisEventDriver.asmdef | 1 - .../BasisEditor.asmdef | 3 +-- .../Basis Framework.asmdef | 3 +-- Basis/Packages/com.basis.sdk/BasisSDK.asmdef | 3 ++- .../Scripts}/Avatar.meta | 0 .../Scripts}/Avatar/Animator.meta | 0 .../BasisPreviousAndCurrentAnimatorData.cs | 0 ...asisPreviousAndCurrentAnimatorData.cs.meta | 0 .../Scripts}/Avatar/BasisAvatarRecorder.cs | 0 .../Avatar/BasisAvatarRecorder.cs.meta | 0 .../Scripts}/Drivers.meta | 0 .../Scripts}/Drivers/Common.meta | 0 .../Common/BasisAudioAndVisemeDriver.cs | 0 .../Common/BasisAudioAndVisemeDriver.cs.meta | 0 .../Drivers/Common/BasisOpenLipSyncContext.cs | 0 .../Common/BasisOpenLipSyncContext.cs.meta | 0 .../Scripts}/Drivers/Local.meta | 0 .../Local/BasisLocalFacialBlinkDriver.cs | 0 .../Local/BasisLocalFacialBlinkDriver.cs.meta | 0 .../BasisAvatarEditorPreviewBootstrap.cs | 0 .../BasisAvatarEditorPreviewBootstrap.cs.meta | 0 .../Editor/BasisEditorPreviewLocalPlayer.cs | 4 ++-- .../BasisEditorPreviewLocalPlayer.cs.meta | 0 .../BasisEditorPreviewParametersFoldout.cs | 0 ...asisEditorPreviewParametersFoldout.cs.meta | 0 .../Scripts/Players/BasisLocalPlayerData.cs | 2 +- .../Scripts}/Sim.meta | 0 .../Scripts}/Sim/BasisAvatarSimMic.cs | 0 .../Scripts}/Sim/BasisAvatarSimMic.cs.meta | 0 .../Scripts}/Sim/BasisAvatarSimPlayer.cs | 2 +- .../Scripts}/Sim/BasisAvatarSimPlayer.cs.meta | 0 Basis/Packages/com.basis.sdk/package.json | 1 + .../Systems/Runtime/HVR.Basis.Comms.asmdef | 1 - Basis/Packages/packages-lock.json | 8 ------- 44 files changed, 11 insertions(+), 126 deletions(-) delete mode 100644 Basis/Packages/com.basis.creator/Basis Creator.asmdef delete mode 100644 Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta delete mode 100644 Basis/Packages/com.basis.creator/Editor.meta delete mode 100644 Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef delete mode 100644 Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta delete mode 100644 Basis/Packages/com.basis.creator/package.json delete mode 100644 Basis/Packages/com.basis.creator/package.json.meta rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Avatar.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Avatar/Animator.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Avatar/BasisAvatarRecorder.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Avatar/BasisAvatarRecorder.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Common.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Common/BasisAudioAndVisemeDriver.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Common/BasisOpenLipSyncContext.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Common/BasisOpenLipSyncContext.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Local.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Local/BasisLocalFacialBlinkDriver.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Editor/BasisAvatarEditorPreviewBootstrap.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Editor/BasisEditorPreviewLocalPlayer.cs (96%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Editor/BasisEditorPreviewLocalPlayer.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Editor/BasisEditorPreviewParametersFoldout.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Editor/BasisEditorPreviewParametersFoldout.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Sim.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Sim/BasisAvatarSimMic.cs (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Sim/BasisAvatarSimMic.cs.meta (100%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Sim/BasisAvatarSimPlayer.cs (96%) rename Basis/Packages/{com.basis.creator => com.basis.sdk/Scripts}/Sim/BasisAvatarSimPlayer.cs.meta (100%) diff --git a/.github/scripts/unitypackagegen.sh b/.github/scripts/unitypackagegen.sh index c49445b99d..770405fe72 100755 --- a/.github/scripts/unitypackagegen.sh +++ b/.github/scripts/unitypackagegen.sh @@ -7,6 +7,7 @@ PACKAGES="Packages/org.basisvr.generator.equals-3.2.0.tgz: Packages/org.basisvr.simplebase-4.0.2.tgz: Packages/org.basisvr.bouncycastle-2.5.0.tgz" SUBFOLDERS="Packages/com.basis.sdk: + Packages/com.basis.openlipsync: Packages/UnityJigglePhysics-upm: Packages/org.basisvr.k4os.compression.lz4: Packages/com.basis.bundlemanagement: @@ -17,11 +18,6 @@ EXTRASUBFOLDER="" EXTRASUBFOLDERS="" MOREFILES="" -# Creator-side authoring packages -CREATOR_SUBFOLDERS="Packages/com.basis.creator: - Packages/com.basis.openlipsync: - Packages/dev.hai-vr.basis.ndmf" - if [[ "$1" == "full" ]]; then @@ -29,9 +25,7 @@ if [[ "$1" == "full" ]]; then PACKAGES+=":Packages/com.valvesoftware.unity.openvr-1.2.1.tgz" - SUBFOLDERS+=":${CREATOR_SUBFOLDERS}" - - # Framework + client-only additions on top of the SDK + creator base. + # Framework + client-only additions on top of the SDK base. SUBFOLDERS+=":Packages/com.avionblock.opussharp: Packages/com.basis.addon.snapcontrols: Packages/com.basis.common: @@ -77,12 +71,6 @@ elif [[ "$1" == "sdk" ]]; then echo "Producing SDK package" # All things are already included. -elif [[ "$1" == "creator" ]]; then - - echo "Producing CREATOR package" - - SUBFOLDERS+=":${CREATOR_SUBFOLDERS}" - else echo "Only full, sdk, and creator targets are specified." die diff --git a/.github/vpm-packages.txt b/.github/vpm-packages.txt index b471c1e57f..711f90fc2a 100644 --- a/.github/vpm-packages.txt +++ b/.github/vpm-packages.txt @@ -9,7 +9,6 @@ com.basis.server com.basis.framework com.basis.framework.editor com.basis.openlipsync -com.basis.creator com.basis.common com.basis.eventdriver com.basis.profilerintergration diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index 31a91a90f0..89e76b6fba 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -353,9 +353,6 @@ jobs: - name: "Produce SDK unitypackage." timeout-minutes: 5 run: .github/scripts/unitypackagegen.sh sdk - - name: "Produce Creator unitypackage." - timeout-minutes: 5 - run: .github/scripts/unitypackagegen.sh creator - name: "Produce full unitypackage." timeout-minutes: 5 run: .github/scripts/unitypackagegen.sh full @@ -365,7 +362,6 @@ jobs: name: unitypackage_upload path: | Basis/Basis.sdk.unitypackage - Basis/Basis.creator.unitypackage Basis/Basis.full.unitypackage - name: "Release unitypackage" if: github.ref_type == 'tag' @@ -374,5 +370,4 @@ jobs: with: files: | Basis/Basis.sdk.unitypackage - Basis/Basis.creator.unitypackage Basis/Basis.full.unitypackage diff --git a/Basis/Packages/com.basis.creator/Basis Creator.asmdef b/Basis/Packages/com.basis.creator/Basis Creator.asmdef deleted file mode 100644 index 20913af4b4..0000000000 --- a/Basis/Packages/com.basis.creator/Basis Creator.asmdef +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Basis Creator", - "rootNamespace": "", - "references": [ - "BasisSDK", - "BasisDebug", - "Unity.Mathematics", - "Basis.OpenLipSync.Runtime" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} diff --git a/Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta b/Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta deleted file mode 100644 index 4c3b5cfa41..0000000000 --- a/Basis/Packages/com.basis.creator/Basis Creator.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 1d9a7d8b1cf84994b029ee62498bad89 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Editor.meta b/Basis/Packages/com.basis.creator/Editor.meta deleted file mode 100644 index f4dfadde37..0000000000 --- a/Basis/Packages/com.basis.creator/Editor.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: dab33da8331106747acf9fdce050d4e0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef b/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef deleted file mode 100644 index c2e3cd2142..0000000000 --- a/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "Basis Creator.Editor", - "rootNamespace": "", - "references": [ - "Basis Creator", - "BasisSDK", - "BasisSDKEditor", - "BasisDebug" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} diff --git a/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta b/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta deleted file mode 100644 index 8faf388eec..0000000000 --- a/Basis/Packages/com.basis.creator/Editor/Basis Creator.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: dbb3a5483bf2460e975c402e2a94d1ad -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Basis/Packages/com.basis.creator/package.json b/Basis/Packages/com.basis.creator/package.json deleted file mode 100644 index a0b80e7fb1..0000000000 --- a/Basis/Packages/com.basis.creator/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "com.basis.creator", - "displayName": "Basis Creator", - "version": "0.0.1", - "description": "Creator-side runtime for Basis avatars and props: visemes, facial blink, lip-sync context, recorder, animator data. Pairs with BasisSDK to author both avatars and props without the full client.", - "author": { - "name": "BasisVR", - "url": "https://github.com/BasisVR" - }, - "license": "MIT", - "dependencies": { - "com.unity.mathematics": "1.3.3" - }, - "vpmDependencies": { - "com.basis.openlipsync": "0.2.0", - "com.basis.sdk": "0.0.1" - } -} diff --git a/Basis/Packages/com.basis.creator/package.json.meta b/Basis/Packages/com.basis.creator/package.json.meta deleted file mode 100644 index f1296992dd..0000000000 --- a/Basis/Packages/com.basis.creator/package.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: f085d7c9d6a8473eaeadb4a3cd6e9394 -PackageManifestImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef b/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef index fe3027d4e8..27731eee32 100644 --- a/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef +++ b/Basis/Packages/com.basis.eventdriver/BasisEventDriver.asmdef @@ -5,7 +5,6 @@ "BasisConsoleDisplay", "BasisSDK", "Basis Framework", - "Basis Creator", "Unity.InputSystem", "com.gator-dragon-games.jigglephysics", "SteamAudioUnity", diff --git a/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef b/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef index 6fdc9875c5..74b50fb076 100644 --- a/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef +++ b/Basis/Packages/com.basis.framework.editor/BasisEditor.asmdef @@ -19,8 +19,7 @@ "Unity.Addressables.Editor", "Basis.OpenLipSync.Runtime", "BasisEventDriver", - "Unity.TextMeshPro", - "Basis Creator" + "Unity.TextMeshPro" ], "includePlatforms": [ "Editor" diff --git a/Basis/Packages/com.basis.framework/Basis Framework.asmdef b/Basis/Packages/com.basis.framework/Basis Framework.asmdef index 684f1abe70..668b74ab6b 100644 --- a/Basis/Packages/com.basis.framework/Basis Framework.asmdef +++ b/Basis/Packages/com.basis.framework/Basis Framework.asmdef @@ -33,8 +33,7 @@ "BasisSettings", "com.cqf.urpvolumetricfog.runtime", "OpusSharp", - "Basis.OpenLipSync.Runtime", - "Basis Creator" + "Basis.OpenLipSync.Runtime" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Basis/Packages/com.basis.sdk/BasisSDK.asmdef b/Basis/Packages/com.basis.sdk/BasisSDK.asmdef index e210c2e329..d32ced479c 100644 --- a/Basis/Packages/com.basis.sdk/BasisSDK.asmdef +++ b/Basis/Packages/com.basis.sdk/BasisSDK.asmdef @@ -6,7 +6,8 @@ "BasisDebug", "Unity.TextMeshPro", "Unity.Addressables", - "Unity.ResourceManager" + "Unity.ResourceManager", + "Basis.OpenLipSync.Runtime" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Basis/Packages/com.basis.creator/Avatar.meta b/Basis/Packages/com.basis.sdk/Scripts/Avatar.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Avatar.meta rename to Basis/Packages/com.basis.sdk/Scripts/Avatar.meta diff --git a/Basis/Packages/com.basis.creator/Avatar/Animator.meta b/Basis/Packages/com.basis.sdk/Scripts/Avatar/Animator.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Avatar/Animator.meta rename to Basis/Packages/com.basis.sdk/Scripts/Avatar/Animator.meta diff --git a/Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs b/Basis/Packages/com.basis.sdk/Scripts/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs rename to Basis/Packages/com.basis.sdk/Scripts/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs diff --git a/Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Avatar/Animator/BasisPreviousAndCurrentAnimatorData.cs.meta diff --git a/Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs b/Basis/Packages/com.basis.sdk/Scripts/Avatar/BasisAvatarRecorder.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs rename to Basis/Packages/com.basis.sdk/Scripts/Avatar/BasisAvatarRecorder.cs diff --git a/Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Avatar/BasisAvatarRecorder.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Avatar/BasisAvatarRecorder.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Avatar/BasisAvatarRecorder.cs.meta diff --git a/Basis/Packages/com.basis.creator/Drivers.meta b/Basis/Packages/com.basis.sdk/Scripts/Drivers.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers.meta rename to Basis/Packages/com.basis.sdk/Scripts/Drivers.meta diff --git a/Basis/Packages/com.basis.creator/Drivers/Common.meta b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Common.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Common.meta rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Common.meta diff --git a/Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisAudioAndVisemeDriver.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisAudioAndVisemeDriver.cs diff --git a/Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisAudioAndVisemeDriver.cs.meta diff --git a/Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisOpenLipSyncContext.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisOpenLipSyncContext.cs diff --git a/Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisOpenLipSyncContext.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Common/BasisOpenLipSyncContext.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Common/BasisOpenLipSyncContext.cs.meta diff --git a/Basis/Packages/com.basis.creator/Drivers/Local.meta b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Local.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Local.meta rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Local.meta diff --git a/Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Local/BasisLocalFacialBlinkDriver.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Local/BasisLocalFacialBlinkDriver.cs diff --git a/Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Drivers/Local/BasisLocalFacialBlinkDriver.cs.meta diff --git a/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs rename to Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs diff --git a/Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs.meta diff --git a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs similarity index 96% rename from Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs rename to Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs index f2396629b0..c558426e77 100644 --- a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs @@ -5,8 +5,8 @@ namespace Basis.Scripts.BasisSdk.Players.Editor { - // Avatar preview shipped by com.basis.creator. Backs off when framework's - // BasisLocalPlayer has already registered with BasisLocalPlayerData (play mode). + // SDK-side avatar preview. Backs off when framework's BasisLocalPlayer has + // already registered with BasisLocalPlayerData (play mode). internal sealed class BasisEditorPreviewLocalPlayer : IBasisLocalPlayer { private const string FallbackControllerPath = "Packages/com.basis.sdk/Animator/BasisLocomotion.controller"; diff --git a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewLocalPlayer.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs.meta diff --git a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs rename to Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs diff --git a/Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Editor/BasisEditorPreviewParametersFoldout.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs.meta diff --git a/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs index d18a82e1c2..ffd88274a5 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Players/BasisLocalPlayerData.cs @@ -9,7 +9,7 @@ public interface IBasisLocalPlayer } // SDK-side local player data. Framework's BasisLocalPlayer writes Instance - // when present; otherwise com.basis.creator's editor preview writes a stand-in + // when present; otherwise the SDK's editor preview writes a stand-in // (the preview only registers when Instance is still null, so only one writer // ever wins). public static class BasisLocalPlayerData diff --git a/Basis/Packages/com.basis.creator/Sim.meta b/Basis/Packages/com.basis.sdk/Scripts/Sim.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Sim.meta rename to Basis/Packages/com.basis.sdk/Scripts/Sim.meta diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs similarity index 100% rename from Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs rename to Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Sim/BasisAvatarSimMic.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs.meta diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs similarity index 96% rename from Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs rename to Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs index 0f9f8cd82d..a54c2312e4 100644 --- a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs @@ -5,7 +5,7 @@ namespace Basis.Scripts.BasisSdk.Players { - // Runtime tick host for the avatar package's editor preview. Attached to the + // Runtime tick host for the SDK's editor preview. Attached to the // preview root after the avatar is loaded so blink + visemes have somewhere // to live in play mode. public sealed class BasisAvatarSimPlayer : BasisPlayer diff --git a/Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs.meta b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs.meta similarity index 100% rename from Basis/Packages/com.basis.creator/Sim/BasisAvatarSimPlayer.cs.meta rename to Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs.meta diff --git a/Basis/Packages/com.basis.sdk/package.json b/Basis/Packages/com.basis.sdk/package.json index ea9afb0850..ac2e5e48e8 100644 --- a/Basis/Packages/com.basis.sdk/package.json +++ b/Basis/Packages/com.basis.sdk/package.json @@ -16,6 +16,7 @@ "com.unity.ugui": "2.0.0" }, "vpmDependencies": { + "com.basis.openlipsync": "0.2.0", "org.basisvr.bouncycastle": "2.5.0", "org.basisvr.newtonsoft.json": "13.0.3" } diff --git a/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef b/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef index 9dfd9f836d..93f6e8fdef 100644 --- a/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef +++ b/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/HVR.Basis.Comms.asmdef @@ -6,7 +6,6 @@ "Unity.Mathematics", "BasisNetworkCore", "Basis Framework", - "Basis Creator", "BasisDebug", "HVR.Basis.Comms.HVRUtility", "Unity.Addressables", diff --git a/Basis/Packages/packages-lock.json b/Basis/Packages/packages-lock.json index 21cdf82f2e..92229dbb22 100644 --- a/Basis/Packages/packages-lock.json +++ b/Basis/Packages/packages-lock.json @@ -12,14 +12,6 @@ "source": "embedded", "dependencies": {} }, - "com.basis.creator": { - "version": "file:com.basis.creator", - "depth": 0, - "source": "embedded", - "dependencies": { - "com.unity.mathematics": "1.3.3" - } - }, "com.basis.bundlemanagement": { "version": "file:com.basis.bundlemanagement", "depth": 0, From 6adb8b37ee24e1308187de39dcb7711f74183788 Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 09:29:50 -0700 Subject: [PATCH 4/8] fix: gate avatar sim/inspector foldout when framework is in project --- Basis/Packages/com.basis.sdk/BasisSDK.asmdef | 8 ++++++- .../BasisAvatarEditorPreviewBootstrap.cs | 2 ++ .../Editor/BasisEditorPreviewLocalPlayer.cs | 2 ++ .../BasisEditorPreviewParametersFoldout.cs | 2 ++ .../SDKInspector/BasisAvatarSDKInspector.cs | 21 +++++++++++++++++-- .../Scripts/Sim/BasisAvatarSimMic.cs | 2 ++ .../Scripts/Sim/BasisAvatarSimPlayer.cs | 2 ++ 7 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Basis/Packages/com.basis.sdk/BasisSDK.asmdef b/Basis/Packages/com.basis.sdk/BasisSDK.asmdef index d32ced479c..4f2538143f 100644 --- a/Basis/Packages/com.basis.sdk/BasisSDK.asmdef +++ b/Basis/Packages/com.basis.sdk/BasisSDK.asmdef @@ -16,6 +16,12 @@ "precompiledReferences": [], "autoReferenced": true, "defineConstraints": [], - "versionDefines": [], + "versionDefines": [ + { + "name": "com.basis.framework", + "expression": "", + "define": "BASIS_FRAMEWORK_EXISTS" + } + ], "noEngineReferences": false } \ No newline at end of file diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs index 0d5bc7a337..e2cdd0b9ea 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisAvatarEditorPreviewBootstrap.cs @@ -1,3 +1,4 @@ +#if !BASIS_FRAMEWORK_EXISTS using UnityEditor; namespace Basis.Scripts.BasisSdk.Players.Editor @@ -11,3 +12,4 @@ private static void Register() } } } +#endif diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs index c558426e77..eac2c800cb 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs @@ -1,3 +1,4 @@ +#if !BASIS_FRAMEWORK_EXISTS using Basis.Scripts.Animator_Driver; using System.Threading.Tasks; using UnityEditor; @@ -121,3 +122,4 @@ public static void DisposeActive() } } +#endif diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs index ee2597963a..9c1ebb6ec5 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewParametersFoldout.cs @@ -1,3 +1,4 @@ +#if !BASIS_FRAMEWORK_EXISTS using UnityEditor; using UnityEngine; using UnityEngine.UIElements; @@ -130,3 +131,4 @@ private static void DrawMicSection() } } } +#endif diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs index f0877f0fae..2c3968654a 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs @@ -15,6 +15,11 @@ public partial class BasisAvatarSDKInspector : Editor { private const string PendingTestInEditorAvatarIdSessionKey = "BasisAvatarSDKInspector.PendingTestInEditorAvatarId"; + // Unity's GlobalObjectId table isn't always populated on the first delayCall after + // EnteredPlayMode (the play-mode scene reload races us). Retry a bounded number of + // ticks so a transient null resolve doesn't drop the pending avatar. + private const int MaxResolveAttempts = 30; + private static int _resolveAttempts; public delegate void BeforeTestInEditorHandler(GameObject clone); public static BeforeTestInEditorHandler OnBeforeTestInEditor; @@ -50,6 +55,7 @@ private static void OnPlayModeStateChanged(PlayModeStateChange state) return; } + _resolveAttempts = 0; EditorApplication.delayCall -= TryExecutePendingTestInEditor; EditorApplication.delayCall += TryExecutePendingTestInEditor; } @@ -59,23 +65,34 @@ private static void TryExecutePendingTestInEditor() string pendingAvatarId = GetPendingTestInEditorAvatarId(); if (string.IsNullOrEmpty(pendingAvatarId)) { + _resolveAttempts = 0; return; } if (!GlobalObjectId.TryParse(pendingAvatarId, out GlobalObjectId avatarId)) { ClearPendingTestInEditorAvatarId(); + _resolveAttempts = 0; return; } BasisAvatar avatar = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(avatarId) as BasisAvatar; - ClearPendingTestInEditorAvatarId(); if (avatar == null) { - BasisDebug.LogError("Unable to resolve the pending avatar for Test In Editor.", BasisDebug.LogTag.Editor); + if (++_resolveAttempts < MaxResolveAttempts) + { + EditorApplication.delayCall += TryExecutePendingTestInEditor; + return; + } + + ClearPendingTestInEditorAvatarId(); + _resolveAttempts = 0; + BasisDebug.LogError($"Unable to resolve the pending avatar for Test In Editor after {MaxResolveAttempts} attempts.", BasisDebug.LogTag.Editor); return; } + ClearPendingTestInEditorAvatarId(); + _resolveAttempts = 0; RequestAvatarLoad(avatar); } diff --git a/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs index f65f9f1640..2dad6a56f5 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimMic.cs @@ -1,3 +1,4 @@ +#if !BASIS_FRAMEWORK_EXISTS using Basis.Scripts.Drivers; using UnityEngine; @@ -56,3 +57,4 @@ private void OnAudioFilterRead(float[] data, int channels) private void OnDisable() => StopCapture(); } } +#endif diff --git a/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs index a54c2312e4..a4c47c63f2 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Sim/BasisAvatarSimPlayer.cs @@ -1,3 +1,4 @@ +#if !BASIS_FRAMEWORK_EXISTS using Basis.Scripts.BasisSdk; using Basis.Scripts.BasisSdk.Helpers; using Basis.Scripts.Drivers; @@ -60,3 +61,4 @@ private void OnDestroy() } } } +#endif From b7c6a0221f03462e02f38b9b04e2dc8092873df6 Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 09:39:35 -0700 Subject: [PATCH 5/8] chore: dont exit 1 on pkg build --- .github/scripts/unitypackagegen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/unitypackagegen.sh b/.github/scripts/unitypackagegen.sh index 770405fe72..85d4b9322d 100755 --- a/.github/scripts/unitypackagegen.sh +++ b/.github/scripts/unitypackagegen.sh @@ -74,7 +74,7 @@ elif [[ "$1" == "sdk" ]]; then else echo "Only full, sdk, and creator targets are specified." die - exit 1 + exit fi set -e From a0aee140724e58c5ce6f729dce41875ee53bff2b Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 11:59:12 -0700 Subject: [PATCH 6/8] fix: dont have resolve loop for basis avatar on moving to playmode --- .../SDKInspector/BasisAvatarSDKInspector.cs | 70 +++++++++++++------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs index 2c3968654a..2ab210cf4c 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs @@ -7,6 +7,7 @@ using UnityEditor; using UnityEditor.UIElements; using UnityEngine; +using UnityEngine.SceneManagement; using UnityEngine.UIElements; using static BasisAvatarValidator; using Basis.Scripts.BasisSdk.Players; @@ -15,11 +16,6 @@ public partial class BasisAvatarSDKInspector : Editor { private const string PendingTestInEditorAvatarIdSessionKey = "BasisAvatarSDKInspector.PendingTestInEditorAvatarId"; - // Unity's GlobalObjectId table isn't always populated on the first delayCall after - // EnteredPlayMode (the play-mode scene reload races us). Retry a bounded number of - // ticks so a transient null resolve doesn't drop the pending avatar. - private const int MaxResolveAttempts = 30; - private static int _resolveAttempts; public delegate void BeforeTestInEditorHandler(GameObject clone); public static BeforeTestInEditorHandler OnBeforeTestInEditor; @@ -46,18 +42,46 @@ private static void InitializeTestInEditorHooks() { EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + + // Re-attach the sceneLoaded hook here so we're + // listening before the play-mode scene finishes loading. + if (HasPendingTestInEditorAvatarId()) + { + HookSceneLoadedForPendingAvatar(); + } } private static void OnPlayModeStateChanged(PlayModeStateChange state) { - if (state != PlayModeStateChange.EnteredPlayMode || !HasPendingTestInEditorAvatarId()) + if (!HasPendingTestInEditorAvatarId()) + { + return; + } + + if (state == PlayModeStateChange.ExitingEditMode) { + HookSceneLoadedForPendingAvatar(); return; } - _resolveAttempts = 0; - EditorApplication.delayCall -= TryExecutePendingTestInEditor; - EditorApplication.delayCall += TryExecutePendingTestInEditor; + // If sceneLoaded fired earlier the pending key is already cleared and this is a no-op. + if (state == PlayModeStateChange.EnteredPlayMode) + { + SceneManager.sceneLoaded -= OnSceneLoadedForPendingAvatar; + TryExecutePendingTestInEditor(); + } + } + + private static void HookSceneLoadedForPendingAvatar() + { + SceneManager.sceneLoaded -= OnSceneLoadedForPendingAvatar; + SceneManager.sceneLoaded += OnSceneLoadedForPendingAvatar; + } + + private static void OnSceneLoadedForPendingAvatar(Scene scene, LoadSceneMode mode) + { + SceneManager.sceneLoaded -= OnSceneLoadedForPendingAvatar; + TryExecutePendingTestInEditor(); } private static void TryExecutePendingTestInEditor() @@ -65,34 +89,23 @@ private static void TryExecutePendingTestInEditor() string pendingAvatarId = GetPendingTestInEditorAvatarId(); if (string.IsNullOrEmpty(pendingAvatarId)) { - _resolveAttempts = 0; return; } if (!GlobalObjectId.TryParse(pendingAvatarId, out GlobalObjectId avatarId)) { ClearPendingTestInEditorAvatarId(); - _resolveAttempts = 0; return; } BasisAvatar avatar = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(avatarId) as BasisAvatar; + ClearPendingTestInEditorAvatarId(); if (avatar == null) { - if (++_resolveAttempts < MaxResolveAttempts) - { - EditorApplication.delayCall += TryExecutePendingTestInEditor; - return; - } - - ClearPendingTestInEditorAvatarId(); - _resolveAttempts = 0; - BasisDebug.LogError($"Unable to resolve the pending avatar for Test In Editor after {MaxResolveAttempts} attempts.", BasisDebug.LogTag.Editor); + BasisDebug.LogError("Unable to resolve the pending avatar for Test In Editor.", BasisDebug.LogTag.Editor); return; } - ClearPendingTestInEditorAvatarId(); - _resolveAttempts = 0; RequestAvatarLoad(avatar); } @@ -643,6 +656,19 @@ public void AvatarTestInEditorClickFunction() { if (!Application.isPlaying) { + // GlobalObjectId for a prefab-stage instance resolves to null after + // EnterPlaymode auto-closes the stage, so the avatar would silently + // vanish post-transition. Bail rather than try to map back to the asset. + var stage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); + if (stage != null && Avatar != null && Avatar.gameObject.scene == stage.scene) + { + EditorUtility.DisplayDialog( + "Test In Editor", + "Close the prefab edit mode and select the avatar from the Project window or a scene before testing.", + BasisEditorLocalization.Get("sdk.common.dialog.yes")); + return; + } + bool result = EditorUtility.DisplayDialog( BasisEditorLocalization.Get("sdk.common.dialog.confirm"), BasisEditorLocalization.Get("sdk.avatar.testInEditor.confirm.body"), From 09ab2dad618b4e71a01f741e56abb691f0751796 Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 12:34:51 -0700 Subject: [PATCH 7/8] fix: auto save avatar as temp prefab when auto loading --- Basis/.gitignore | 2 + .../SDKInspector/BasisAvatarSDKInspector.cs | 108 ++++++++++-------- 2 files changed, 62 insertions(+), 48 deletions(-) diff --git a/Basis/.gitignore b/Basis/.gitignore index 0c7a594e00..47c0e70337 100644 --- a/Basis/.gitignore +++ b/Basis/.gitignore @@ -106,6 +106,8 @@ mono_crash.mem.*.*.blob [Aa]ssets/_[Uu]ser[Cc]ontent.meta [Aa]ssets/[Gg]it[Ii]gnore/ [Aa]ssets/[Gg]it[Ii]gnore.meta +[Aa]ssets/_[Bb]asis[Tt]emp/ +[Aa]ssets/_[Bb]asis[Tt]emp.meta # FFmpeg /[Aa]ssets/[Ss]treamingAssets/[Ff][Ff]mpeg/ diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs index 2ab210cf4c..75408c9345 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs @@ -7,7 +7,6 @@ using UnityEditor; using UnityEditor.UIElements; using UnityEngine; -using UnityEngine.SceneManagement; using UnityEngine.UIElements; using static BasisAvatarValidator; using Basis.Scripts.BasisSdk.Players; @@ -16,6 +15,8 @@ public partial class BasisAvatarSDKInspector : Editor { private const string PendingTestInEditorAvatarIdSessionKey = "BasisAvatarSDKInspector.PendingTestInEditorAvatarId"; + private const string TempPrefabDirectory = "Assets/" + TempPrefabFolderName; + private const string TempPrefabFolderName = "_BasisTemp"; public delegate void BeforeTestInEditorHandler(GameObject clone); public static BeforeTestInEditorHandler OnBeforeTestInEditor; @@ -43,77 +44,65 @@ private static void InitializeTestInEditorHooks() EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; - // Re-attach the sceneLoaded hook here so we're - // listening before the play-mode scene finishes loading. - if (HasPendingTestInEditorAvatarId()) + // Clean up temp prefabs left over from a previous editor session. + if (string.IsNullOrEmpty(GetPendingTestInEditorAvatarId())) { - HookSceneLoadedForPendingAvatar(); + CleanupTempPrefabDirectory(); } } private static void OnPlayModeStateChanged(PlayModeStateChange state) { - if (!HasPendingTestInEditorAvatarId()) + if (state == PlayModeStateChange.EnteredPlayMode) { - return; + TryExecutePendingTestInEditor(); } - - if (state == PlayModeStateChange.ExitingEditMode) + else if (state == PlayModeStateChange.EnteredEditMode) { - HookSceneLoadedForPendingAvatar(); - return; + CleanupTempPrefabDirectory(); } + } - // If sceneLoaded fired earlier the pending key is already cleared and this is a no-op. - if (state == PlayModeStateChange.EnteredPlayMode) + private static string CreateTempPrefabFromSceneAvatar(BasisAvatar avatar) + { + if (avatar == null) return null; + if (!AssetDatabase.IsValidFolder(TempPrefabDirectory)) { - SceneManager.sceneLoaded -= OnSceneLoadedForPendingAvatar; - TryExecutePendingTestInEditor(); + AssetDatabase.CreateFolder("Assets", TempPrefabFolderName); } - } - private static void HookSceneLoadedForPendingAvatar() - { - SceneManager.sceneLoaded -= OnSceneLoadedForPendingAvatar; - SceneManager.sceneLoaded += OnSceneLoadedForPendingAvatar; + string path = AssetDatabase.GenerateUniqueAssetPath( + $"{TempPrefabDirectory}/{avatar.gameObject.name}.prefab"); + // SaveAsPrefabAsset (no Connect) leaves the original scene GameObject untouched. + var prefab = PrefabUtility.SaveAsPrefabAsset(avatar.gameObject, path); + return prefab != null ? path : null; } - private static void OnSceneLoadedForPendingAvatar(Scene scene, LoadSceneMode mode) + private static void CleanupTempPrefabDirectory() { - SceneManager.sceneLoaded -= OnSceneLoadedForPendingAvatar; - TryExecutePendingTestInEditor(); + if (AssetDatabase.IsValidFolder(TempPrefabDirectory)) + { + AssetDatabase.DeleteAsset(TempPrefabDirectory); + } } private static void TryExecutePendingTestInEditor() { - string pendingAvatarId = GetPendingTestInEditorAvatarId(); - if (string.IsNullOrEmpty(pendingAvatarId)) - { - return; - } - - if (!GlobalObjectId.TryParse(pendingAvatarId, out GlobalObjectId avatarId)) - { - ClearPendingTestInEditorAvatarId(); - return; - } - - BasisAvatar avatar = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(avatarId) as BasisAvatar; + string assetPath = GetPendingTestInEditorAvatarId(); + if (string.IsNullOrEmpty(assetPath)) return; ClearPendingTestInEditorAvatarId(); + + var go = AssetDatabase.LoadAssetAtPath(assetPath); + BasisAvatar avatar = go != null ? go.GetComponent() : null; if (avatar == null) { - BasisDebug.LogError("Unable to resolve the pending avatar for Test In Editor.", BasisDebug.LogTag.Editor); + BasisDebug.LogError($"Unable to resolve the pending avatar at '{assetPath}' for Test In Editor.", BasisDebug.LogTag.Editor); return; } RequestAvatarLoad(avatar); } - private static bool HasPendingTestInEditorAvatarId() - { - return SessionState.GetBool(PendingTestInEditorAvatarIdSessionKey + ".Exists", false); - } - private static string GetPendingTestInEditorAvatarId() { return SessionState.GetString(PendingTestInEditorAvatarIdSessionKey, string.Empty); @@ -656,9 +645,8 @@ public void AvatarTestInEditorClickFunction() { if (!Application.isPlaying) { - // GlobalObjectId for a prefab-stage instance resolves to null after - // EnterPlaymode auto-closes the stage, so the avatar would silently - // vanish post-transition. Bail rather than try to map back to the asset. + // Avatar in PrefabStage gets destroyed when EnterPlaymode auto-closes + // the stage. Bail rather than try to map back to the asset. var stage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); if (stage != null && Avatar != null && Avatar.gameObject.scene == stage.scene) { @@ -669,22 +657,46 @@ public void AvatarTestInEditorClickFunction() return; } + if (Avatar == null) return; + bool result = EditorUtility.DisplayDialog( BasisEditorLocalization.Get("sdk.common.dialog.confirm"), BasisEditorLocalization.Get("sdk.avatar.testInEditor.confirm.body"), BasisEditorLocalization.Get("sdk.common.dialog.yes"), BasisEditorLocalization.Get("sdk.common.dialog.no")); - if (result) + if (!result) return; + + // Defer the temp-prefab write until after the confirm dialog so a + // cancelled flow doesn't leave orphan files on disk. + string assetPath = ResolveAvatarAssetPath(Avatar) ?? CreateTempPrefabFromSceneAvatar(Avatar); + if (string.IsNullOrEmpty(assetPath)) { - SetPendingTestInEditorAvatarId(GlobalObjectId.GetGlobalObjectIdSlow(Avatar).ToString()); - EditorApplication.EnterPlaymode(); + EditorUtility.DisplayDialog( + "Test In Editor", + "Couldn't resolve the avatar to an asset or write a temporary prefab. Save it as a prefab manually and try again.", + BasisEditorLocalization.Get("sdk.common.dialog.yes")); + return; } + + SetPendingTestInEditorAvatarId(assetPath); + EditorApplication.EnterPlaymode(); } else { RequestAvatarLoad(); } } + + // Resolves the inspector target to a project-relative asset path. Returns + // null when the avatar lives only in a scene with no prefab backing. + private static string ResolveAvatarAssetPath(BasisAvatar avatar) + { + if (avatar == null) return null; + string path = AssetDatabase.GetAssetPath(avatar); + if (!string.IsNullOrEmpty(path)) return path; + var source = PrefabUtility.GetCorrespondingObjectFromSource(avatar); + return source != null ? AssetDatabase.GetAssetPath(source) : null; + } public void RequestAvatarLoad() { RequestAvatarLoad(Avatar); From 39bf6b2c6ac183f15aaaf2911c7441a2e9a10986 Mon Sep 17 00:00:00 2001 From: mriise Date: Fri, 15 May 2026 19:29:32 -0700 Subject: [PATCH 8/8] chore: use plain public instead of get/set for variables in editor preview player --- .../Scripts/Editor/BasisEditorPreviewLocalPlayer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs index eac2c800cb..673ed2512b 100644 --- a/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs +++ b/Basis/Packages/com.basis.sdk/Scripts/Editor/BasisEditorPreviewLocalPlayer.cs @@ -15,10 +15,10 @@ internal sealed class BasisEditorPreviewLocalPlayer : IBasisLocalPlayer private static readonly BasisEditorPreviewLocalPlayer _instance = new BasisEditorPreviewLocalPlayer(); - public static BasisAvatar ActiveAvatar { get; private set; } - public static BasisAnimatorVariableApply Applier { get; private set; } - public static BasisAvatarSimPlayer ActiveSimPlayer { get; private set; } - public static BasisAvatarSimMic ActiveSimMic { get; private set; } + public static BasisAvatar ActiveAvatar; + public static BasisAnimatorVariableApply Applier; + public static BasisAvatarSimPlayer ActiveSimPlayer; + public static BasisAvatarSimMic ActiveSimMic; public static event System.Action StateChanged; private static GameObject _previewRoot;