From a984cf86735170d075f8224dd7c83fa760e54eed Mon Sep 17 00:00:00 2001 From: "Jeremy Lam aka. Vistanz" Date: Sun, 17 Nov 2024 11:02:09 +0800 Subject: [PATCH] Use VRCParentConstraint instead of constraint hack for world fixed objects when available (#1326) * Fixes error when merging same parameter with different type in RC menu item. * Rollback ReactiveObjectPass, use another approach * Set defaults to ModularAvatarMergeAnimator to prevent potential errors * Use VRCParentConstraint instead of constraint hack for world fixed objects when available * Make sure the VRC constraint only applies on VRChat avatars * Extract creation logic to external method * Rearrange method * Get rid of unit test * Fix unit test build error * Fix assert fail --- Editor/WorldFixedObjectProcessor.cs | 38 +++++++++++++++++-- .../WorldFixedObjectTest.cs | 23 ++++++++++- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Editor/WorldFixedObjectProcessor.cs b/Editor/WorldFixedObjectProcessor.cs index 85e4464c..35298392 100644 --- a/Editor/WorldFixedObjectProcessor.cs +++ b/Editor/WorldFixedObjectProcessor.cs @@ -86,6 +86,15 @@ namespace nadena.dev.modular_avatar.core.editor obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = Vector3.one; + if (!TryCreateVRCConstraint(avatarRoot, obj)) CreateConstraint(obj, fixedGameObject); + + _proxy = obj.transform; + + return obj.transform; + } + + private void CreateConstraint(GameObject obj, GameObject fixedGameObject) + { var constraint = obj.AddComponent(); constraint.AddSource(new ConstraintSource() { @@ -96,10 +105,31 @@ namespace nadena.dev.modular_avatar.core.editor constraint.locked = true; constraint.rotationOffsets = new[] {Vector3.zero}; constraint.translationOffsets = new[] {Vector3.zero}; - - _proxy = obj.transform; - - return obj.transform; } + +#if MA_VRCSDK3_AVATARS_3_7_0_OR_NEWER + private bool TryCreateVRCConstraint(Transform avatarRoot, GameObject obj) + { + var isVrcAvatar = avatarRoot.TryGetComponent(out VRC.SDKBase.VRC_AvatarDescriptor _); + + if (!isVrcAvatar) return false; + + var constraint = obj.AddComponent( + System.Type.GetType("VRC.SDK3.Dynamics.Constraint.Components.VRCParentConstraint, VRC.SDK3.Dynamics.Constraint") + ) as VRC.Dynamics.ManagedTypes.VRCParentConstraintBase; + constraint.IsActive = true; + constraint.Locked = true; + constraint.AffectsPositionX = true; + constraint.AffectsPositionY = true; + constraint.AffectsPositionZ = true; + constraint.AffectsRotationX = true; + constraint.AffectsRotationY = true; + constraint.AffectsRotationZ = true; + constraint.FreezeToWorld = true; + return true; + } +#else + private bool TryCreateVRCConstraint(Transform avatarRoot, GameObject obj) => false; +#endif } } \ No newline at end of file diff --git a/UnitTests~/WorldFixedObjectTest/WorldFixedObjectTest.cs b/UnitTests~/WorldFixedObjectTest/WorldFixedObjectTest.cs index ba838bda..2338db10 100644 --- a/UnitTests~/WorldFixedObjectTest/WorldFixedObjectTest.cs +++ b/UnitTests~/WorldFixedObjectTest/WorldFixedObjectTest.cs @@ -3,6 +3,7 @@ using nadena.dev.modular_avatar.animation; using nadena.dev.modular_avatar.core; using nadena.dev.modular_avatar.core.editor; using NUnit.Framework; +using UnityEngine; using UnityEngine.Animations; public class WorldFixedObjectTest : TestBase @@ -25,7 +26,16 @@ public class WorldFixedObjectTest : TestBase // fixed root is created Assert.That(fixedRoot, Is.Not.Null); - Assert.That(fixedRoot.GetComponent(), Is.Not.Null); + bool isVrcAvatar = false; + System.Type vrcParentConstraintType = null; + #if MA_VRCSDK3_AVATARS + isVrcAvatar = avatar.TryGetComponent(out VRC.SDKBase.VRC_AvatarDescriptor _); + vrcParentConstraintType = System.Type.GetType("VRC.SDK3.Dynamics.Constraint.Components.VRCParentConstraint, VRC.SDK3.Dynamics.Constraint"); + #endif + Component constraint = isVrcAvatar && vrcParentConstraintType != null ? + fixedRoot.GetComponent(vrcParentConstraintType) : + fixedRoot.GetComponent(); + Assert.That(constraint, Is.Not.Null); // objects are moved to fixed root Assert.That(movedFixedObject, Is.Not.Null); @@ -52,7 +62,16 @@ public class WorldFixedObjectTest : TestBase // fixed root is created Assert.That(fixedRoot, Is.Not.Null); - Assert.That(fixedRoot.GetComponent(), Is.Not.Null); + bool isVrcAvatar = false; + System.Type vrcParentConstraintType = null; + #if MA_VRCSDK3_AVATARS + isVrcAvatar = avatar.TryGetComponent(out VRC.SDKBase.VRC_AvatarDescriptor _); + vrcParentConstraintType = System.Type.GetType("VRC.SDK3.Dynamics.Constraint.Components.VRCParentConstraint, VRC.SDK3.Dynamics.Constraint"); + #endif + Component constraint = isVrcAvatar && vrcParentConstraintType != null ? + fixedRoot.GetComponent(vrcParentConstraintType) : + fixedRoot.GetComponent(); + Assert.That(constraint, Is.Not.Null); // objects are moved to fixed root Assert.That(movedFixedObject, Is.Not.Null);