diff --git a/Packages/nadena.dev.modular-avatar/Editor/Menu/ActionProcessing/ActionGenerator.cs b/Packages/nadena.dev.modular-avatar/Editor/Menu/ActionProcessing/ActionGenerator.cs index a20c7073..dbd026ae 100644 --- a/Packages/nadena.dev.modular-avatar/Editor/Menu/ActionProcessing/ActionGenerator.cs +++ b/Packages/nadena.dev.modular-avatar/Editor/Menu/ActionProcessing/ActionGenerator.cs @@ -88,16 +88,15 @@ namespace nadena.dev.modular_avatar.core.editor } var layerList = controller.layers.ToList(); - layerList.Insert(0, GenerateBlendshapeBaseLayer(avatar)); - rootBlendTree.defaultWeight = 1; layerList.Insert(0, rootBlendTree); - if (layerList.Count > 1) - { - layerList[1].defaultWeight = 1; - } + rootBlendTree.defaultWeight = 1; controller.layers = layerList.ToArray(); + // Generate blendshape base layer including anything we're animating in our blendtree + layerList.Insert(0, GenerateBlendshapeBaseLayer(avatar)); + controller.layers = layerList.ToArray(); + foreach (var action in avatar.GetComponentsInChildren(true)) { Object.DestroyImmediate((UnityEngine.Object) action); diff --git a/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionBlendshape.cs b/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionBlendshape.cs new file mode 100644 index 00000000..b0c2469a --- /dev/null +++ b/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionBlendshape.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using UnityEngine; + +namespace nadena.dev.modular_avatar.core +{ + [AddComponentMenu("Modular Avatar/MA Action Blendshape")] + [RequireComponent(typeof(ActionController))] + public class ActionBlendshape : AvatarTagComponent, SwitchedMenuAction + { + [Serializable] + public class BlendshapeSpec + { + public AvatarObjectReference target = new AvatarObjectReference(); + public string blendshape; + public float value; + } + + public List Blendshapes; + + public bool BindsParameter(TargetParameter parameter) + { + return parameter == TargetParameter.BaseParameter; + } + + public ImmutableDictionary GetCurves() + { + ImmutableDictionary.Builder builder = + ImmutableDictionary.Empty.ToBuilder(); + + foreach (var spec in Blendshapes) + { + var target = spec.target?.Get(this); + if (target == null) continue; + + if (string.IsNullOrWhiteSpace(spec.blendshape)) continue; + + builder.Add( + new MenuCurveBinding(target, typeof(SkinnedMeshRenderer), "blendShape." + spec.blendshape), + AnimationCurve.Constant(0, 1, spec.value) + ); + } + + return builder.ToImmutable(); + } + + public ImmutableDictionary GetInactiveCurves() + { + ImmutableDictionary.Builder builder = + ImmutableDictionary.Empty.ToBuilder(); + + foreach (var spec in Blendshapes) + { + var target = spec.target?.Get(this); + if (target == null) continue; + + var targetRenderer = target.GetComponent(); + if (targetRenderer == null) continue; + + var mesh = targetRenderer.sharedMesh; + if (mesh == null) continue; + + if (string.IsNullOrWhiteSpace(spec.blendshape)) continue; + + var blendshapeIndex = mesh.GetBlendShapeIndex(spec.blendshape); + if (blendshapeIndex < 0) continue; + + var value = targetRenderer.GetBlendShapeWeight(blendshapeIndex); + + builder.Add( + new MenuCurveBinding(target, typeof(SkinnedMeshRenderer), "blendShape." + spec.blendshape), + AnimationCurve.Constant(0, 1, value) + ); + } + + return builder.ToImmutable(); + } + } +} \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionBlendshape.cs.meta b/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionBlendshape.cs.meta new file mode 100644 index 00000000..3e777cb4 --- /dev/null +++ b/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionBlendshape.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b91a8e5892cd4d2c85fcd0b2f2c570e1 +timeCreated: 1682852930 \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionToggleObject.cs b/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionToggleObject.cs index ca228d3d..8bf22ec7 100644 --- a/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionToggleObject.cs +++ b/Packages/nadena.dev.modular-avatar/Runtime/Menu/Actions/ActionToggleObject.cs @@ -14,7 +14,7 @@ namespace nadena.dev.modular_avatar.core [Serializable] public class ObjectEntry { - public AvatarObjectReference target; + public AvatarObjectReference target = new AvatarObjectReference(); public bool Active; }