From ae975506d78829de4080d8ca4ed85b9ed5c19c26 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 17:15:14 -0700 Subject: [PATCH 1/9] fix: occasionally objects controlling reactive components "flicker" (#1298) Reported-by: @whipnice --- .../Animation/GameObjectDisableDelayPass.cs | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/Editor/Animation/GameObjectDisableDelayPass.cs b/Editor/Animation/GameObjectDisableDelayPass.cs index 8e8bca4c..fb453429 100644 --- a/Editor/Animation/GameObjectDisableDelayPass.cs +++ b/Editor/Animation/GameObjectDisableDelayPass.cs @@ -1,9 +1,11 @@ using System.Linq; +using nadena.dev.modular_avatar.core.editor; using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; using UnityEngine; using VRC.SDK3.Avatars.Components; +using BuildContext = nadena.dev.ndmf.BuildContext; namespace nadena.dev.modular_avatar.animation { @@ -23,11 +25,16 @@ namespace nadena.dev.modular_avatar.animation if (fx == null) return; + var nullMotion = new AnimationClip(); + nullMotion.name = "NullMotion"; + var blendTree = new BlendTree(); blendTree.blendType = BlendTreeType.Direct; blendTree.useAutomaticThresholds = false; - blendTree.children = asc.BoundReadableProperties.Select(GenerateDelayChild).ToArray(); + blendTree.children = asc.BoundReadableProperties + .Select(prop => GenerateDelayChild(nullMotion, prop)) + .ToArray(); var asm = new AnimatorStateMachine(); var state = new AnimatorState(); @@ -54,7 +61,7 @@ namespace nadena.dev.modular_avatar.animation }).ToArray(); } - private ChildMotion GenerateDelayChild((EditorCurveBinding, string) binding) + private ChildMotion GenerateDelayChild(Motion nullMotion, (EditorCurveBinding, string) binding) { var ecb = binding.Item1; var prop = binding.Item2; @@ -64,10 +71,40 @@ namespace nadena.dev.modular_avatar.animation curve.AddKey(0, 1); AnimationUtility.SetEditorCurve(motion, ecb, curve); + // Occasionally, we'll have a very small value pop up, probably due to FP errors. + // To correct for this, instead of directly using the property in the direct blend tree, + // we'll use a 1D blend tree to give ourselves a buffer. + + var bufferBlendTree = new BlendTree(); + bufferBlendTree.blendType = BlendTreeType.Simple1D; + bufferBlendTree.useAutomaticThresholds = false; + bufferBlendTree.blendParameter = prop; + bufferBlendTree.children = new[] + { + new ChildMotion + { + motion = nullMotion, + timeScale = 1, + threshold = 0 + }, + new ChildMotion + { + motion = nullMotion, + timeScale = 1, + threshold = 0.01f + }, + new ChildMotion + { + motion = motion, + timeScale = 1, + threshold = 1 + } + }; + return new ChildMotion { - motion = motion, - directBlendParameter = prop, + motion = bufferBlendTree, + directBlendParameter = MergeBlendTreePass.ALWAYS_ONE, timeScale = 1 }; } From 9dc342e81e099f3f50d749ab4017e4214a568704 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 17:15:23 -0700 Subject: [PATCH 2/9] fix: always-on toggles fail to animate objects to off (#1300) Closes: #1285 --- .../Animation/GameObjectDisableDelayPass.cs | 15 ++++++ .../ReactiveComponent/ObjectToggleTests.cs | 50 +++++++++++++++++++ .../ObjectToggleTests.cs.meta | 3 ++ 3 files changed, 68 insertions(+) create mode 100644 UnitTests~/ReactiveComponent/ObjectToggleTests.cs create mode 100644 UnitTests~/ReactiveComponent/ObjectToggleTests.cs.meta diff --git a/Editor/Animation/GameObjectDisableDelayPass.cs b/Editor/Animation/GameObjectDisableDelayPass.cs index fb453429..0eed02d2 100644 --- a/Editor/Animation/GameObjectDisableDelayPass.cs +++ b/Editor/Animation/GameObjectDisableDelayPass.cs @@ -59,6 +59,21 @@ namespace nadena.dev.modular_avatar.animation defaultWeight = 1, blendingMode = AnimatorLayerBlendingMode.Override }).ToArray(); + + // Ensure the initial state of readable props matches the actual state of the gameobject + var parameters = fx.parameters; + var paramToIndex = parameters.Select((p, i) => (p, i)).ToDictionary(x => x.p.name, x => x.i); + foreach (var (binding, prop) in asc.BoundReadableProperties) + { + var obj = asc.PathMappings.PathToObject(binding.path); + + if (obj != null && paramToIndex.TryGetValue(prop, out var index)) + { + parameters[index].defaultFloat = obj.activeSelf ? 1 : 0; + } + } + + fx.parameters = parameters; } private ChildMotion GenerateDelayChild(Motion nullMotion, (EditorCurveBinding, string) binding) diff --git a/UnitTests~/ReactiveComponent/ObjectToggleTests.cs b/UnitTests~/ReactiveComponent/ObjectToggleTests.cs new file mode 100644 index 00000000..6637ff05 --- /dev/null +++ b/UnitTests~/ReactiveComponent/ObjectToggleTests.cs @@ -0,0 +1,50 @@ +using System.Linq; +using modular_avatar_tests; +using nadena.dev.modular_avatar.core; +using nadena.dev.modular_avatar.core.editor; +using NUnit.Framework; +using UnityEditor.Animations; +using UnityEngine; + +namespace UnitTests.ReactiveComponent +{ + internal class ObjectToggleTests : TestBase + { + [Test] + public void WhenObjectIsAlwaysOn_CorrectProxyParameterIsGenerated() + { + var root = CreateRoot("root"); + var obj = CreateChild(root, "obj"); + var toggle = CreateChild(root, "toggle"); + + // Prevent obj from being removed by the GC game objects pass + obj.AddComponent(); + + var toggleComponent = toggle.AddComponent(); + var aor = new AvatarObjectReference(); + aor.Set(obj); + + toggleComponent.Objects = new() + { + new() + { + Active = false, + Object = aor + } + }; + + AvatarProcessor.ProcessAvatar(root); + + // TODO: Ideally we should start using play mode testing for these things... + var fx = (AnimatorController)FindFxController(root).animatorController; + var readableProp = fx.parameters.FirstOrDefault( + p => p.name.StartsWith("__MA/ReadableProp/obj/UnityEngine.GameObject/m_IsActive") + ); + + Assert.IsNotNull(readableProp); + Assert.AreEqual(readableProp.defaultFloat, 0); + + Assert.IsFalse(obj.activeSelf); + } + } +} \ No newline at end of file diff --git a/UnitTests~/ReactiveComponent/ObjectToggleTests.cs.meta b/UnitTests~/ReactiveComponent/ObjectToggleTests.cs.meta new file mode 100644 index 00000000..9e86034a --- /dev/null +++ b/UnitTests~/ReactiveComponent/ObjectToggleTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7c68d69f7b4a46c5b2ce3d8f26b0fa76 +timeCreated: 1729376563 \ No newline at end of file From ab4d1fd2f4285780b8f281b8292e2964fc69ee56 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 17:15:33 -0700 Subject: [PATCH 3/9] fix: transient NRE when opening reaction debugger (#1301) --- .../AnimationGeneration/ReactiveObjectAnalyzer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs index 923ac135..9b64dde8 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs @@ -128,7 +128,7 @@ namespace nadena.dev.modular_avatar.core.editor foreach (var cond in rule.ControllingConditions) { var paramName = cond.Parameter; - if (ForcePropertyOverrides.TryGetValue(paramName, out var value)) + if (ForcePropertyOverrides?.TryGetValue(paramName, out var value) == true) { cond.InitialValue = value; } From 123523540eddc8a682c6f55af63fd22e76266a17 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 17:15:43 -0700 Subject: [PATCH 4/9] fix: parameters lose their default value when others are moved around (#1302) Closes: #1296 --- .../Inspector/Parameters/DefaultValueField.cs | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/Editor/Inspector/Parameters/DefaultValueField.cs b/Editor/Inspector/Parameters/DefaultValueField.cs index 6ba6cd22..f29f217b 100644 --- a/Editor/Inspector/Parameters/DefaultValueField.cs +++ b/Editor/Inspector/Parameters/DefaultValueField.cs @@ -20,7 +20,8 @@ namespace nadena.dev.modular_avatar.core.editor private readonly DropdownField _boolField; private ParameterSyncType _syncType; - + private bool _hasInitialBinding; + public DefaultValueField() { // Hidden binding elements @@ -57,28 +58,39 @@ namespace nadena.dev.modular_avatar.core.editor { _numberField.style.display = DisplayStyle.Flex; _boolField.style.display = DisplayStyle.None; - OnUpdateNumberValue(_numberField.value); + OnUpdateNumberValue(_numberField.value, true); } else { _numberField.style.display = DisplayStyle.None; _boolField.style.display = DisplayStyle.Flex; - OnUpdateBoolValue(_boolField.value); + OnUpdateBoolValue(_boolField.value, true); } } - private void OnUpdateNumberValue(string value) + private void OnUpdateNumberValue(string value, bool implicitUpdate = false) { + // Upon initial creation, sometimes the OnUpdateSyncType fires before we receive the initial value event. + // In this case, suppress the update to avoid losing data. + if (implicitUpdate && !_hasInitialBinding) return; + + var theValue = _defaultValueField.value; if (string.IsNullOrWhiteSpace(value)) { - _defaultValueField.value = 0; + if (!implicitUpdate) + { + _defaultValueField.value = 0; + } + + theValue = _defaultValueField.value; + _hasExplicitDefaultValueField.value = false; } else if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed) && !float.IsNaN(parsed) && !float.IsInfinity(parsed)) { - _defaultValueField.value = _syncType switch + theValue = _defaultValueField.value = _syncType switch { ParameterSyncType.Int => Mathf.FloorToInt(Mathf.Clamp(parsed, 0, 255)), ParameterSyncType.Float => Mathf.Clamp(parsed, -1, 1), @@ -88,11 +100,15 @@ namespace nadena.dev.modular_avatar.core.editor _hasExplicitDefaultValueField.value = true; } - UpdateVisibleField(_defaultValueField.value, _hasExplicitDefaultValueField.value); + UpdateVisibleField(theValue, _hasExplicitDefaultValueField.value); } - private void OnUpdateBoolValue(string value) + private void OnUpdateBoolValue(string value, bool implicitUpdate = false) { + // Upon initial creation, sometimes the OnUpdateSyncType fires before we receive the initial value event. + // In this case, suppress the update to avoid losing data. + if (implicitUpdate && !_hasInitialBinding) return; + _defaultValueField.value = value == V_True ? 1 : 0; _hasExplicitDefaultValueField.value = value != V_None; @@ -101,6 +117,8 @@ namespace nadena.dev.modular_avatar.core.editor private void UpdateVisibleField(float value, bool hasExplicitValue) { + _hasInitialBinding = true; + if (hasExplicitValue || Mathf.Abs(value) > 0.0000001) { _numberField.SetValueWithoutNotify(value.ToString(CultureInfo.InvariantCulture)); From 11a62c88d49298df22f064c97151f705af419f6d Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 17:46:31 -0700 Subject: [PATCH 5/9] fix: issues when handling VRCExpressionMenus with an uninitialized type field (#1303) --- Editor/Inspector/Menu/MenuItemGUI.cs | 7 +++---- Editor/Menu/MenuExtractor.cs | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Editor/Inspector/Menu/MenuItemGUI.cs b/Editor/Inspector/Menu/MenuItemGUI.cs index 30439a32..8f4ab313 100644 --- a/Editor/Inspector/Menu/MenuItemGUI.cs +++ b/Editor/Inspector/Menu/MenuItemGUI.cs @@ -301,10 +301,9 @@ namespace nadena.dev.modular_avatar.core.editor EditorGUILayout.BeginVertical(); if (_type.hasMultipleDifferentValues) return; - VRCExpressionsMenu.Control.ControlType type = - (VRCExpressionsMenu.Control.ControlType) Enum - .GetValues(typeof(VRCExpressionsMenu.Control.ControlType)) - .GetValue(_type.enumValueIndex); + var controlTypeArray = Enum.GetValues(typeof(VRCExpressionsMenu.Control.ControlType)); + var index = Math.Clamp(_type.enumValueIndex, 0, controlTypeArray.Length - 1); + var type = (VRCExpressionsMenu.Control.ControlType)controlTypeArray.GetValue(index); switch (type) { diff --git a/Editor/Menu/MenuExtractor.cs b/Editor/Menu/MenuExtractor.cs index 89ee232c..9f670382 100644 --- a/Editor/Menu/MenuExtractor.cs +++ b/Editor/Menu/MenuExtractor.cs @@ -119,9 +119,11 @@ namespace nadena.dev.modular_avatar.core.editor internal static VRCExpressionsMenu.Control CloneControl(VRCExpressionsMenu.Control c) { + var type = c.type != 0 ? c.type : VRCExpressionsMenu.Control.ControlType.Button; + return new VRCExpressionsMenu.Control() { - type = c.type, + type = type, name = c.name, icon = c.icon, parameter = new VRCExpressionsMenu.Control.Parameter() { name = c.parameter?.name }, From 5bafb0ba9d2f027f9b938529389fd7595fdd5312 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 17:46:39 -0700 Subject: [PATCH 6/9] fix: "extract menu to objects" does not set the target of its menu group properly (#1304) Closes: #1297 --- Editor/Inspector/Menu/MenuInstallerEditor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Editor/Inspector/Menu/MenuInstallerEditor.cs b/Editor/Inspector/Menu/MenuInstallerEditor.cs index 5110aa36..f32efe0f 100644 --- a/Editor/Inspector/Menu/MenuInstallerEditor.cs +++ b/Editor/Inspector/Menu/MenuInstallerEditor.cs @@ -368,7 +368,7 @@ namespace nadena.dev.modular_avatar.core.editor serializedObject.ApplyModifiedProperties(); - Localization.ShowLanguageUI(); + ShowLanguageUI(); } private string ObjectHierarchyOrder(Component arg) @@ -415,6 +415,9 @@ namespace nadena.dev.modular_avatar.core.editor var group = installer.gameObject.AddComponent(); var menuRoot = new GameObject(); menuRoot.name = "Menu"; + + group.targetObject = menuRoot; + Undo.RegisterCreatedObjectUndo(menuRoot, "Extract menu"); menuRoot.transform.SetParent(group.transform, false); foreach (var control in menu.controls) From 26153ea60dd10f62c34fad080e6f83268e597212 Mon Sep 17 00:00:00 2001 From: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com> Date: Sun, 20 Oct 2024 09:52:51 +0900 Subject: [PATCH 7/9] feat: improve behavior when called setup outfit for setuped outfit (#1200) --- Editor/SetupOutfit.cs | 101 ++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 28 deletions(-) diff --git a/Editor/SetupOutfit.cs b/Editor/SetupOutfit.cs index ba69ed9f..c09578c8 100644 --- a/Editor/SetupOutfit.cs +++ b/Editor/SetupOutfit.cs @@ -145,25 +145,54 @@ namespace nadena.dev.modular_avatar.core.editor out var avatarRoot, out var avatarHips, out var outfitHips) ) return; + Undo.SetCurrentGroupName("Setup Outfit"); + var avatarArmature = avatarHips.transform.parent; var outfitArmature = outfitHips.transform.parent; - if (outfitArmature.GetComponent() == null) + var merge = outfitArmature.GetComponent(); + if (merge == null) + { + merge = Undo.AddComponent(outfitArmature.gameObject); + } else { + Undo.RecordObject(merge, ""); + } + + if (merge.mergeTarget == null || merge.mergeTargetObject == null) { - var merge = Undo.AddComponent(outfitArmature.gameObject); merge.mergeTarget = new AvatarObjectReference(); merge.mergeTarget.referencePath = RuntimeUtil.RelativePath(avatarRoot, avatarArmature.gameObject); merge.LockMode = ArmatureLockMode.BaseToMerge; + } + + if (string.IsNullOrEmpty(merge.prefix) && string.IsNullOrEmpty(merge.suffix)) + { merge.InferPrefixSuffix(); + } - List subRoots = new List(); - HeuristicBoneMapper.RenameBonesByHeuristic(merge, skipped: subRoots); + PrefabUtility.RecordPrefabInstancePropertyModifications(merge); - // If the outfit has an UpperChest bone but the avatar doesn't, add an additional MergeArmature to - // help with this - foreach (var subRoot in subRoots) + List subRoots = new List(); + HeuristicBoneMapper.RenameBonesByHeuristic(merge, skipped: subRoots); + + // If the outfit has an UpperChest bone but the avatar doesn't, add an additional MergeArmature to + // help with this + foreach (var subRoot in subRoots) + { + var subConfig = subRoot.GetComponent(); + var subConfigMangleNames = false; + if (subConfig == null) + { + subConfig = Undo.AddComponent(subRoot.gameObject); + } + else + { + Undo.RecordObject(subConfig, ""); + subConfigMangleNames = subConfig.mangleNames; + } + + if (subConfig.mergeTarget == null || subConfig.mergeTargetObject == null) { - var subConfig = Undo.AddComponent(subRoot.gameObject); var parentTransform = subConfig.transform.parent; var parentConfig = parentTransform.GetComponentInParent(); var parentMapping = parentConfig.MapBone(parentTransform); @@ -174,34 +203,48 @@ namespace nadena.dev.modular_avatar.core.editor subConfig.LockMode = ArmatureLockMode.BaseToMerge; subConfig.prefix = merge.prefix; subConfig.suffix = merge.suffix; - subConfig.mangleNames = false; + subConfig.mangleNames = subConfigMangleNames; + PrefabUtility.RecordPrefabInstancePropertyModifications(subConfig); } + } - var avatarRootMatchingArmature = avatarRoot.transform.Find(outfitArmature.gameObject.name); - if (merge.prefix == "" && merge.suffix == "" && avatarRootMatchingArmature != null) - { - // We have an armature whose names exactly match the root armature - this can cause some serious - // confusion in Unity's humanoid armature matching system. Fortunately, we can avoid this by - // renaming a bone close to the root; this will ensure the number of matching bones is small, and - // Unity's heuristics (apparently) will choose the base avatar's armature as the "true" armature. - outfitArmature.name += ".1"; + var avatarRootMatchingArmature = avatarRoot.transform.Find(outfitArmature.gameObject.name); + if (merge.prefix == "" && merge.suffix == "" && avatarRootMatchingArmature != null) + { + // We have an armature whose names exactly match the root armature - this can cause some serious + // confusion in Unity's humanoid armature matching system. Fortunately, we can avoid this by + // renaming a bone close to the root; this will ensure the number of matching bones is small, and + // Unity's heuristics (apparently) will choose the base avatar's armature as the "true" armature. + outfitArmature.name += ".1"; - // Also make sure to refresh the avatar's animator humanoid bone cache. - var avatarAnimator = avatarRoot.GetComponent(); - var humanDescription = avatarAnimator.avatar; - avatarAnimator.avatar = null; - // ReSharper disable once Unity.InefficientPropertyAccess - avatarAnimator.avatar = humanDescription; - } + // Also make sure to refresh the avatar's animator humanoid bone cache. + var avatarAnimator = avatarRoot.GetComponent(); + var humanDescription = avatarAnimator.avatar; + avatarAnimator.avatar = null; + // ReSharper disable once Unity.InefficientPropertyAccess + avatarAnimator.avatar = humanDescription; } FixAPose(avatarRoot, outfitArmature); + var meshSettings = outfitRoot.GetComponent(); + var mSInheritProbeAnchor = ModularAvatarMeshSettings.InheritMode.SetOrInherit; + var mSInheritBounds = ModularAvatarMeshSettings.InheritMode.SetOrInherit; if (outfitRoot != null - && outfitRoot.GetComponent() == null + && meshSettings == null && outfitRoot.GetComponentInParent() == null) { - var meshSettings = Undo.AddComponent(outfitRoot.gameObject); + meshSettings = Undo.AddComponent(outfitRoot.gameObject); + } else if (outfitRoot != null && meshSettings != null) { + Undo.RecordObject(meshSettings, ""); + mSInheritProbeAnchor = meshSettings.InheritProbeAnchor; + mSInheritBounds = meshSettings.InheritBounds; + } + + if (meshSettings != null + && (meshSettings.ProbeAnchor == null || meshSettings.ProbeAnchor.Get(meshSettings) == null + || meshSettings.RootBone == null || meshSettings.RootBone.Get(meshSettings) == null)) + { Transform rootBone = null, probeAnchor = null; Bounds bounds = ModularAvatarMeshSettings.DEFAULT_BOUNDS; @@ -217,8 +260,8 @@ namespace nadena.dev.modular_avatar.core.editor rootBone = avatarRoot.transform; } - meshSettings.InheritProbeAnchor = ModularAvatarMeshSettings.InheritMode.SetOrInherit; - meshSettings.InheritBounds = ModularAvatarMeshSettings.InheritMode.SetOrInherit; + meshSettings.InheritProbeAnchor = mSInheritProbeAnchor; + meshSettings.InheritBounds = mSInheritBounds; meshSettings.ProbeAnchor = new AvatarObjectReference(); meshSettings.ProbeAnchor.referencePath = RuntimeUtil.RelativePath(avatarRoot, probeAnchor.gameObject); @@ -226,6 +269,8 @@ namespace nadena.dev.modular_avatar.core.editor meshSettings.RootBone = new AvatarObjectReference(); meshSettings.RootBone.referencePath = RuntimeUtil.RelativePath(avatarRoot, rootBone.gameObject); meshSettings.Bounds = bounds; + + PrefabUtility.RecordPrefabInstancePropertyModifications(meshSettings); } } From 3b067e46640f902c3d297738818c2ad1c242266c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=C3=AF=7E?= <60819407+hai-vr@users.noreply.github.com> Date: Sun, 20 Oct 2024 03:58:41 +0200 Subject: [PATCH 8/9] Make compatible with Unity 6 projects (#1232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Disable compilation for use in Unity 6 (6000.0.20f1): - Do not compile some classes and code paths in non-VRChat projects. - This has been tested in Unity 6 (6000.0.20f1). * Fix hide internal components in Unity 6: - [AddComponentMenu("")] does not work in Unity 6. - Replace it with [AddComponentMenu("/")] - This alternative is confirmed to also work in Unity 2022. --------- Co-authored-by: Haï~ Co-authored-by: bd_ --- Editor/Animation/AnimationServicesContext.cs | 4 ++++ Editor/Animation/GameObjectDisableDelayPass.cs | 6 ++++-- Editor/Animation/PathMappings.cs | 2 ++ Editor/ApplyAnimatorDefaultValuesPass.cs | 6 ++++-- Editor/Inspector/FirstPersonVisibleEditor.cs | 5 ++++- Editor/Inspector/Menu/ToggleCreatorShortcut.cs | 6 ++++-- Editor/PluginDefinition/PluginDefinition.cs | 11 ++++++++--- .../ReactiveObjectAnalyzer.LocateReactions.cs | 6 ++++-- .../AnimationGeneration/ReactiveObjectAnalyzer.cs | 6 ++++-- .../AnimationGeneration/ReactiveObjectPass.cs | 5 ++++- .../AnimationGeneration/ReactiveObjectPrepass.cs | 6 ++++-- Editor/ReactiveObjects/MaterialSetterPreview.cs | 6 ++++-- Editor/ReactiveObjects/MenuItemPreviewCondition.cs | 6 ++++-- Editor/ReactiveObjects/ObjectTogglePreview.cs | 6 ++++-- Editor/ReactiveObjects/ParameterAssignerPass.cs | 6 ++++-- Editor/ReactiveObjects/ShapeChangerPreview.cs | 6 ++++-- Editor/ReactiveObjects/Simulator/ROSimulator.cs | 6 ++++-- Editor/ReactiveObjects/Simulator/ROSimulatorButton.cs | 4 ++++ .../Simulator/StateOverrideController.cs | 7 +++++-- Editor/VisibleHeadAccessoryProcessor.cs | 5 ++++- Runtime/Activator.cs | 4 ++-- Runtime/ModularAvatarConvertConstraints.cs | 2 +- 22 files changed, 86 insertions(+), 35 deletions(-) diff --git a/Editor/Animation/AnimationServicesContext.cs b/Editor/Animation/AnimationServicesContext.cs index 95d68ec3..bc63cec9 100644 --- a/Editor/Animation/AnimationServicesContext.cs +++ b/Editor/Animation/AnimationServicesContext.cs @@ -7,7 +7,9 @@ using nadena.dev.ndmf; using UnityEditor; using UnityEditor.Animations; using UnityEngine; +#if MA_VRCSDK3_AVATARS using VRC.SDK3.Avatars.Components; +#endif #endregion @@ -89,12 +91,14 @@ namespace nadena.dev.modular_avatar.animation // HACK: This is a temporary crutch until we rework the entire animator services system public void AddPropertyDefinition(AnimatorControllerParameter paramDef) { +#if MA_VRCSDK3_AVATARS var fx = (AnimatorController) _context.AvatarDescriptor.baseAnimationLayers .First(l => l.type == VRCAvatarDescriptor.AnimLayerType.FX) .animatorController; fx.parameters = fx.parameters.Concat(new[] { paramDef }).ToArray(); +#endif } public string GetActiveSelfProxy(GameObject obj) diff --git a/Editor/Animation/GameObjectDisableDelayPass.cs b/Editor/Animation/GameObjectDisableDelayPass.cs index 0eed02d2..87692657 100644 --- a/Editor/Animation/GameObjectDisableDelayPass.cs +++ b/Editor/Animation/GameObjectDisableDelayPass.cs @@ -1,4 +1,5 @@ -using System.Linq; +#if MA_VRCSDK3_AVATARS +using System.Linq; using nadena.dev.modular_avatar.core.editor; using nadena.dev.ndmf; using UnityEditor; @@ -124,4 +125,5 @@ namespace nadena.dev.modular_avatar.animation }; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/Animation/PathMappings.cs b/Editor/Animation/PathMappings.cs index 9546a063..8ea314bc 100644 --- a/Editor/Animation/PathMappings.cs +++ b/Editor/Animation/PathMappings.cs @@ -368,6 +368,7 @@ namespace nadena.dev.modular_avatar.animation } Profiler.EndSample(); +#if MA_VRCSDK3_AVATARS var layers = context.AvatarDescriptor.baseAnimationLayers .Concat(context.AvatarDescriptor.specialAnimationLayers); @@ -383,6 +384,7 @@ namespace nadena.dev.modular_avatar.animation ApplyMappingsToAvatarMask(acLayer.avatarMask); } Profiler.EndSample(); +#endif Profiler.EndSample(); } diff --git a/Editor/ApplyAnimatorDefaultValuesPass.cs b/Editor/ApplyAnimatorDefaultValuesPass.cs index 7b3c91ed..0f9cb15e 100644 --- a/Editor/ApplyAnimatorDefaultValuesPass.cs +++ b/Editor/ApplyAnimatorDefaultValuesPass.cs @@ -1,4 +1,5 @@ -#region +#if MA_VRCSDK3_AVATARS +#region using System; using System.Collections.Immutable; @@ -57,4 +58,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/Inspector/FirstPersonVisibleEditor.cs b/Editor/Inspector/FirstPersonVisibleEditor.cs index b9646ddb..8f7cedb9 100644 --- a/Editor/Inspector/FirstPersonVisibleEditor.cs +++ b/Editor/Inspector/FirstPersonVisibleEditor.cs @@ -1,4 +1,5 @@ -using UnityEditor; +#if MA_VRCSDK3_AVATARS +using UnityEditor; namespace nadena.dev.modular_avatar.core.editor { @@ -45,3 +46,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } + +#endif \ No newline at end of file diff --git a/Editor/Inspector/Menu/ToggleCreatorShortcut.cs b/Editor/Inspector/Menu/ToggleCreatorShortcut.cs index e549d319..d1027b95 100644 --- a/Editor/Inspector/Menu/ToggleCreatorShortcut.cs +++ b/Editor/Inspector/Menu/ToggleCreatorShortcut.cs @@ -1,4 +1,5 @@ -using nadena.dev.modular_avatar.ui; +#if MA_VRCSDK3_AVATARS +using nadena.dev.modular_avatar.ui; using UnityEditor; using UnityEngine; using VRC.SDK3.Avatars.ScriptableObjects; @@ -62,4 +63,5 @@ namespace nadena.dev.modular_avatar.core.editor Undo.RegisterCreatedObjectUndo(toggle, "Create Toggle"); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/PluginDefinition/PluginDefinition.cs b/Editor/PluginDefinition/PluginDefinition.cs index 2d258b23..4a31f17a 100644 --- a/Editor/PluginDefinition/PluginDefinition.cs +++ b/Editor/PluginDefinition/PluginDefinition.cs @@ -57,26 +57,29 @@ namespace nadena.dev.modular_avatar.core.editor.plugin #endif seq.WithRequiredExtension(typeof(AnimationServicesContext), _s2 => { +#if MA_VRCSDK3_AVATARS seq.Run("Shape Changer", ctx => new ReactiveObjectPass(ctx).Execute()) .PreviewingWith(new ShapeChangerPreview(), new ObjectSwitcherPreview(), new MaterialSetterPreview()); -#if MA_VRCSDK3_AVATARS + // TODO: We currently run this above MergeArmaturePlugin, because Merge Armature might destroy // game objects which contain Menu Installers. It'd probably be better however to teach Merge Armature // to retain those objects? maybe? seq.Run(MenuInstallPluginPass.Instance); #endif - + seq.Run(MergeArmaturePluginPass.Instance); seq.Run(BoneProxyPluginPass.Instance); +#if MA_VRCSDK3_AVATARS seq.Run(VisibleHeadAccessoryPluginPass.Instance); +#endif seq.Run("World Fixed Object", ctx => new WorldFixedObjectProcessor().Process(ctx) ); seq.Run(ReplaceObjectPluginPass.Instance); #if MA_VRCSDK3_AVATARS seq.Run(BlendshapeSyncAnimationPluginPass.Instance); -#endif seq.Run(GameObjectDelayDisablePass.Instance); +#endif seq.Run(ConstraintConverterPass.Instance); }); #if MA_VRCSDK3_AVATARS @@ -213,6 +216,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin } } +#if MA_VRCSDK3_AVATARS class VisibleHeadAccessoryPluginPass : MAPass { protected override void Execute(ndmf.BuildContext context) @@ -220,6 +224,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin new VisibleHeadAccessoryProcessor(MAContext(context)).Process(); } } +#endif class ReplaceObjectPluginPass : MAPass { diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.LocateReactions.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.LocateReactions.cs index 179e4ce4..7cc2e403 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.LocateReactions.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.LocateReactions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if MA_VRCSDK3_AVATARS +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using nadena.dev.ndmf.preview; @@ -346,4 +347,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs index 9b64dde8..228f215c 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectAnalyzer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if MA_VRCSDK3_AVATARS +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using nadena.dev.modular_avatar.animation; @@ -304,4 +305,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs index 882f96bf..ae77c80f 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs @@ -1,4 +1,5 @@ -#region +#if MA_VRCSDK3_AVATARS +#region using System; using System.Collections.Generic; @@ -613,3 +614,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } + +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPrepass.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPrepass.cs index 82c5faa8..cec2bf17 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPrepass.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPrepass.cs @@ -1,4 +1,5 @@ -using nadena.dev.ndmf; +#if MA_VRCSDK3_AVATARS +using nadena.dev.ndmf; using UnityEditor.Animations; using UnityEngine; @@ -53,4 +54,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/MaterialSetterPreview.cs b/Editor/ReactiveObjects/MaterialSetterPreview.cs index a181429d..9b1a8e59 100644 --- a/Editor/ReactiveObjects/MaterialSetterPreview.cs +++ b/Editor/ReactiveObjects/MaterialSetterPreview.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if MA_VRCSDK3_AVATARS +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; @@ -144,4 +145,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/MenuItemPreviewCondition.cs b/Editor/ReactiveObjects/MenuItemPreviewCondition.cs index 1d8f8629..04ce486a 100644 --- a/Editor/ReactiveObjects/MenuItemPreviewCondition.cs +++ b/Editor/ReactiveObjects/MenuItemPreviewCondition.cs @@ -1,4 +1,5 @@ -using System; +#if MA_VRCSDK3_AVATARS +using System; using System.Collections.Generic; using nadena.dev.ndmf; using nadena.dev.ndmf.preview; @@ -70,4 +71,5 @@ namespace nadena.dev.modular_avatar.core.editor return _context.Observe(mami, _ => mami.isDefault); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/ObjectTogglePreview.cs b/Editor/ReactiveObjects/ObjectTogglePreview.cs index 45b4e9fa..3d138ed0 100644 --- a/Editor/ReactiveObjects/ObjectTogglePreview.cs +++ b/Editor/ReactiveObjects/ObjectTogglePreview.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if MA_VRCSDK3_AVATARS +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; @@ -104,4 +105,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/ParameterAssignerPass.cs b/Editor/ReactiveObjects/ParameterAssignerPass.cs index 9b891f84..b7afd0bf 100644 --- a/Editor/ReactiveObjects/ParameterAssignerPass.cs +++ b/Editor/ReactiveObjects/ParameterAssignerPass.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if MA_VRCSDK3_AVATARS +using System.Collections.Generic; using System.Linq; using nadena.dev.ndmf; using UnityEngine; @@ -236,4 +237,5 @@ namespace nadena.dev.modular_avatar.core.editor }; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/ShapeChangerPreview.cs b/Editor/ReactiveObjects/ShapeChangerPreview.cs index 58c09131..d3cde839 100644 --- a/Editor/ReactiveObjects/ShapeChangerPreview.cs +++ b/Editor/ReactiveObjects/ShapeChangerPreview.cs @@ -1,4 +1,5 @@ -#region +#if MA_VRCSDK3_AVATARS +#region using System; using System.Collections.Generic; @@ -294,4 +295,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/Simulator/ROSimulator.cs b/Editor/ReactiveObjects/Simulator/ROSimulator.cs index 40b9be8c..4d192515 100644 --- a/Editor/ReactiveObjects/Simulator/ROSimulator.cs +++ b/Editor/ReactiveObjects/Simulator/ROSimulator.cs @@ -1,4 +1,5 @@ -using System; +#if MA_VRCSDK3_AVATARS +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -637,4 +638,5 @@ namespace nadena.dev.modular_avatar.core.editor.Simulator ve_inactive.style.display = activeState ? DisplayStyle.None : DisplayStyle.Flex; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/ReactiveObjects/Simulator/ROSimulatorButton.cs b/Editor/ReactiveObjects/Simulator/ROSimulatorButton.cs index 285f4c6b..0d1eced6 100644 --- a/Editor/ReactiveObjects/Simulator/ROSimulatorButton.cs +++ b/Editor/ReactiveObjects/Simulator/ROSimulatorButton.cs @@ -1,5 +1,7 @@ using nadena.dev.modular_avatar.core.editor; +#if MA_VRCSDK3_AVATARS using nadena.dev.modular_avatar.core.editor.Simulator; +#endif using UnityEditor; using UnityEngine; using UnityEngine.UIElements; @@ -42,11 +44,13 @@ namespace nadena.dev.modular_avatar.core.editor private void OpenDebugger() { +#if MA_VRCSDK3_AVATARS GameObject target = Selection.activeGameObject; if (ReferenceObject is Component c) target = c.gameObject; else if (ReferenceObject is GameObject go) target = go; ROSimulator.OpenDebugger(target); +#endif } } } \ No newline at end of file diff --git a/Editor/ReactiveObjects/Simulator/StateOverrideController.cs b/Editor/ReactiveObjects/Simulator/StateOverrideController.cs index 74d9c45e..4392f953 100644 --- a/Editor/ReactiveObjects/Simulator/StateOverrideController.cs +++ b/Editor/ReactiveObjects/Simulator/StateOverrideController.cs @@ -1,4 +1,6 @@ -using nadena.dev.modular_avatar.core.editor.Simulator; +#if MA_VRCSDK3_AVATARS +using System; +using nadena.dev.modular_avatar.core.editor.Simulator; using UnityEditor; using UnityEngine.UIElements; @@ -74,4 +76,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Editor/VisibleHeadAccessoryProcessor.cs b/Editor/VisibleHeadAccessoryProcessor.cs index b5014d2d..54bbcb1a 100644 --- a/Editor/VisibleHeadAccessoryProcessor.cs +++ b/Editor/VisibleHeadAccessoryProcessor.cs @@ -1,4 +1,5 @@ -#region +#if MA_VRCSDK3_AVATARS +#region using System; using System.Collections.Generic; @@ -251,3 +252,5 @@ namespace nadena.dev.modular_avatar.core.editor } } } + +#endif \ No newline at end of file diff --git a/Runtime/Activator.cs b/Runtime/Activator.cs index 9d45d930..6825177e 100644 --- a/Runtime/Activator.cs +++ b/Runtime/Activator.cs @@ -19,7 +19,7 @@ namespace nadena.dev.modular_avatar.core /// initially inactive in the scene (which can have high overhead if the user has a lot of inactive avatars in the /// scene). /// - [AddComponentMenu("")] + [AddComponentMenu("/")] [ExecuteInEditMode] [DefaultExecutionOrder(-9998)] public class Activator : MonoBehaviour, IEditorOnly @@ -30,7 +30,7 @@ namespace nadena.dev.modular_avatar.core } } - [AddComponentMenu("")] + [AddComponentMenu("/")] [ExecuteInEditMode] [DefaultExecutionOrder(-9997)] public class AvatarActivator : MonoBehaviour, IEditorOnly diff --git a/Runtime/ModularAvatarConvertConstraints.cs b/Runtime/ModularAvatarConvertConstraints.cs index 1440fa25..f4f5ebdd 100644 --- a/Runtime/ModularAvatarConvertConstraints.cs +++ b/Runtime/ModularAvatarConvertConstraints.cs @@ -6,7 +6,7 @@ namespace nadena.dev.modular_avatar.core #if MA_VRCSDK3_AVATARS [AddComponentMenu("Modular Avatar/MA Convert Constraints")] #else - [AddComponentMenu("")] + [AddComponentMenu("/")] #endif [HelpURL("https://modular-avatar.nadena.dev/docs/reference/convert-constraints?lang=auto")] public class ModularAvatarConvertConstraints : AvatarTagComponent From e0702c5dcfafcb59aa8525a747c2aa08d44796d1 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 19 Oct 2024 20:09:45 -0700 Subject: [PATCH 9/9] 1.10.5 --- .github/ProjectRoot/vpm-manifest-2022.json | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ProjectRoot/vpm-manifest-2022.json b/.github/ProjectRoot/vpm-manifest-2022.json index 60d7c06f..ab64302d 100644 --- a/.github/ProjectRoot/vpm-manifest-2022.json +++ b/.github/ProjectRoot/vpm-manifest-2022.json @@ -4,7 +4,7 @@ "version": "3.7.0" }, "nadena.dev.ndmf": { - "version": "1.4.0" + "version": "1.5.6" } }, "locked": { @@ -19,7 +19,7 @@ "dependencies": {} }, "nadena.dev.ndmf": { - "version": "1.5.3" + "version": "1.5.6" } } } \ No newline at end of file diff --git a/package.json b/package.json index ec982b70..01bfb789 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nadena.dev.modular-avatar", "displayName": "Modular Avatar", - "version": "1.10.4", + "version": "1.10.5", "unity": "2022.3", "description": "A suite of tools for assembling your avatar out of reusable components", "author": { @@ -16,6 +16,6 @@ }, "vpmDependencies": { "com.vrchat.avatars": ">=3.7.0", - "nadena.dev.ndmf": ">=1.5.4 <2.0.0-a" + "nadena.dev.ndmf": ">=1.5.6 <2.0.0-a" } }