diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs index 96c65365..ae77c80f 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs @@ -26,10 +26,7 @@ namespace nadena.dev.modular_avatar.core.editor private AnimationClip _initialStateClip; private bool _writeDefaults; - - private AnimatorCombiner _combineSession; - private AnimatorController _animController; - + public ReactiveObjectPass(ndmf.BuildContext context) { this.context = context; @@ -37,37 +34,26 @@ namespace nadena.dev.modular_avatar.core.editor internal void Execute() { - var fxController = FindFxController(); - // Having a WD OFF layer after WD ON layers can break WD. We match the behavior of the existing states, // and if mixed, use WD ON to maximize compatibility. - _writeDefaults = MergeAnimatorProcessor.ProbeWriteDefaults(fxController.animatorController as AnimatorController) ?? true; - - _combineSession = new AnimatorCombiner(context, fxController.animatorController != null ? fxController.animatorController.name : "FX (Reactive Objects)"); - _combineSession.AddController("", fxController.animatorController as AnimatorController, null); - _animController = new AnimatorController(); - + _writeDefaults = MergeAnimatorProcessor.ProbeWriteDefaults(FindFxController().animatorController as AnimatorController) ?? true; + var analysis = new ReactiveObjectAnalyzer(context).Analyze(context.AvatarRootObject); var shapes = analysis.Shapes; var initialStates = analysis.InitialStates; - + GenerateActiveSelfProxies(shapes); ProcessMeshDeletion(initialStates, shapes); ProcessInitialStates(initialStates, shapes); ProcessInitialAnimatorVariables(shapes); - + foreach (var groups in shapes.Values) { ProcessShapeKey(groups); } - - _combineSession.AddController("", _animController, null); - FinishCombineSession(); - Object.DestroyImmediate(_animController); // Cleanup - _combineSession = null; } private void GenerateActiveSelfProxies(Dictionary shapes) @@ -576,7 +562,24 @@ namespace nadena.dev.modular_avatar.core.editor private void ApplyController(AnimatorStateMachine asm, string layerName) { - var paramList = _animController.parameters.ToList(); + var fx = FindFxController(); + + if (fx.animatorController == null) + { + throw new InvalidOperationException("No FX layer found"); + } + + if (!context.IsTemporaryAsset(fx.animatorController)) + { + throw new InvalidOperationException("FX layer is not a temporary asset"); + } + + if (!(fx.animatorController is AnimatorController animController)) + { + throw new InvalidOperationException("FX layer is not an animator controller"); + } + + var paramList = animController.parameters.ToList(); var paramSet = paramList.Select(p => p.name).ToHashSet(); foreach (var paramName in initialValues.Keys.Except(paramSet)) @@ -590,9 +593,9 @@ namespace nadena.dev.modular_avatar.core.editor paramSet.Add(paramName); } - _animController.parameters = paramList.ToArray(); + animController.parameters = paramList.ToArray(); - _animController.layers = _animController.layers.Append( + animController.layers = animController.layers.Append( new AnimatorControllerLayer { stateMachine = asm, @@ -609,29 +612,6 @@ namespace nadena.dev.modular_avatar.core.editor return fx; } - - private void FinishCombineSession() - { - for (int i = 0; i < context.AvatarDescriptor.baseAnimationLayers.Length; i++) - { - if (context.AvatarDescriptor.baseAnimationLayers[i].type == VRCAvatarDescriptor.AnimLayerType.FX) - { - context.AvatarDescriptor.baseAnimationLayers[i].animatorController = _combineSession.Finish(); - return; - } - } - - // When we don't have an FX layer, we create one. - context.AvatarDescriptor.baseAnimationLayers = context.AvatarDescriptor.baseAnimationLayers.Append( - new VRCAvatarDescriptor.CustomAnimLayer - { - type = VRCAvatarDescriptor.AnimLayerType.FX, - isDefault = false, - isEnabled = true, - animatorController = _combineSession.Finish(), - } - ).ToArray(); - } } } diff --git a/Editor/ReactiveObjects/ParameterAssignerPass.cs b/Editor/ReactiveObjects/ParameterAssignerPass.cs index b7afd0bf..179c7061 100644 --- a/Editor/ReactiveObjects/ParameterAssignerPass.cs +++ b/Editor/ReactiveObjects/ParameterAssignerPass.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using nadena.dev.ndmf; using UnityEngine; +using UnityEditor.Animations; using VRC.SDK3.Avatars.ScriptableObjects; namespace nadena.dev.modular_avatar.core.editor @@ -186,6 +187,19 @@ namespace nadena.dev.modular_avatar.core.editor expParams.parameters = expParams.parameters.Concat(newParameters.Values).ToArray(); } + + if (_mamiByParam.Count > 0) + { + // This make sures the parameters are correctly merged into the FX layer. + context.AvatarRootObject.AddComponent().animator = new AnimatorController + { + parameters = _mamiByParam.Keys.Select(name => new AnimatorControllerParameter + { + name = name, + type = AnimatorControllerParameterType.Float, + }).ToArray(), + }; + } } internal static ControlCondition AssignMenuItemParameter(