diff --git a/UnityRiftGUI/Studio.cs b/UnityRiftGUI/Studio.cs index 0b39181..e0be927 100644 --- a/UnityRiftGUI/Studio.cs +++ b/UnityRiftGUI/Studio.cs @@ -368,6 +368,24 @@ public static (string, List) BuildAssetData() containers.Add((m_Container.Value, m_Container.Key)); } break; + case LazyObject lazyAsset: + // Heavy assets are loaded as placeholders; derive exportability from + // the real ClassIDType so lazy Mesh/AnimationClip/Shader/Font/TextAsset/ + // MovieTexture are not dropped from the type filter. Avatar and + // AnimatorController placeholders stay non-exportable. + assetItem.Text = lazyAsset.m_Name; + switch (lazyAsset.type) + { + case ClassIDType.Mesh: + case ClassIDType.AnimationClip: + case ClassIDType.Shader: + case ClassIDType.Font: + case ClassIDType.TextAsset: + case ClassIDType.MovieTexture: + exportable = true; + break; + } + break; case NamedObject m_NamedObject: assetItem.Text = m_NamedObject.m_Name; break; @@ -984,6 +1002,25 @@ private static void SelectAssemblyFolder() { if (!assemblyLoader.Loaded) { + // Standalone builds strip MonoBehaviour script fields, so without the game's + // assemblies the preview reads only the 32-byte base and logs "Failed to read + // type, read 32 bytes but expected N bytes" for every field. Auto-load the Mono + // "Managed" folder found next to the loaded files before falling back to the + // manual picker. IL2CPP games have no Managed folder, so they still fall through + // to the manual "Select Assembly Folder" dialog. + var paths = assetsManager.AssetsFileList + .Select(f => f.originalPath ?? f.fullName) + .Where(p => p != null) + .Distinct() + .ToList(); + var managed = AssemblyLoader.FindManagedFolder(paths); + if (managed != null) + { + assemblyLoader.Load(managed); + AssembliesLoaded?.Invoke(); + return; + } + var openFolderDialog = new OpenFolderDialog(); openFolderDialog.Title = "Select Assembly Folder"; if (openFolderDialog.ShowDialog() == DialogResult.OK) diff --git a/UnityRiftUtility/ModelConverter.cs b/UnityRiftUtility/ModelConverter.cs index 7adcf7d..59dab4e 100644 --- a/UnityRiftUtility/ModelConverter.cs +++ b/UnityRiftUtility/ModelConverter.cs @@ -305,10 +305,22 @@ private void CollectAnimationClip(Animator m_Animator) { AnimatorController m_AnimatorController; var animationList = new List(); + var overrideMap = new Dictionary(); if (m_Controller is AnimatorOverrideController overrideController) { if (!overrideController.m_Controller.TryGet(out m_AnimatorController)) return; + // The base controller only holds empty template_* placeholder clips; the + // real animation data lives in the override map. Map each original clip to + // its override so we collect the playable clips instead of 0.00s templates. + foreach (var clipOverride in overrideController.m_Clips) + { + if (clipOverride.m_OriginalClip.TryGet(out var originalClip) + && clipOverride.m_OverrideClip.TryGet(out var overrideClip)) + { + overrideMap[originalClip] = overrideClip; + } + } } else { @@ -319,7 +331,9 @@ private void CollectAnimationClip(Animator m_Animator) { if (pptr.TryGet(out var m_AnimationClip)) { - animationList.Add(m_AnimationClip); + animationList.Add(overrideMap.TryGetValue(m_AnimationClip, out var overrideClip) + ? overrideClip + : m_AnimationClip); } } animationClipUniqArray = animationList.Distinct(animationClipEqComparer).ToArray();