diff --git a/Editor/PluginDefinition/PluginDefinition.cs b/Editor/PluginDefinition/PluginDefinition.cs index 02ca727d..69f179d7 100644 --- a/Editor/PluginDefinition/PluginDefinition.cs +++ b/Editor/PluginDefinition/PluginDefinition.cs @@ -81,19 +81,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin FixupExpressionsMenuPass.FixupExpressionsMenu(maContext); }); #endif - seq.Run("Rebind humanoid avatar", ctx => - { - // workaround problem with avatar matching - // https://github.com/bdunderscore/modular-avatar/issues/430 - var animator = ctx.AvatarRootObject.GetComponent(); - if (animator) - { - var avatar = animator.avatar; - animator.avatar = null; - // ReSharper disable once Unity.InefficientPropertyAccess - animator.avatar = avatar; - } - }); + seq.Run(RebindHumanoidAvatarPass.Instance); seq.Run("Purge ModularAvatar components", ctx => { foreach (var component in ctx.AvatarRootTransform.GetComponentsInChildren(true)) @@ -253,6 +241,14 @@ namespace nadena.dev.modular_avatar.core.editor.plugin } #endif + class RebindHumanoidAvatarPass : MAPass + { + protected override void Execute(ndmf.BuildContext context) + { + new RebindHumanoidAvatar(context).Process(); + } + } + class GCGameObjectsPluginPass : MAPass { protected override void Execute(ndmf.BuildContext context) diff --git a/Editor/RebindHumanoidAvatar.cs b/Editor/RebindHumanoidAvatar.cs new file mode 100644 index 00000000..8d32aa02 --- /dev/null +++ b/Editor/RebindHumanoidAvatar.cs @@ -0,0 +1,63 @@ +using System.Linq; +using UnityEngine; + +namespace nadena.dev.modular_avatar.core.editor.plugin +{ + // workaround problem with avatar matching + // https://github.com/bdunderscore/modular-avatar/issues/430 + internal class RebindHumanoidAvatar + { + private readonly ndmf.BuildContext _buildContext; + + public RebindHumanoidAvatar(ndmf.BuildContext context) + { + _buildContext = context; + } + + public void Process() + { + var avatarAnimator = _buildContext.AvatarRootObject.GetComponent(); + if (avatarAnimator == null || avatarAnimator.avatar == null) return; + + var localTransformValues = _buildContext.AvatarRootObject + .GetComponentsInChildren(true) + .ToDictionary((t) => t, LocalTransformValue.FromTransform); + + var boundAvatar = avatarAnimator.avatar; + avatarAnimator.avatar = null; + // ReSharper disable once Unity.InefficientPropertyAccess + avatarAnimator.avatar = boundAvatar; + + // resetting avatar also resets local transform value from avatar asset + // needs to restore them manually from pre-cache + // https://github.com/bdunderscore/modular-avatar/issues/1036 + foreach (var (transform, preserved) in localTransformValues) + { + preserved.RestoreToTransform(transform); + } + } + + struct LocalTransformValue + { + Vector3 Position; + Quaternion Rotation; + Vector3 Scale; + + internal static LocalTransformValue FromTransform(Transform t) + { + return new LocalTransformValue + { + Position = t.localPosition, + Rotation = t.localRotation, + Scale = t.localScale + }; + } + + internal readonly void RestoreToTransform(Transform t) + { + t.SetLocalPositionAndRotation(Position, Rotation); + t.localScale = Scale; + } + } + } +} \ No newline at end of file diff --git a/Editor/RebindHumanoidAvatar.cs.meta b/Editor/RebindHumanoidAvatar.cs.meta new file mode 100644 index 00000000..715768d6 --- /dev/null +++ b/Editor/RebindHumanoidAvatar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f0b7a3de79e73a4f853218f26ed7077 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: